[英]Serializing an object with restsharp and passing it to WebApi not serializing list
[英]Serializing Parent/Child Object to with EF and WebApi
我在实体框架中有以下模型:
public class Customer
{
[XmlIgnore]
public virtual ICollection<Customer> Children { get; set; }
public string Name { get; set; }
}
现在我尝试使用web api序列化它:
public class CustomerController:ApiController {
public HttpResponseMessage GetAll()
{
using (var tc = new DataContext())
{
List<Customer> allCustomers = tc.Customers.ToList();
return Request.CreateResponse(HttpStatusCode.OK, allCustomers);
}
}
}
当我这样做并使用POST调用该方法时,我收到以下错误:
'ObjectContent`1'类型无法序列化内容类型'application / json的响应主体; 字符集= utf-8的
InnerException:“从'System.Data.Entity.DynamicProxies.Customer'上的'Children'获取值时出错”
InnerException(2):“ObjectContext实例已被释放,不能再用于需要连接的操作。”
customers.Children目前是一个空列表。
我猜这个问题的出现是因为儿童与客户的类型相同,导致“无限序列化循环”。 (我没有更好的词来形容)
我已经尝试过XmlIgnore来防止该属性被序列化但没有效果。
不要将导航属性声明为virtual
或禁用延迟加载行为。 默认情况下启用延迟加载,通过创建派生代理类型的实例,然后覆盖virtual
属性以添加加载挂钩来实现。 因此,如果您想使用XML序列化程序,我建议您关闭延迟加载:
public class YourContext : DbContext
{
public YourContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}
如果要加载相关实体( Children
),可以使用Include
扩展方法作为查询的一部分。 此行为称为Eager Loading 。
using System.Data.Entity; // For extension method `Include`
List<Customer> allCustomers = tc.Customers.Include(c=>c.Children).ToList();
这些链接可以帮助您更好地理解我在答案中解释的内容:
如果从导航属性中删除virtual
关键字,则POCO实体不符合第二个链接中描述的要求,因此,EF不会创建代理类来延迟加载导航属性。 但是,如果禁用延迟加载,即使导航属性是virtual
,也不会在任何实体中加载它们。 在使用序列化程序时禁用延迟加载是个好主意。 大多数序列化程序通过访问类型实例上的每个属性来工作。
仅仅为了知识:以下也有效:
public class Customer
{
[XmlIgnore,JSonIgnore]
public virtual ICollection<Customer> Children { get; set; }
public string Name { get; set; }
}
神奇的是那里的“JsonIgnore”。
尽管如此:@octavioccl的答案是一个更好的解决方案,需要更多的工作,但创建更好的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.