net - web api return json example




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

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.


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 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.


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 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 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.


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

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


          ............................
      }
}

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.


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




asp.net-web-api