实体框架关系结果 Web API 序列化错误
本文关键字:API 序列化 错误 Web 结果 框架 关系 实体 | 更新日期: 2023-09-27 18:30:57
我在我的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();
}
}
我的方法是使用延迟加载获取数据,并将 JSON 数据序列化为 Web API 响应。
context.Blogs.ToList()
返回关系数据(我在断点上看到)。
但是Web Api结果有错误。
异常消息:
"对象内容"1"类型无法序列化 的响应正文 内容类型"应用程序/JSON";字符集=UTF-8
内部异常:
从"博客"获取值时出错 'System.Data.Entity.DynamicProxies.Article_D002A1ECE031410435306DCEF780AFF03EBB8BD36DA603662C993107FAEB1917 "ExceptionType": "Newtonsoft.Json.JsonSerializationException
我设置了我的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
方法,从而触发延迟加载。为此,您可以使用第三方软件包,例如自动映射器,但它们可能会导致开销。
对于API,我个人建议Eager Load。API 的要点是,您作为开发设计端点,您可以限制可以使用和不使用的内容。如果你想要延迟加载,那么我建议MVC是一个更好的选择。
尝试在控制器中使用数据传输对象。就我而言,这解决了问题。BlogModel 是必须添加才能使用的新类的名称,因为它与实体类具有相同的属性 DTO.It。
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;
}