无法使用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;
它对我有用
对我有用的解决方案:
- 使用[DataContract]为每个属性的类和[DataMember]属性进行序列化。这足以获得Json结果(例如来自fiddler)。
- 要获取xml序列化,请在Global.asax中写入以下代码: var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;
- 阅读这篇文章,它帮助我理解了序列化: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>
我基本上添加了一行
- 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);
我收到此错误的另一种情况是我的数据库查询返回空值但我的用户/视图模型类型设置为不可为空。例如,将我的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
。
- 将它添加到
false
构造函数中DBContext
要么
- 在
public ProductEntities() : base("name=ProductEntities") this.Configuration.ProxyCreationEnabled = false;
方法中添加一行Get
如果正确的答案是一种方法,但是当你可以通过一个配置设置修复它时,它是一种过度杀伤力。
最好在dbcontext构
以上是关于无法使用Json在Web API中序列化响应的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 jquery 从 Web API 获取 JSON 响应
Asp.Net Web API 错误:“ObjectContent`1”类型无法序列化内容类型“application/xml”的响应正文;字符集=utf-8'