2012-09-27 42 views
91

ASP.NET Web API realiza la negociación de contenido de forma predeterminada; devolverá XML o JSON u otro tipo basado en el encabezado Accept. No necesito/quiero esto, ¿hay alguna manera (como un atributo o algo) de decirle a la API web que siempre devuelva JSON?¿Cómo forzar a ASP.NET Web API a devolver siempre JSON?

+0

Usted puede ser capaz de hacer esto la eliminación de todos los formateadores excepto JSON de 'GlobalConfiguration.Configuration.Formatters' –

Respuesta

66

Supporting only JSON in ASP.NET Web API – THE RIGHT WAY

Reemplazar IContentNegotiator con JsonContentNegotiator:

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

JsonContentNegotiator aplicación:

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")); 
    } 
} 
+3

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

+2

Comprobar el método static public void Register (HttpConfiguration config) {...} en el archivo WebApiConfig.cs que ha sido creado por VS2012 en la creación del proyecto –

+0

Esto forzará a JSON en el sentido de que un cliente 'Accept'ing XML obtendrá JSON, y ** no recibirá un 406 **? –

145

Borrar todos los formateadores y volver a agregar el formateador Json.

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

EDITAR

he añadido a Global.asax dentro Application_Start().

+0

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

+0

En su método Application_Start() – Jafin

+6

Filip W ahora ha mejorado mucho :), consulte aquí http://www.strathweb.com/2013/06/supporting-only-json-in-asp-net-web-api -the-right-way/ –

2

Si quieres hacer eso por un solo método, entonces declarar su método como devolver HttpResponseMessage vez de IEnumerable<Whatever> y do:

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

este código es el dolor para las pruebas unitarias, sino que también es posible de esta manera:

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

Si quiere algo para un método, solo cree un http://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute(v=vs.118).aspx – Elisabeth

1

Inspirado por una excelente respuesta de Dmitry Pavlov, alteré un poco para que pudiera plug-in lo formateador quería cumplir .

Gracias 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)); 
    } 
} 
10

Philip W tenía la respuesta correcta, pero para mayor claridad y una solución de trabajo completa, editar el archivo Global.asax.cs a tener este aspecto: (Tenga en cuenta que tenía que agregar la referencia System.Net.Http.Formatting en el fichero generado 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()); 
     } 
    } 
} 
6
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); 

Esto borra el formateador XML y el impago de este modo a formato JSON.

+0

Perfeccione todo lo que necesite – tfa

0

Yo puede utilizar en WebApiConfig.cs:

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

Esto tiene cabeceras correctas establecidas. Parece un poco más elegante.

public JsonResult<string> TestMethod() 
{ 
return Json("your string or object"); 
} 
Cuestiones relacionadas