serialize recorrer newtonsoft library example ejemplo c# asp.net json asp.net-web-api

c# - recorrer - Error al serializar la respuesta en la API web con Json



web api c# ejemplo (18)

¡Esto también ocurre cuando el tipo de respuesta no es público! Devolví una clase interna cuando utilicé Visual Studio para generar el tipo.

internal class --> public class

Estoy trabajando con ASP.NET MVC 5 Web Api. Quiero consultar a todos mis usuarios.

Escribo: api / users y recibo esto:

"El tipo ''ObjectContent`1'' no pudo serializar el cuerpo de la respuesta para el tipo de contenido ''application / json; charset = utf-8''"

En WebApiConfig, ya agregué estas líneas:

HttpConfiguration config = new HttpConfiguration(); config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType); config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

Pero todavía no funciona

Mi función para los datos de retorno es esta:

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


Agregue este código a global.asax continuación en Application_Start :

Actualización de .Ignore a .Serialize . Debe funcionar.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize; GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);


Cuando se trata de devolver los datos al consumidor desde la API web (o cualquier otro servicio web para el caso), recomiendo no pasar entidades que provienen de una base de datos. Es mucho más confiable y sostenible utilizar Modelos en los cuales usted tiene control de cómo se ven los datos y no de la base de datos. De esta forma, no tendrá que perder tanto tiempo con los formateadores en WebApiConfig. Solo puede crear un modelo de usuario que tenga modelos secundarios como propiedades y deshacerse de los bucles de referencia en los objetos de retorno. Eso hace que el serializador sea mucho más feliz.

Además, no es necesario eliminar los formateadores o los tipos de medios compatibles normalmente si solo especifica el encabezado "Acepta" en la solicitud. Jugar con eso a veces puede hacer que las cosas sean más confusas.

Ejemplo:

public class UserModel { public string Name {get;set;} public string Age {get;set;} // Other properties here that do not reference another UserModel class. }


En mi caso, he tenido un mensaje de error similar:

El tipo ''ObjectContent`1'' no pudo serializar el cuerpo de la respuesta para el tipo de contenido ''application / xml; charset = utf-8 ''.

Pero cuando profundizo en esto, el problema fue:

Escriba ''name.SomeSubRootType'' con el nombre del contrato de datos ''SomeSubRootType: //schemas.datacontract.org/2004/07/WhatEverService'' no se espera. Considere usar DataContractResolver si está usando DataContractSerializer o agregue cualquier tipo no conocido de forma estática a la lista de tipos conocidos, por ejemplo, utilizando el atributo KnownTypeAttribute o agregándolos a la lista de tipos conocidos pasados ​​al serializador.

La forma en que resolví añadiendo KnownType .

[KnownType(typeof(SomeSubRootType))] public partial class SomeRootStructureType

Esto fue resuelto inspirado en esta answer .

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


Lo resolví usando este código para el archivo WebApiConfig.cs

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


Mi favorito personal: simplemente agregue el siguiente código a App_Start/WebApiConfig.cs . Esto devolverá json en lugar de XML por defecto y también evitará el error que tenía. No es necesario editar Global.asax para eliminar XmlFormatter etc.

El tipo ''ObjectContent`1'' no pudo serializar el cuerpo de la respuesta para el tipo de contenido ''application / xml; charset = utf-8

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));


No me gusta este código:

foreach(var user in db.Users)

Como alternativa, uno podría hacer algo como esto, que funcionó para mí:

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

Sin embargo, terminé usando la solución de Lucas Roselli.

Actualización: simplificado al devolver un objeto anónimo:

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


Otro caso en el que recibí este error fue cuando mi consulta de base de datos devolvió un valor nulo, pero mi tipo de modelo de usuario / vista se estableció como no nulo. Por ejemplo, cambiar mi campo UserModel de int a int? resuelto.


Para agregar a la respuesta de jensendp:

Pasaría la entidad a un modelo creado por el usuario y usaría los valores de esa entidad para establecer los valores en su modelo recién creado. Por ejemplo:

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; } }

Luego, cambie su tipo de devolución a: IEnumerable<UserInformation>


Si bien todas estas respuestas anteriores son correctas, es posible que desee comprobar InnerException> ExceptionMessage .

Si dice algo como esto "La instancia de ObjectContext se ha eliminado y ya no se puede usar para operaciones que requieren una conexión ". Esto podría ser un problema debido al comportamiento predeterminado de EF.

Al asignar LazyLoadingEnabled = false en tu constructor de DbContext se logrará el truco.

public class MyDbContext : DbContext { public MyDbContext() { this.Configuration.LazyLoadingEnabled = false; } }

Para una lectura más detallada sobre el comportamiento EagerLoading y LazyLoading de EF, consulte este artículo de MSDN .


Si está trabajando con EF, además de agregar el código a continuación en Global.asax

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; GlobalConfiguration.Configuration.Formatters .Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);

No te olvides de importar

using System.Data.Entity;

Entonces puedes devolver tus propios modelos EF

¡Simple como eso!


Si está trabajando con EntityFramework, debe deshabilitar el proxy en su constructor de clase DbContext como,

public class MyDbContext : DbContext { public MyDbContext() { this.Configuration.ProxyCreationEnabled = false; } }


Solución que funcionó para mí:

  1. Utilice [DataContract] para los atributos de clase y [DataMember] para que cada propiedad se serialice. Esto es suficiente para obtener el resultado de Json (por ejemplo, de fiddler).

  2. Para obtener serialización xml, escriba en Global.asax este código:

    var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;

  3. Lea este artículo, me ayudó a entender la serialización: https://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

También hay este escenario que genera el mismo error:

En caso de que el retorno sea un método List<dynamic> to web api

Ejemplo:

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; } }

Por lo tanto, para este escenario, utilice el [KnownTypeAttribute] en la clase de devolución (todos ellos) de esta manera:

[KnownTypeAttribute(typeof(TestClass))] public class TestClass { public string Name { get; set; } public int Age { get; set; } }

Esto funciona para mi!


Use AutoMapper ...

public IEnumerable<User> GetAll() { using (Database db = new Database()) { var users = AutoMapper.Mapper.DynamicMap<List<User>>(db.Users); return users; } }


Use el siguiente espacio de nombre:

using System.Web.OData;

En lugar de :

using System.Web.Http.OData;

Funcionó para mí


La respuesta correcta es una forma de hacerlo, sin embargo, es una exageración cuando se puede solucionar mediante una configuración de configuración.

Es mejor usarlo en el constructor dbcontext

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

Error de Asp.Net Web API: el tipo ''ObjectContent`1'' no pudo serializar el cuerpo de la respuesta para el tipo de contenido ''application / xml; charset = utf-8 ''


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(); } }