【问题标题】:failed to serialize the response in Web API无法序列化 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;
}

为什么会出现这个错误?

【问题讨论】:

标签: c# serialization asp.net-web-api


【解决方案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 Id{get;set;}
public string Title{get;set;}
public IList<Location> Locations{get;set;}
}

ViewMapper/Dto

public class TagResultsViewMapper
{
public int Id{get;set;}
public string Title{get;set;}
//just remove the following relationship 
//public IList<Location> Locations{get;set;}
}

【讨论】:

    【解决方案3】:

    把它放在构造函数中。希望这能解决问题:

        public MyController()
        {
    
            db.Configuration.ProxyCreationEnabled = false;
        }
    

    【讨论】:

    【解决方案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 正在寻找一个在我的数据库中不存在的 表!!

                【讨论】:

                  猜你喜欢
                  • 2014-05-30
                  • 1970-01-01
                  • 2016-02-07
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-09-13
                  相关资源
                  最近更新 更多