我有两个班级:
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Order
{
public int ID { get; set; }
public int CustomerID { get; set; }
public virtual Customer Customer { get; set; }
public string Description { get; set; }
}
我正在尝试使用Customer
和JSON
将Json.Net
序列化为ContractResolver
,不包括每个Customer
的{{1}}属性。我只想保留Order
。我不想使用像Description
这样的注释,因为我想让不同情况下的序列化不同。
所以我做了这样的事情:
[JsonIgnore]
然后我从数据库中获取客户并尝试将其序列化:
public class CustomerContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (property.DeclaringType == typeof(Order) && property.PropertyName.Equals(nameof(Order.Customer)))
{
property.ShouldSerialize = instance => { return false; };
}
return property;
}
}
JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = new CustomerContractResolver() };
string json = Newtonsoft.Json.JsonConvert.SerializeObject(customer, Formatting.Indented, settings);
的{{1}}方法按照预期为Orders集合中的每个CreateProperty
调用,但我仍然收到错误:
为属性'Customer'检测到自引用循环,类型为'System.Data.Entity.DynamicProxies.Customer_04661D0875E326DF9B5D4D2BA503FC19E2C0EBD49A7BE593D66F67AE77F7FDBE'。路径'订单[0]'。
意味着ShouldSerialize委托不起作用。
此处有任何想法如何从每个CustomerContractResolver
中排除Order
属性?
答案 0 :(得分:0)
从异常错误消息中看来,您正在使用Entity Framework并启用了dynamic proxies:
在创建POCO实体类型的实例时,实体框架通常会创建动态生成的派生类型的实例,作为实体的代理。
因为传入的对象是派生的,所以检查property.DeclaringType == typeof(Order)
将失败。相反,您可以使用unexpected GetType() result for entity entry中的一个答案来检查基础类型是否为Order
,例如:
public class CustomerContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (typeof(Order).IsAssignableFrom(property.DeclaringType) && property.PropertyName.Equals(nameof(Order.Customer)))
{
property.ShouldSerialize = instance => { return false; };
}
return property;
}
}
无论是否使用动态代理,检查属性的声明类型是否可从Order
分配都应该有效。