从JSON中排除域模型对象的属性

时间:2016-07-29 10:38:32

标签: c# json asp.net-mvc serialization json.net

我使用Newtonsoft JSON来序列化在附属程序集中定义的对象图。我有一个循环引用,它会导致超出JSON中的递归限制,并为已经数据量很大的POST增加额外的膨胀。

记录的方法是在我的数据对象上向属性添加JsonIgnore属性,但这需要在我的域项目中使用Newtonsoft.Json引用。是否还有其他方法可以将属性排除在序列化之外?

3 个答案:

答案 0 :(得分:3)

备选方案1

您应该可以将[DataContract][DataMember]一起使用。

[DataContract]
public class MyDomainModel
{
    [DataMember]
    public string PublicString { get; set; }

    public string HiddenString { get; set; }

    public MyDomainModel InfiniteReference { get; set; }
}

需要引用System.Runtime.Serialization

示例:

[HttpGet]
public MyDomainModel GetModels()
{
        var model = new MyDomainModel
        {
            HiddenString = "Hidden",
            PublicString = "Public",
        };
        model.InfiniteReference = model;
        return model;
 }

输出:

{
"publicString": "Public"
}

备选方案2

  

我有一个循环引用[...]

您可以使用ReferenceLoopHandling,它只会剪切循环引用。但是当你提到其他额外的膨胀时,这可能不是你想要的。

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

答案 1 :(得分:0)

有类似的问题。我在序列化时使用自定义属性和契约解析器以完全过度和过度工作的方式解决了这个问题,因此我不需要在模型中引用任何外部库(系统除外)。

声明您自己的属性,例如

[AttributeUsage(AttributeTargets.Property)]
public sealed class IgnoreMeAttribute : Attribute
{
}

装饰你的模特

[IgnoreMe]
public string IgnoreMePlease { get; set; }

添加

public class ShouldSerializeContractResolver : DefaultContractResolver
{
    public static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        if (property.AttributeProvider.GetAttributes(typeof (IgnoreMeAttribute), false).Any())
            property.ShouldSerialize = instance => false;

        return property;
    }
}

并使用它

var result = JsonConvert.SerializeObject(value, Formatting.None, new JsonSerializerSettings { ContractResolver = ShouldSerializeContractResolver.Instance });

答案 2 :(得分:0)

您可以在模型属性上应用[IgnoreDataMember]属性,该属性引用System.Runtime.Serialization。默认情况下,所有其他属性都将被序列化。

e.g。

public class MyViewModel
{
    public string SerializedProperty { get; set; }

    [IgnoreDataMember]
    public string IgnoredProperty { get; set; }
}