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

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?

Soporta solo 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 formatters) { return new ContentNegotiationResult( _jsonFormatter, new MediaTypeHeaderValue("application/json")); } } 

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

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

EDITAR

Lo agregué a Global.asax dentro de Application_Start() .

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í: (Observe que tuve que agregar la referencia System.Net.Http.Formatting al archivo generado)

 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()); } } } 
 GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); 

Esto borra el formateador XML y, por lo tanto, cambia al formato JSON.

Si desea hacer eso solo para un método, entonces declare que su método devuelve HttpResponseMessage lugar de IEnumerable y lo hace:

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

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

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

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

Gracias a Dmitry.

 ///  /// A ContentNegotiator implementation that does not negotiate. Inspired by the film Taken. ///  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 formatters) { return new ContentNegotiationResult(_formatter, new MediaTypeHeaderValue(_mimeTypeId)); } } 

Yo puedo usar en WebApiConfig.cs:

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

Esto tiene los encabezados correctos establecidos. Parece un poco más elegante.

 public JsonResult TestMethod() { return Json("your string or object"); }