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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法使用Json在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; 

但它仍然无效。

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

public IEnumerable<User> GetAll()

    using (Database db = new Database())
    
        return db.Users.ToList();
    

答案

当涉及从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.

另一答案

我个人最喜欢的:只需将下面的代码添加到App_Start/WebApiConfig.cs。这将默认返回json而不是XML,并且还可以防止出现错误。无需编辑Global.asax以删除XmlFormatter等。

'ObjectContent`1'类型无法序列化内容类型'application / xml的响应主体;字符集= utf-8的

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
另一答案

使用AutoMapper ...

public IEnumerable<User> GetAll()
    
        using (Database db = new Database())
        
            var users = AutoMapper.Mapper.DynamicMap<List<User>>(db.Users);
            return users;
        
    
另一答案

使用以下命名空间:

using System.Web.OData;

代替 :

using System.Web.Http.OData;

它对我有用

另一答案

对我有用的解决方案:

  1. 使用[DataContract]为每个属性的类和[DataMember]属性进行序列化。这足以获得Json结果(例如来自fiddler)。
  2. 要获取xml序列化,请在Global.asax中写入以下代码: var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;
  3. 阅读这篇文章,它帮助我理解了序列化:https://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization
另一答案

要添加到jensendp的答案:

我会将实体传递给用户创建的模型,并使用该实体的值来设置新创建的模型中的值。例如:

public class UserInformation 
   public string Name  get; set; 
   public int Age  get; set; 

   public UserInformation(UserEntity user) 
      this.Name = user.name;
      this.Age = user.age;
   

然后将您的返回类型更改为:IEnumerable<UserInformation>

另一答案

This is my error

我基本上添加了一行

  • entities.Configuration.ProxyCreationEnabled = false;

到UsersController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using UserDataAccess;

namespace SBPMS.Controllers

    public class UsersController : ApiController
    


        public IEnumerable<User> Get() 
            using (SBPMSystemEntities entities = new SBPMSystemEntities()) 
                entities.Configuration.ProxyCreationEnabled = false;
                return entities.Users.ToList();
            
        
        public User Get(int id) 
            using (SBPMSystemEntities entities = new SBPMSystemEntities()) 
                entities.Configuration.ProxyCreationEnabled = false;
                return entities.Users.FirstOrDefault(e => e.user_ID == id);
            
        
    

Here is my output:

另一答案

我收到此错误的另一种情况是我的数据库查询返回空值但我的用户/视图模型类型设置为不可为空。例如,将我的UserModel字段从int更改为int?已解决。

另一答案

响应类型不公开时也会发生这种情况!我返回了一个内部类,因为我使用Visual Studio生成类型。

internal class --> public class
另一答案

虽然上面的所有这些答案都是正确的,但可能需要检查InnerException> ExceptionMessage。

如果它说的是这样的话“已经处理了ObjectContext实例,并且不能再用于需要连接的操作。”由于EF的默认行为,这可能是一个问题。

通过在DbContext构造函数中指定LazyLoadingEnabled = false可以解决问题。

public class MyDbContext : DbContext

  public MyDbContext()
  
    this.Configuration.LazyLoadingEnabled = false;
  

有关EF的Eager Loading和Lazy Loading行为的更详细阅读,请参阅此qazxsw poi。

另一答案

在我的情况下,我有类似的错误消息:

'ObjectContent`1'类型无法序列化内容类型'application / xml的响应主体;字符集= UTF-8' 。

但是当我深入研究它时,问题是:

键入'name.SomeSubRootType',不要求使用数据合约名称'SomeSubRootType://schemas.datacontract.org/2004/07/WhatEverService'。如果您正在使用DataContractSerializer或者将任何静态未知的类型添加到已知类型列表中,请考虑使用DataContractResolver - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给序列化程序的已知类型列表中。

我通过添加MSDN Article解决的方式。

KnownType

这是从这个[KnownType(typeof(SomeSubRootType))] public partial class SomeRootStructureType 的灵感解决的。

参考:answer

另一答案

如果您正在使用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模型

就那么简单!

另一答案

Visual Studio 2017或2019在这方面完全没有意义,因为Visual Studio本身要求输出为json格式,而Visual Studio的默认格式为“XmlFormat”(config.Formatters.XmlFormatter)。

Visual Studio应该自动执行此操作,而不是给开发人员带来太多麻烦。

要解决此问题,请转到WebApiConfig.cs文件,然后添加

var json = config.Formatters.JsonFormatter; json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; config.Formatters.Remove(config.Formatters.XmlFormatter);

在“config.MapHttpAttributeRoutes();”之后在Register(HttpConfiguration config)方法中。这将允许您的项目生成json输出。

另一答案

在我的情况下,我解决了重建数据库。我在模型中进行了一些更改并在软件包管理器控制台中启动了Update-Database我收到以下错误:

“ALTER TABLE语句与FOREIGN KEY约束冲突”FK_dbo.Activities_dbo.Projects_ProjectId“。冲突发生在数据库”TrackEmAllContext-20190530144302“,表”dbo.Projects“,列'Id'。”

另一答案

如果:如果向WebApiConfig.cs或Global.asax.cs添加代码不适合您:

https://msdn.microsoft.com/en-us/library/ms730167(v=vs.100).aspx

添加.ToList()函数。

我尝试了所有解决方案,但以下为我工作:

.ToList();

我希望,这有帮助。

另一答案

添加以下行

var allShops = context.shops.Where(s => s.city_id == id)**.ToList()**;
return allShops;

两种方式使用this.Configuration.ProxyCreationEnabled = false; 作为ProxyCreationEnabled

  1. 将它添加到false构造函数中 DBContext

要么

  1. public ProductEntities() : base("name=ProductEntities") this.Configuration.ProxyCreationEnabled = false; 方法中添加一行 Get
另一答案

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

最好在dbcontext构

以上是关于无法使用Json在Web API中序列化响应的主要内容,如果未能解决你的问题,请参考以下文章

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

无法反序列化 JSON 响应

无法序列化 Web API 中的响应

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

无法使用 jquery 从 Web API 获取 JSON 响应

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