[英]Entity Framework relational result Web Api serialization error
我在Wep Api项目中使用实体框架。 我的模型是现实的,并符合以下要求:
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
public class Article
{
public int Id { get; set; }
public int BlogId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public virtual Blog Blog { get; set; }
}
上下文是这样的:
public class BloggingContext: DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Article> Articles { get; set; }
}
我在asp.net Web Api控制器中使用它。
public class BlogController: ApiController{
public IEnumerable<Blog> Get(){
var context = new BloggingContext();
return context.Blogs.ToList();
}
}
我的方法是通过延迟加载获取数据,并作为Web Api响应序列化为JSON数据。
context.Blogs.ToList()
返回关系数据(我在断点上看到)。
但是Web Api结果有错误。
异常消息:
'ObjectContent`1'类型未能序列化内容类型'application / json的响应主体; 字符集= utf-8的
内部异常:
从“ System.Data.Entity.DynamicProxies.Article_D002A1ECE031410435306DCEF780AFF03EBB8BD36DA603662C993107FAEB1917“ ExceptionType”上的“博客”获取值时出错
我设置了WebApiConfig.cs
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
jsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
您可以尝试禁用代理生成。 至少,如果它不能解决问题,则可能会给您带来更明确的例外。
context.Configuration.ProxyCreationEnabled = false;
老懒加载问题! 好好玩!
因此,首先,当您断点并评估实体时,它本身会触发延迟加载。 这样的实体框架很聪明,但没有帮助。 实际上,如果您不进行调试,则这些相同的属性将为null。
您在此处有2个选项:1.急切加载或2.如前所述,使用传输对象。 但是他们为什么会这样。
很明显。 通过使用context.Blogs.Include(x => x... etc)
您告诉实体框架只是继续并加载它们,因为我们将需要它。
为什么使用传输对象有效? 为了将数据传输到新对象中,您必须在旧实体内的所有属性上调用Get
方法,从而触发延迟加载。 为此,您可以使用第三方软件包,例如AutoMapper,但它们可能会导致开销。
对于API,我个人建议进行Eager加载。 API的要点是您作为开发设计的终点,并限制了可以使用和不能使用的内容。 如果您想要延迟加载,那么我建议使用MVC是更好的选择。
尝试在控制器中使用数据传输对象。在我的情况下,此问题已解决.BlogModel是您必须添加以用作DTO的新类的名称,它具有与实体类相同的属性。
public IEnumerable<Blog> Get(){
List<BlogModel> listofModels = new List<BlogModel>();
foreach(var model in whateveristhenameofyourentity.Blogs)
{
BlogModel blogModel = new BlogModel();
blogModel.name = model.name;
.
.
.
listofModels.Add(BlogModel);
}
IEnumerable<BlogModel> models = listofModels.AsIEnumerable();
return models;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.