supportedmediatypes new net mvc mediatypeheadervalue jsonformatter iactionresult formatters asp c# asp.net-web-api

c# - new - ¿Cómo forzar a ASP.NET Web API a devolver datos JSON o XML en función de mi entrada?



web api json c# (7)

Intento obtener los datos XML de salida o JSON en función de mi entrada. Utilicé el código de la API WEB a continuación, pero no pude obtener el resultado exacto.

public string Get(int id) { if (GlobalConfiguration.Configuration.Formatters.XmlFormatter == null) { GlobalConfiguration.Configuration.Formatters.Add(GlobalConfiguration.Configuration.Formatters.XmlFormatter); } if (GlobalConfiguration.Configuration.Formatters.JsonFormatter == null) { GlobalConfiguration.Configuration.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter); } if (id == 1) { GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter); GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true; } else { GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter); GlobalConfiguration.Configuration.Formatters.JsonFormatter.UseDataContractJsonSerializer = true; } return "value"; }


Agregue el siguiente código del evento global.asax en el archivo global.asax . En API Url, agregue la cadena de consulta:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add( new QueryStringMapping("type", "json", new MediaTypeHeaderValue("application/json"))); GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add( new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml")));

p.ej:

for xml : http://localhost:49533/api/?type=xml for json: http://localhost:49533/api/?type=json


Lo analizó un poco más y encontró su respuesta en otra publicación :

public HttpResponseMessage Get(int id) { string content = "value"; if (id == 1) { return Request.CreateResponse<string>(HttpStatusCode.OK, content, Configuration.Formatters.JsonFormatter); } return Request.CreateResponse<string>(HttpStatusCode.OK, content, Configuration.Formatters.XmlFormatter); }


Lo que intenta hacer no funcionará en un entorno de subprocesos múltiples. No puede agregar y eliminar de la colección de formateadores según cada solicitud. Aquí hay una mejor manera de lograr lo que quieres.

public HttpResponseMessage Get(int id) { Foo foo = new Foo(); var content = new ObjectContent<Foo>(foo, ((id == 1) ? Configuration.Formatters.XmlFormatter : Configuration.Formatters.JsonFormatter)); return new HttpResponseMessage() { Content = content }; }


QueryStringMapping` es una buena solución, pero necesito un valor predeterminado para el tipo.

para xml: localhost:49533/api/?type=xml

para json: localhost:49533/api/

Resuelvo esa situación de esa manera:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); var jSettings = new JsonSerializerSettings(); GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = jSettings; GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", new MediaTypeHeaderValue("application/xml")));


Si bien la respuesta aceptada por parece ser la mejor para su situación específica (es decir, el uso de MediaTypeMappings), alternativamente puede tener dos métodos diferentes, uno que devuelva XML y otro que devuelva JSON. Para hacerlo, puede crear una instancia de HttpConfiguration específica del controlador (para evitar modificar la de ConfiguraciónConfiguración.Global):

public MyReturnType GetMyTypeAsXml() { Configuration = new HttpConfiguration(); Configuration.Formatters.Clear(); Configuration.Formatters.Add(new XmlMediaTypeFormatter()); return new MyReturnType(); } public MyReturnType GetMyTypeAsJson() { Configuration = new HttpConfiguration(); Configuration.Formatters.Clear(); Configuration.Formatters.Add(new JsonMediaTypeFormatter()); return new MyReturnType(); }

No estoy seguro de la cantidad de sobrecarga que hay en girar una nueva instancia de HttpConfiguration (sospecho que no mucho), pero la nueva instancia viene con la colección de formateadores llena por defecto, por lo que debes borrarla justo después de crear instancias eso. Tenga en cuenta que si no usa Configuration = new HttpConfiguration (), y en su lugar modifica Configuration directamente, modifica la propiedad GlobalConfiguration.Configuration (por lo que afectará a todos sus otros métodos de WebApi, ¡mal!).


Si su solicitud especifica el tipo de mime, por ejemplo application/json , la API web formateará la respuesta de manera apropiada.

Si intenta depurar su API web manualmente, use una herramienta como Fiddler 2 para especificar el tipo.

Este artículo describe el concepto.


También funciona para forzar los encabezados de aceptación. Una gran opción si no siempre regresas HttpResponseMessage''s . Es decir

Request.Headers.Add("Accept", "text/json"); return Request.CreateResponse(HttpStatusCode.OK, yourobject);

o

Request.Headers.Add("Accept", "application/xml"); return new Rss20FeedFormatter(feed);