无法序列化 Web API 中的响应
Posted
技术标签:
【中文标题】无法序列化 Web API 中的响应【英文标题】:failed to serialize the response in Web API 【发布时间】:2012-09-20 10:04:36 【问题描述】:我正在使用 ASP.NET MVC Web API,我遇到了这个错误:
“ObjectContent`1”类型无法序列化内容类型“application/xml;”的响应正文; charset=utf-8'。
我的控制器是:
public Employee GetEmployees()
Employee employees = db.Employees.First();
return employees;
为什么会出现这个错误?
【问题讨论】:
您看到的异常是一般异常,可能由多种因素引起。检查序列化异常的InnerException
属性,找出导致序列化失败的确切原因。
您能分享一下您的员工类型的代码吗?这可能是因为 Employee 类型不可序列化...
也看看这个***.com/questions/8173524/…
JSON.NET Error Self referencing loop detected for type的可能重复
【参考方案1】:
在您的 global.asax 文件中,在 Application_start() 方法中添加以下行:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
希望对你有帮助!
【讨论】:
什么是application_start,在哪里可以找到?这条线到底应该放在哪里? 对不起,这句话是什么意思? 行已添加到Global.asax
的Application_Start
,但没有变化。
这仍然对我不起作用。但是我在这个答案的后面添加了另一行并且它起作用了: GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);我在下面创建了一个更完整的答案
这个答案不应该被接受,因为它确实删除了 XmlSerializer 而不是用 XmlSerializer 解决循环引用的问题。【参考方案2】:
嗯,以下可能会有所帮助。
我遇到了同样的异常,在我的情况下,我首先传递了为实体代码创建的实际 poco 实体。因为它包含与其他实体的关系,所以我只是在它之上创建了 viewmapper/dto 实体以返回。
现在可以正常使用了。
Poco 实体:
public class Tag
public int Idget;set;
public string Titleget;set;
public IList<Location> Locationsget;set;
ViewMapper/Dto
public class TagResultsViewMapper
public int Idget;set;
public string Titleget;set;
//just remove the following relationship
//public IList<Location> Locationsget;set;
【讨论】:
【参考方案3】:把它放在构造函数中。希望这能解决问题:
public MyController()
db.Configuration.ProxyCreationEnabled = false;
【讨论】:
优秀的解决方案。我需要将它放入构造函数中并且它起作用了。 结合 GlobalConfiguration 设置对我有用。但为什么这行得通?关于如何解决问题的任何解释?问题到底出在哪里? 了解什么是实体代理:msdn.microsoft.com/en-us/library/jj592886(v=vs.113).aspx 了解什么是 ProxyCreationEnabled:***.com/questions/7111109/…【参考方案4】:我找到了两个解决方案。第一个也是最容易实现的是将任何 IEnumerables、ICollections 更改为 List 类型。 WebAPI 可以序列化这些对象,但是它不能序列化接口类型。
public class Store
[StringLength(5)]
public string Zip5 get; set;
public virtual List<StoreReport> StoreReports get; set; //use a list here
另一种选择是不使用本机 JSON 序列化程序并在 WebApi Config 的 Register 方法中运行此覆盖:
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
【讨论】:
虽然更改为 List 对我有用,但添加无参数构造函数也对我有用,我可以继续返回 IEnumerable我遇到了同样的问题。我解决了它。我把默认构造函数放到了DTO类中。
例如:
public class User
public User()
希望它对你有用!
【讨论】:
感谢您的建议,这对我的 xml 响应有所帮助,但有谁知道它为什么需要默认构造函数?我们已经有了数据…… 我认为从响应中序列化对象时,首先调用构造函数创建对象实例,然后使用set方法将数据设置为对象实例。这是我的猜测。 这实际上应该是选择的答案,因为它没有对您需要的返回类型做出任何假设。这适用于 XML 和 JSON。感谢您发布此内容。【参考方案6】:请查看 web api 文档以了解此问题,Handling Circular Object References
问候
【讨论】:
【参考方案7】:但是如果你发现其他实体/类有这个问题,你必须为每个类创建一个新的 DTO,如果你有很多,你可以找到一个问题,我认为创建一个 DTO 只为解决这个问题并不是最好的办法……
你试过了吗?
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.All;
问候
【讨论】:
【参考方案8】:解决方案很简单。
在 LINQ 查询后添加 .ToList()(或 ToDictionary,如果需要)。
它会进行预先加载而不是延迟加载数据
【讨论】:
将操作返回类型更改为IENumerable
并将 .TiList()
添加到返回对我有用。【参考方案9】:
对我来说,这是循环引用的问题。
接受的答案对我不起作用,因为它只会改变 JSON 格式化程序的行为,但是当我从浏览器调用服务时,我得到了 XML。
为了解决这个问题,我关闭了 XML 并强制只返回 JSON。
在 Global.asax 文件中,将以下行放在 Application_Start 方法的顶部:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
现在只会返回 JSON 结果。如果您需要 XML 结果,则需要找到不同的解决方案。
【讨论】:
为我工作。但问题是我正在使用 POSTMAN。这是一个镀铬扩展。当我使用 POSTMAN 发布数据时,它工作正常。但是当我使用restsharp时,它给了我这个错误。无论如何,您的解决方案解决了我的问题 这个答案没有提供使用xml的解决方案,这就是他所要求的。 对我有用,因为我从 xml 切换到 json。 实际上,这个答案可以找到问题的根源。我收到的第一个错误是循环引用错误(试图从 MVC 控制器返回 JSON)。当我切换到 API 继承的控制器时,我开始收到此错误。当我将上面的代码添加到 Global.asax 时,错误消失了。【参考方案10】:** 从客户端从请求 web api/wcf/... 调用时会发生此错误,但作为副作用,您需要通过 include 关键字包含依赖关系。 **
public CustomerPortalContext()
: base("Name=CustomerPortalContext")
base.Configuration.ProxyCreationEnabled = false;
【讨论】:
【参考方案11】:你的问题和我的很相似。您不得直接从数据库返回数据。为此,您必须创建模型并关联要显示的数据。
在我的示例中,Json 无法序列化有关 User 的数据,我创建了一个 userModel,并且在我的 API 中,我从数据库返回 userModel 而不是 User。
User 和 UserModel 之间转换或关联数据的逻辑必须在 API 中。
Failed to serialize the response in Web API with Json
【讨论】:
【参考方案12】:如果你使用带有实体框架的 web api,一个解决方案可以是 Failed to serialize the response in Web API with Json
基本上,您需要为每个 EF 模型创建一个模型,这消除了类之间的依赖关系并允许轻松序列化。
代码:(取自参考链接)
创建用户模型
public class UserModel
public string FirstName get; set;
public string LastName get; set;
改变我的方法GetAll()
public IEnumerable<UserModel> GetAll()
using (Database db = new Database ())
List<UserModel> listOfUsers = new List<UserModel>();
UserModel userModel = new UserModel();
foreach(var user in db.Users)
userModel.FirstName = user.FirstName;
userModel.LastName = user.LastName;
listOfUsers.Add(userModel);
IEnumerable<UserModel> users = listOfUsers;
return users;
【讨论】:
【参考方案13】:如果您使用的是 EF,除了在 Global.asax 上添加以下代码
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
别忘了导入
using System.Data.Entity;
然后您可以返回自己的 EF 模型
【讨论】:
【参考方案14】:Default Entity 6 use XML to apis,在你的项目中,找到文件"Global.asax" File并添加这一行:
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
此行删除 XML 格式化程序。
【讨论】:
您好,Web API 将响应序列化为 XML 和 JSON,如果添加 header Content-Type : application/json,则响应为 JSON,您需要定义此 header,在浏览器中始终可以将其视为 XML 格式【参考方案15】:这是我从我的 odata Web API 调用返回的具体错误:
The 'ObjectContent`1' type failed to serialize the response
body for content type 'application/json; odata.metadata=minimal'.
我终于发现我的 dbContext 类在 onModelCreating 中分配了一个格式错误的表名。所以 SqlClient 正在寻找一个在我的数据库中不存在的 表!!
【讨论】:
以上是关于无法序列化 Web API 中的响应的主要内容,如果未能解决你的问题,请参考以下文章
Asp.Net Web API 错误:“ObjectContent`1”类型无法序列化内容类型“application/xml”的响应正文;字符集=utf-8'
Asp.Net Web API错误:'ObjectContent`1'类型无法序列化内容类型'application / xml的响应主体;字符集= UTF-8'(代码