net example asp json google-chrome asp.net-web-api

example - web api json c#



¿Cómo obtengo la API web de ASP.NET para devolver JSON en lugar de XML utilizando Chrome? (29)

Aquí hay una solución similar a jayson.centeno''s y otras respuestas, pero utilizando la extensión incorporada de System.Net.Http.Formatting .

public static void Register(HttpConfiguration config) { // add support for the ''format'' query param // cref: http://blogs.msdn.com/b/hongyes/archive/2012/09/02/support-format-in-asp-net-web-api.aspx config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json"); config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml"); // ... additional configuration }

La solución se orientó principalmente a admitir el formato $ para OData en las primeras versiones de WebApi, pero también se aplica a la implementación sin OData y devuelve el Content-Type: application/json; charset=utf-8 Content-Type: application/json; charset=utf-8 header en la respuesta.

Le permite agregar &$format=json o &$format=xml al final de su uri cuando prueba con un navegador. No interfiere con otros comportamientos esperados cuando usa un cliente que no es de navegador, donde puede configurar sus propios encabezados.

Al usar la nueva API web de ASP.NET , en Chrome , estoy viendo XML. ¿Cómo puedo cambiarlo para solicitar JSON y poder verlo en el navegador? Creo que es solo una parte de los encabezados de solicitud, ¿estoy en lo correcto?


Como la pregunta es específica de Chrome, puede obtener la extensión Postman, que le permite configurar el tipo de contenido de la solicitud.


Desde MSDN Creación de una aplicación de una sola página con ASP.NET y AngularJS (aproximadamente 41 minutos).

public static class WebApiConfig { public static void Register(HttpConfiguration config) { // ... possible routing etc. // Setup to return json and camelcase it! var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter; formatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(); }

Debería ser actual, lo probé y funcionó.


Echa un vistazo a la negociación de contenido en la WebAPI. Estas ( Parte 1 y Parte 2 ) maravillosamente detalladas y detalladas publicaciones en el blog explican cómo funciona.

En resumen, tiene razón y solo necesita configurar los encabezados de solicitud de Accept o Content-Type . Dado que su Acción no está codificada para devolver un formato específico, puede configurar Accept: application/json .


El uso de RequestHeaderMapping funciona incluso mejor, porque también establece Content-Type = application/json en el encabezado de respuesta, lo que permite a Firefox (con el complemento JSONView) formatear la respuesta como JSON.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings .Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", "text/html", StringComparison.InvariantCultureIgnoreCase, true, "application/json"));


En el Global.asax estoy usando el siguiente código. Mi URI para obtener JSON es http://www.digantakumar.com/api/values?json=true

protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("json", "true", "application/json")); }


En el WebApiConfig.cs , agregue al final de la función de registro :

// Remove the XML formatter config.Formatters.Remove(config.Formatters.XmlFormatter);

Source


Esta es la forma más fácil que he usado en mis aplicaciones. Agregue las siguientes 3 líneas de código en App_Start//WebApiConfig.cs en la función de Register

var formatters = GlobalConfiguration.Configuration.Formatters; formatters.Remove(formatters.XmlFormatter); config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));

La API web de Asp.net serializará automáticamente su objeto devuelto a JSON y, al agregarse la application/json en el encabezado, el navegador o el receptor entenderán que está devolviendo el resultado JSON.


Este código hace que json sea mi predeterminado y también me permite usar el formato XML. Acabo de añadir el xml=true .

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml")); GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

¡Gracias a todos!


Ha pasado algo de tiempo desde que se hizo esta pregunta (y se respondió), pero otra opción es anular el encabezado Aceptar en el servidor durante el procesamiento de la solicitud utilizando un MessageHandler como se muestra a continuación:

public class ForceableContentTypeDelegationHandler : DelegatingHandler { protected async override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { var someOtherCondition = false; var accHeader = request.Headers.GetValues("Accept").FirstOrDefault(); if (someOtherCondition && accHeader.Contains("application/xml")) { request.Headers.Remove("Accept"); request.Headers.Add("Accept", "application/json"); } return await base.SendAsync(request, cancellationToken); } }

Donde someOtherCondition puede ser cualquier cosa, incluido el tipo de navegador, etc. Esto sería para casos condicionales en los que solo a veces queremos anular la negociación de contenido predeterminada. De lo contrario, según otras respuestas, simplemente eliminaría un formateador innecesario de la configuración.

Tendrás que registrarte por supuesto. Usted puede hacer esto globalmente:

public static void Register(HttpConfiguration config) { config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler()); }

o en una ruta por ruta:

config.Routes.MapHttpRoute( name: "SpecialContentRoute", routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}", defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional }, constraints: null, handler: new ForceableContentTypeDelegationHandler() );

Y dado que se trata de un controlador de mensajes, se ejecutará en los extremos de solicitud y respuesta de la canalización de manera muy similar a un HttpModule . Por lo tanto, puede reconocer fácilmente la anulación con un encabezado personalizado:

public class ForceableContentTypeDelegationHandler : DelegatingHandler { protected async override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { var wasForced = false; var someOtherCondition = false; var accHeader = request.Headers.GetValues("Accept").FirstOrDefault(); if (someOtherCondition && accHeader.Contains("application/xml")) { request.Headers.Remove("Accept"); request.Headers.Add("Accept", "application/json"); wasForced = true; } var response = await base.SendAsync(request, cancellationToken); if (wasForced){ response.Headers.Add("X-ForcedContent", "We overrode your content prefs, sorry"); } return response; } }


La aplicación Chrome "Advanced REST Client" me pareció excelente para trabajar con los servicios REST. Puede configurar Content-Type para application/json entre otras cosas: Cliente REST avanzado


La devolución del formato correcto se realiza mediante el formateador de tipo multimedia. Como han mencionado otros, puedes hacer esto en la clase WebApiConfig :

public static class WebApiConfig { public static void Register(HttpConfiguration config) { ... // Configure Web API to return JSON config.Formatters.JsonFormatter .SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html")); ... } }

Para más información, verifique:

En caso de que sus acciones devuelvan XML (que es el caso de forma predeterminada) y necesita solo un método específico para devolver JSON, puede usar un ActionFilterAttribute y aplicarlo a esa acción específica.

Atributo del filtro:

public class JsonOutputAttribute : ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { ObjectContent content = actionExecutedContext.Response.Content as ObjectContent; var value = content.Value; Type targetType = actionExecutedContext.Response.Content.GetType().GetGenericArguments()[0]; var httpResponseMsg = new HttpResponseMessage { StatusCode = HttpStatusCode.OK, RequestMessage = actionExecutedContext.Request, Content = new ObjectContent(targetType, value, new JsonMediaTypeFormatter(), (string)null) }; actionExecutedContext.Response = httpResponseMsg; base.OnActionExecuted(actionExecutedContext); } }

Aplicando a la acción:

[JsonOutput] public IEnumerable<Person> GetPersons() { return _repository.AllPersons(); // the returned output will be in JSON }

Tenga en cuenta que puede omitir la palabra Attribute en la decoración de acción y usar solo [JsonOutput] lugar de [JsonOutputAttribute] .


La mayoría de las respuestas anteriores tienen perfecto sentido. Dado que los datos se están formateando en formato XML, eso significa que se aplica el formateador XML, de modo que puede ver el formato JSON simplemente eliminando XMLFormatter del parámetro HttpConfiguration como

public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Formatters.Remove(config.Formatters.XmlFormatter); config.EnableSystemDiagnosticsTracing(); }

ya que JSON es el formato predeterminado


MVC4 Sugerencia rápida nº 3: eliminar el formateador XML de la API web de ASP.Net

En Global.asax agrega la línea:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

al igual que:

protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); BundleTable.Bundles.RegisterTemplateBundles(); GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); }


Me gusta más el enfoque de Felipe Leusin : asegúrese de que los navegadores obtengan JSON sin comprometer la negociación de contenido de los clientes que realmente desean XML. La única pieza que faltaba para mí era que los encabezados de respuesta aún contenían tipo de contenido: texto / html. ¿Por qué fue eso un problema? Porque uso la extensión JSON Formatter Chrome , que inspecciona el tipo de contenido, y no consigo el formato bonito al que estoy acostumbrado. Lo solucioné con un sencillo formateador personalizado que acepta solicitudes de texto / html y devuelve respuestas de aplicación / json:

public class BrowserJsonFormatter : JsonMediaTypeFormatter { public BrowserJsonFormatter() { this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); this.SerializerSettings.Formatting = Formatting.Indented; } public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { base.SetDefaultContentHeaders(type, headers, mediaType); headers.ContentType = new MediaTypeHeaderValue("application/json"); } }

Registrarse como tal:

config.Formatters.Add(new BrowserJsonFormatter());


Me sorprende ver tantas respuestas que requieren codificación para cambiar un caso de uso único (GET) en una API en lugar de usar una herramienta adecuada, lo que debe instalarse una vez y se puede usar para cualquier API (propia o de terceros) y todo casos de uso.

Así que la buena respuesta es:

  1. Si solo desea solicitar json u otro tipo de contenido, instale Requestly o una herramienta similar y modifique el encabezado Aceptar.
  2. Si desea utilizar POST también y tiene un formato agradable json, xml, etc., use una extensión de prueba de API adecuada como Postman o ARC .

No me queda claro por qué hay toda esta complejidad en la respuesta. Seguro que hay muchas formas de hacerlo, con QueryStrings, encabezados y opciones ... pero lo que creo que es la mejor práctica es simple. Solicita una URL simple (por ejemplo, http://yourstartup.com/api/cars ) y a cambio obtiene JSON. Obtienes JSON con el encabezado de respuesta adecuado:

Content-Type: application/json

Al buscar una respuesta a esta misma pregunta, encontré este hilo y tuve que seguir adelante porque esta respuesta aceptada no funciona exactamente. Encontré una respuesta que creo que es demasiado simple para no ser la mejor:

Establecer el formateador predeterminado de WebAPI

Voy a añadir mi consejo aquí también.

WebApiConfig.cs namespace com.yourstartup { using ...; using System.Net.Http.Formatting; ... config.Formatters.Clear(); //because there are defaults of XML.. config.Formatters.Add(new JsonMediaTypeFormatter()); }

Tengo una pregunta de dónde provienen los valores predeterminados (al menos los que estoy viendo). ¿Son los valores predeterminados de .NET, o tal vez creados en otro lugar (por alguien más en mi proyecto)? En fin, espero que esto ayude.


No uses tu navegador para probar tu API.

En su lugar, intente utilizar un cliente HTTP que le permita especificar su solicitud, como CURL o incluso Fiddler.

El problema con este problema está en el cliente, no en la API. La API web se comporta correctamente, de acuerdo con la solicitud del navegador.


Se puede utilizar de la siguiente manera:

GlobalConfiguration.Configuration.Formatters.Clear(); GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());


Según la última versión de ASP.net WebApi 2,

bajo WebApiConfig.cs , esto funcionará

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter); config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);


Si hace esto en el WebApiConfig obtendrá JSON de forma predeterminada, pero aún así le permitirá devolver XML si pasa text/xml como el encabezado Accept solicitud.

public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml"); config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType); } }

Si no está utilizando el tipo de proyecto MVC y, por lo tanto, no tenía esta clase para comenzar, vea esta respuesta para obtener detalles sobre cómo incorporarlo.


Simplemente cambia el App_Start/WebApiConfig.cs esta manera:

public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); //Below formatter is used for returning the Json result. var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml"); config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType); //Default route config.Routes.MapHttpRoute( name: "ApiControllerOnly", routeTemplate: "api/{controller}" ); }


Solo agregue esas dos líneas de código en su clase WebApiConfig

public static class WebApiConfig { public static void Register(HttpConfiguration config) { //add this two line config.Formatters.Clear(); config.Formatters.Add(new JsonMediaTypeFormatter()); ............................ } }


Una opción rápida es utilizar la especialización MediaTypeMapping. Este es un ejemplo del uso de QueryStringMapping en el evento Application_Start:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));

Ahora, siempre que la URL contenga la cadena de consulta? A = b en este caso, la respuesta de Json se mostrará en el navegador.


Usé un filtro de acción global para eliminar Accept: application/xml cuando el encabezado User-Agent contiene "Chrome":

internal class RemoveXmlForGoogleChromeFilter : IActionFilter { public bool AllowMultiple { get { return false; } } public async Task<HttpResponseMessage> ExecuteActionFilterAsync( HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) { var userAgent = actionContext.Request.Headers.UserAgent.ToString(); if (userAgent.Contains("Chrome")) { var acceptHeaders = actionContext.Request.Headers.Accept; var header = acceptHeaders.SingleOrDefault( x => x.MediaType.Contains("application/xml")); acceptHeaders.Remove(header); } return await continuation(); } }

Parece funcionar.


Usando la respuesta de Felipe Leusin durante años, después de una actualización reciente de las bibliotecas principales y de Json.Net, me topé con una excepción System.MissingMethodException : SupportedMediaTypes. La solución en mi caso, con suerte útil para otros que experimentan la misma excepción inesperada, es instalar System.Net.Http . NuGet aparentemente lo elimina en algunas circunstancias. Después de una instalación manual, el problema fue resuelto.


WebApiConfig es el lugar donde puede configurar si desea imprimir en json o xml. por defecto es xml. en la función de registro podemos usar los formateadores de configuración de Http para formatear la salida. Se requiere System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") para obtener la salida en el formato json.


Acabo de agregar lo siguiente en la clase App_Start / WebApiConfig.cs en mi proyecto MVC Web API.

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

Eso asegura que obtenga json en la mayoría de las consultas, pero puede obtener xml cuando envía text/xml .

Si necesita tener la respuesta Content-Type como application/json , verifique la respuesta de Todd a continuación .

NameSpace está utilizando System.Net.Http.Headers ;


config.Formatters.Remove(config.Formatters.XmlFormatter);