如何使用ContractResolver从我的基类中的嵌套类列表中排除属性

时间:2017-10-03 09:29:19

标签: c# entity-framework json.net

我有两个班级:

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; }
}

我正在尝试使用CustomerJSONJson.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属性?

1 个答案:

答案 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分配都应该有效。