¿Cómo forzar a ASP.NET Web API a devolver siempre JSON?


103

ASP.NET Web API realiza la negociación de contenido de forma predeterminada: devolverá XML o JSON u otro tipo según el Acceptencabezado. No necesito / quiero esto, ¿hay alguna manera (como un atributo o algo así) de decirle a la API web que siempre devuelva JSON?


Es posible que pueda hacer esto eliminando todos los formateadores excepto json deGlobalConfiguration.Configuration.Formatters
Claudio Redi

Respuestas:


75

Compatible solo con JSON en ASP.NET Web API: EL CAMINO CORRECTO

Reemplace IContentNegotiator con JsonContentNegotiator:

var jsonFormatter = new JsonMediaTypeFormatter();
//optional: set serializer settings here
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));

Implementación de JsonContentNegotiator:

public class JsonContentNegotiator : IContentNegotiator
{
    private readonly JsonMediaTypeFormatter _jsonFormatter;

    public JsonContentNegotiator(JsonMediaTypeFormatter formatter) 
    {
        _jsonFormatter = formatter;    
    }

    public ContentNegotiationResult Negotiate(
            Type type, 
            HttpRequestMessage request, 
            IEnumerable<MediaTypeFormatter> formatters)
    {
        return new ContentNegotiationResult(
            _jsonFormatter, 
            new MediaTypeHeaderValue("application/json"));
    }
}

4
¿Dónde se corta y pega la primera parte del código también? No veo un objeto "config" en mi Global.asax. ¿De dónde viene esa variable? el artículo tampoco explica.
BuddyJoe

3
Verifique el método {...} public static void Register (HttpConfiguration config) en el archivo WebApiConfig.cs que ha sido generado por VS2012 en la creación del proyecto
Dmitry Pavlov

¿Forzará esto JSON en el sentido de que un AcceptXML cliente obtendrá JSON y no un 406 ?
Luke Puplett

1
Puedo responder mi propio comentario / pregunta: devuelve XML cualquiera que sea el Acceptencabezado.
Luke Puplett

2
Esto rompe mi integración de capa y espada y parece que está relacionado con este problema en github ( github.com/domaindrivendev/Swashbuckle/issues/219 ). Me gustaría usar este método, pero el que se muestra a continuación GlobalConfiguration...Clear()realmente funciona.
seangwright

167

Borre todos los formateadores y vuelva a agregar el formateador Json.

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

EDITAR

Lo agregué al Global.asaxinterior Application_Start().


y en que archivo .. ?? global.ascx .. ??
shashwat

En su método Application_Start ()
Jafin

6
Filip W acaba de mejorar ahora :), véalo
Tien Do

7
@TienDo: ¿vincular al propio blog de Filip?
Phill

10

Philip W tenía la respuesta correcta, pero para mayor claridad y una solución de trabajo completa, edite su archivo Global.asax.cs para que se vea así: (Tenga en cuenta que tuve que agregar la referencia System.Net.Http.Formatting al archivo generado en stock)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace BoomInteractive.TrainerCentral.Server {
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication {
        protected void Application_Start() {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //Force JSON responses on all requests
            GlobalConfiguration.Configuration.Formatters.Clear();
            GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
        }
    }
}

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

Esto borra el formateador XML y, por lo tanto, el formato JSON es el predeterminado.


Perfeccione todo lo que se necesita
tfa

4

Inspirado por la excelente respuesta de Dmitry Pavlov, la modifiqué ligeramente para poder conectar cualquier formateador que quisiera aplicar.

Crédito a Dmitry.

/// <summary>
/// A ContentNegotiator implementation that does not negotiate. Inspired by the film Taken.
/// </summary>
internal sealed class LiamNeesonContentNegotiator : IContentNegotiator
{
    private readonly MediaTypeFormatter _formatter;
    private readonly string _mimeTypeId;

    public LiamNeesonContentNegotiator(MediaTypeFormatter formatter, string mimeTypeId)
    {
        if (formatter == null)
            throw new ArgumentNullException("formatter");

        if (String.IsNullOrWhiteSpace(mimeTypeId))
            throw new ArgumentException("Mime type identifier string is null or whitespace.");

        _formatter = formatter;
        _mimeTypeId = mimeTypeId.Trim();
    }

    public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
    {
        return new ContentNegotiationResult(_formatter, new MediaTypeHeaderValue(_mimeTypeId));
    }
}

2

Si desea hacer eso solo para un método, declare su método como regresando en HttpResponseMessagelugar de IEnumerable<Whatever>y haga:

    public HttpResponseMessage GetAllWhatever()
    {
        return Request.CreateResponse(HttpStatusCode.OK, new List<Whatever>(), Configuration.Formatters.JsonFormatter);
    }

este código es doloroso para las pruebas unitarias, pero también es posible así:

    sut = new WhateverController() { Configuration = new HttpConfiguration() };
    sut.Configuration.Formatters.Add(new Mock<JsonMediaTypeFormatter>().Object);
    sut.Request = new HttpRequestMessage();

Si desea algo para un método, solo cree un msdn.microsoft.com/en-us/library/…
Elisabeth


0

Puede usar en WebApiConfig.cs:

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

0

para aquellos que usan OWIN

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

se convierte en (en Startup.cs):

   public void Configuration(IAppBuilder app)
        {
            OwinConfiguration = new HttpConfiguration();
            ConfigureOAuth(app);

            OwinConfiguration.Formatters.Clear();
            OwinConfiguration.Formatters.Add(new DynamicJsonMediaTypeFormatter());

            [...]
        }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.