我使用Newtonsoft JSON来序列化在附属程序集中定义的对象图。我有一个循环引用,它会导致超出JSON中的递归限制,并为已经数据量很大的POST增加额外的膨胀。
记录的方法是在我的数据对象上向属性添加JsonIgnore
属性,但这需要在我的域项目中使用Newtonsoft.Json引用。是否还有其他方法可以将属性排除在序列化之外?
答案 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; }
}