无法序列化 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.asaxApplication_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【参考方案5】:

我遇到了同样的问题。我解决了它。我把默认构造函数放到了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 中的响应的主要内容,如果未能解决你的问题,请参考以下文章

Web API:无法序列化内容类型的响应正文

无法使用Json在Web API中序列化响应

Asp.Net Web API 错误:“ObjectContent`1”类型无法序列化内容类型“application/xml”的响应正文;字符集=utf-8'

Asp.Net Web API错误:'ObjectContent`1'类型无法序列化内容类型'application / xml的响应主体;字符集= UTF-8'(代码

无法反序列化 text/html json 响应

从 .NET Core Web API 调用 SalesForce API 并将响应反序列化为 c# 对象?