如何从Json序列化中排除属性

13 浏览
0 Comments

如何从Json序列化中排除属性

我有一个DTO类,我将其序列化为JSON。如何排除其中一个公共属性?(该属性必须是公共的,因为我在其他地方的代码中使用它)

0
0 Comments

如何从Json序列化中排除属性的出现原因和解决方法

在进行Json序列化时,有时我们希望排除一些属性。可能出于以下原因:不想为属性添加属性,无法访问类,或者希望在运行时决定要序列化的内容。下面介绍了两种解决方法。

1. 在Newtonsoft.Json中的解决方法:

使用Newtonsoft.Json的解决方法非常简单,可以创建一个自定义的ContractResolver来忽略特定的属性。下面是一个示例代码:

//忽略某些属性的辅助类
public class IgnorePropertiesResolver : DefaultContractResolver
{
    private readonly HashSet ignoreProps;
    public IgnorePropertiesResolver(IEnumerable propNamesToIgnore)
    {
        this.ignoreProps = new HashSet(propNamesToIgnore);
    }
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        if (this.ignoreProps.Contains(property.PropertyName))
        {
            property.ShouldSerialize = _ => false;
        }
        return property;
    }
}

使用方法如下:

JsonConvert.SerializeObject(YourObject, new JsonSerializerSettings()
{
    ContractResolver = new IgnorePropertiesResolver(new[] { "Prop1", "Prop2" })
});

如果决定使用此解决方法,请确保缓存`ContractResolver`对象,否则可能会影响性能。具体代码可以在这里找到:https://github.com/jitbit/JsonIgnoreProps

2. 在System.Text.Json中的解决方法:

在.NET Core中,默认使用`System.Text.Json`进行Json序列化,它更快,但没有Newtonsoft那么灵活。但是,在运行时排除属性有以下几种解决方法:

- 在.NET 7及以上版本中,可以控制序列化哪些属性,具体方法可以参考这里:https://devblogs.microsoft.com/dotnet/system-text-json-in-dotnet-7/#example-conditional-serialization

- 在.NET 6及以下版本中,可以使用接口转换或使用映射器来排除属性。具体方法可以参考这个答案:https://stackoverflow.com/a/61344654/56621

这些方法都非常有效。需要注意的是,如果需要与其他解析器(如`CamelCasePropertyNamesContractResolver`)组合使用,只需将自定义的`IgnorePropertiesResolver`继承自`CamelCasePropertyNamesContractResolver`,而不是直接继承自`DefaultContractResolver`。

以上解决方法对于无法硬编码要排除的属性时非常有用。感谢这个答案的提供者,解决了许多困扰。

这些解决方法非常适用于不能修改原始类或使用属性的情况。希望这篇文章对大家有所帮助。

0
0 Comments

如何从Json序列化中排除属性?

在.NET框架中,如果您正在使用System.Web.Script.Serialization,您可以在不应被序列化的成员上放置ScriptIgnore属性。可以从这里的示例中看到:

public class User {
    public int Id { get; set; }
    public string Name { get; set; }
    [ScriptIgnore]
    public bool IsComplete
    {
        get { return Id > 0 && !string.IsNullOrEmpty(Name); }
    } 
}

在这种情况下,只有Id和Name属性会被序列化,因此生成的JSON对象将如下所示:

{ "Id": 3, "Name": "Test User" }

补充说明:不要忘记为此添加对"System.Web.Extensions"的引用,以使其正常工作。

我发现ScriptIgnore位于System.Web.Script.Serialization命名空间中。

我发现System.Web.Controller.Json()(即在MVC中返回JsonResult)仅与[ScriptIgnore]一起工作,而不是[JsonIgnore]。因此,对于JsonResult类型,请使用[ScriptIgnore]。是的,正确的引用是System.Web.Script.Serialization。

0
0 Comments

如何在Json序列化中排除属性

如果你正在使用Json.Net,使用属性[JsonIgnore]会在序列化或反序列化时简单地忽略字段/属性。

或者你可以使用DataContract和DataMember属性选择性地序列化/反序列化属性/字段。

[DataContract]

public class Computer

{

// included in JSON

[DataMember]

public string Name { get; set; }

[DataMember]

public decimal SalePrice { get; set; }

// ignored

public string Manufacture { get; set; }

public int StockCount { get; set; }

public decimal WholeSalePrice { get; set; }

public DateTime NextShipmentDate { get; set; }

}

更多详细信息,请参考http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size

如果我是提问者,我会选择这个答案,而不是选择[ScriptIgnore]的解决方案。主要是因为这个Json解决方案与Json问题相一致。为什么要涉及System.Web.Extensions,而你所使用的库提供了一个解决方案?我个人认为,最好的解决方法是[IgnoreDataMember]属性,因为System.Runtime.Serialization应该与每个序列化器兼容,如果你想要替换Json。

IgnoreDataMember在默认的JsonResult序列化器中不起作用。

如果值为null,为什么要在反序列化时忽略?为什么不只是为属性创建一个处理null值的属性,或者创建一个优雅处理null值的属性?

注意你的命名空间。[JsonIgnore]属性存在于Newtonsoft.Json和System.Text.Json.Serialization命名空间中。很容易在模型上使用Newtonsoft.Json.JsonIgnore,但在序列化模型时使用System.Text.Json.Serialization.JsonSerializer.Serialize(或反之亦然)。然后JsonIgnore属性被忽略了。

我发现[JsonIgnore]对我不起作用。我不得不为每个成员使用[DataContract]和[DataMember]属性,除了我不想要的那个成员。我不知道为什么这应该有所不同。我最终使用了System.Text.Json,但我也尝试了Newtonsoft。

[JsonIgnore]也是ASP.NET Core中System.Text.Json.Serialization命名空间中的一个有效属性。

0