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

Cam*_*Dev 102 c# asp.net json asp.net-web-api

我正在使用ASP.NET MVC 5 Web Api.我想咨询我的所有用户.

我写了api/users,我收到了这个:

"'ObjectContent`1'类型无法为内容类型'application/json; charset = utf-8'"序列化响应正文

在WebApiConfig中,我已添加以下行:

HttpConfiguration config = new HttpConfiguration();
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; 
Run Code Online (Sandbox Code Playgroud)

但它仍然无效.

我的返回数据函数是这样的:

public IEnumerable<User> GetAll()
{
    using (Database db = new Database())
    {
        return db.Users.ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

Luc*_*lli 137

如果您正在使用EF,除了在Global.asax上添加以下代码

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
    .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters
    .Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);          
Run Code Online (Sandbox Code Playgroud)

不要忘记导入

using System.Data.Entity;
Run Code Online (Sandbox Code Playgroud)

然后您可以返回自己的EF模型

就那么简单!

  • 关于此代码的作用及其含义的一些解释将受到欢迎. (16认同)

jen*_*ndp 73

当涉及从Web Api(或任何其他Web服务)将数据返回给使用者时,我强烈建议不要传回来自数据库的实体.使用模型可以更加可靠和可维护,在模型中您可以控制数据的外观,而不是数据库.这样你就不必在WebApiConfig中乱用格式化程序了.您可以创建一个将子模型作为属性的UserModel,并删除返回对象中的引用循环.这使得序列化器更加快乐.

此外,如果您只是在请求中指定"接受"标头,则无需删除格式化程序或支持的媒体类型.玩弄这些东西有时会让事情变得更加混乱.

例:

public class UserModel {
    public string Name {get;set;}
    public string Age {get;set;}
    // Other properties here that do not reference another UserModel class.
}
Run Code Online (Sandbox Code Playgroud)

  • 您正在返回实体.实体是指DB中可以通过唯一ID检索的对象.您将从数据库返回所有用户实体.我建议您创建一个名为"UserModel"的新类,并为从数据库中获取的每个User实体创建一个新的数据模型类实例,其中填充了您要公开的必要信息.返回一个IEnumerable的UserModel对象,而不是User实体.确保模型属性不引用UserModel类的实例.这就是让你解决这个问题的原因. (4认同)
  • ncampuzano是正确的,你不想返回自动生成的实体.如果您使用存储过程进行数据库访问,则分离将更加清晰.您需要生成一个C#值对象,并将IDataReader中的值映射到值对象.由于您正在使用EF,因此会为您生成类,但这些类是特殊的EF类,它们比值对象更多.您应该只向客户端返回"哑"值对象. (2认同)

Md.*_*rim 52

如果正确的答案是一种方法,但是当你可以通过一个配置设置修复它时,它是一种过度杀伤力.

最好在dbcontext构造函数中使用它

public DbContext() // dbcontext constructor
            : base("name=ConnectionStringNameFromWebConfig")
{
     this.Configuration.LazyLoadingEnabled = false;
     this.Configuration.ProxyCreationEnabled = false;
}
Run Code Online (Sandbox Code Playgroud)

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


Bim*_*Das 34

将此代码添加到global.asax下面Application_Start:

从更新.Ignore.Serialize.它必须工作.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
            GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
Run Code Online (Sandbox Code Playgroud)


小智 11

public class UserController : ApiController
{

   Database db = new Database();

   // construction
   public UserController()
   {
      // Add the following code
      // problem will be solved
      db.Configuration.ProxyCreationEnabled = false;
   }

   public IEnumerable<User> GetAll()
    {
            return db.Users.ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)


Kas*_*sen 10

我不喜欢这段代码:

foreach(var user in db.Users)

作为替代方案,人们可​​能会做这样的事情,这对我有用:

var listOfUsers = db.Users.Select(r => new UserModel
                         {
                             userModel.FirstName = r.FirstName;
                             userModel.LastName = r.LastName;

                         });

return listOfUsers.ToList();
Run Code Online (Sandbox Code Playgroud)

但是,我最终使用了Lucas Roselli的解决方案.

更新:通过返回匿名对象简化:

var listOfUsers = db.Users.Select(r => new 
                         {
                             FirstName = r.FirstName;
                             LastName = r.LastName;
                         });

return listOfUsers.ToList();
Run Code Online (Sandbox Code Playgroud)


aem*_*mre 8

我使用此代码将其解析为WebApiConfig.cs文件

var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; 
config.Formatters.Remove(config.Formatters.XmlFormatter);
Run Code Online (Sandbox Code Playgroud)


Ale*_*lex 6

还有这种情况产生相同的错误:

如果返回是List<dynamic>web api方法

例:

public HttpResponseMessage Get()
{
    var item = new List<dynamic> { new TestClass { Name = "Ale", Age = 30 } };

    return Request.CreateResponse(HttpStatusCode.OK, item);
}

public class TestClass
{
    public string Name { get; set; }
    public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

因此,对于这种情况,请使用返回类中的[KnownTypeAttribute](所有这些),如下所示:

[KnownTypeAttribute(typeof(TestClass))]
public class TestClass
{
    public string Name { get; set; }
    public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这适合我!


Er *_*n G 6

将其添加到您Application_Start()Global.asax文件方法中应该可以解决问题

protected void Application_Start()
{
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
        .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    GlobalConfiguration.Configuration.Formatters
        .Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter); 
// ...
}
Run Code Online (Sandbox Code Playgroud)

方法2:[不推荐]
如果使用EntityFramework,则可以在DbContext类构造函数中禁用代理。注意:如果您更新模型,此代码将被删除

public class MyDbContext : DbContext
{
  public MyDbContext()
  {
    this.Configuration.ProxyCreationEnabled = false;
  }
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

172260 次

最近记录:

6 年,1 月 前