validate net iactionresult handling exceptions error code catch asp all c# asp.net asp.net-mvc asp.net-mvc-4 asp.net-web-api

c# - net - web api error handling



Devolver un tipo anónimo desde MVC 4 Web Api falla con un error de serialización (3)

Estoy empezando con MVC 4 Web API y parece que no entiendo cómo funciona.

Antes de la API web, tenía un método de acción MVC simple como este:

public JsonResult User() { return Json(new { firstName = "Joe", lastName = "Jacobs", email = "[email protected]" }); }

Eso funcionaría bien. En el nuevo controlador API web estoy tratando de hacer algo similar.

public object User() { return new { firstName = "Joe", lastName = "Jacobs", email = "[email protected]" } }

Esto falla con un error de serialización:

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

Excepción interna:

Escriba ''<> f__AnonymousType1`3 [System.String, System.String, System.String]'' no se puede serializar. Considere marcarlo con el atributo DataContractAttribute y marcar todos sus miembros que desee serializar con el atributo DataMemberAttribute. Si el tipo es una colección, considere marcarlo con CollectionDataContractAttribute. Consulte la documentación de Microsoft .NET Framework para otros tipos compatibles.

¿Qué no entiendo acerca de devolver el tipo anónimo desde el controlador API?


Si miras al Fiddler (muestra aquí uso Firefox)

Por defecto, la solicitud del navegador aceptará application / xml, no application / json

Pero puedes crear una solicitud falsa desde Fiddler agregando un encabezado:

Accept: application/json

Funcionará

Desde el enlace :

El serializador XML no admite tipos anónimos ni instancias de JObject. Si utiliza estas funciones para sus datos JSON, debe eliminar el formateador XML de la interconexión, tal como se describe más adelante en este artículo.

Cómo eliminar XmlFormatter :

var configuration = GlobalConfiguration.Configuration; configuration.Formatters.Remove(configuration.Formatters.XmlFormatter);


Descubrí que a la API no le gustaba devolver una lista sin procesar. En cambio, tuve que crear un objeto y establecer el valor del objeto como mi lista; ver la primera declaración de devolución.

Ejemplo:

public IHttpActionResult GetMessages(int messageFeedId, int lastMessageId) { List<Message> messageDomainObjects = MessageService.GetMessages(messageFeedId, lastMessageId); if (messageDomainObjects.Any()) { var messages = messageDomainObjects.Select(m => new MessageModel( m.Id, m.Message, m.CreatedDate, m.IsActive, new UserModel( m.User.Id, m.User.FirstName, m.User.LastName ) )); return Ok(new { messages = messages }); } else { return Ok(new { }); } }


También puede usar JsonMediaTypeFormatter para que no necesite el JSONObject y las clases relacionadas. Luego puede devolver un tipo dinámico en su clase de controlador.

public static void Register(HttpConfiguration config) { config.Formatters.Clear(); config.Formatters.Add(new JsonMediaTypeFormatter()); config.MapHttpAttributeRoutes(); } public class YourController : ApiController { [HttpGet, Route("getstuff/{stuffId}")] public dynamic Get(string stuffId) { var stuff = Model.Stuff.Get(stuffId); return new { success= stuff != null, stuffId = stuff.Id, name = stuff.Name }; } }

Si también desea dar soporte a Jsonp, puede heredar JsonMediaTypeFormatter y crear su propio JsonpMediaTypeFormatter (que también se puede encontrar en : https://.com/a/12492552/1138266 ).