L'API Web ASP.NET négocie le contenu par défaut - renverra XML ou JSON ou un autre type basé sur l'en-tête Accept
. Je n’ai pas besoin/je ne veux pas cela, y at-il un moyen (comme un attribut ou quelque chose) de dire à Web API de toujours renvoyer JSON?
Prise en charge de JSON uniquement dans l'API Web ASP.NET - THE RIGHT WAY
Remplacez IContentNegotiator par JsonContentNegotiator:
var jsonFormatter = new JsonMediaTypeFormatter();
//optional: set serializer settings here
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
Implémentation 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"));
}
}
Effacer tous les formateurs et ajouter Json formateur en arrière.
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
MODIFIER
Je l'ai ajouté à Global.asax
dans Application_Start()
.
Philip W avait la bonne réponse, mais pour plus de clarté et une solution complète, modifiez votre fichier Global.asax.cs pour qu'il ressemble à ceci: (Remarque: je devais ajouter la référence System.Net.Http.Formatting au fichier stock généré)
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();
Cela efface le formateur XML et par conséquent le format JSON par défaut.
Inspiré par l'excellente réponse de Dmitry Pavlov, je l'ai légèrement modifiée pour pouvoir brancher tout formateur que je voulais appliquer.
Crédit à 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));
}
}
Si vous voulez faire cela pour une seule méthode, déclarez alors votre méthode comme retournant HttpResponseMessage
au lieu de IEnumerable<Whatever>
et faites:
public HttpResponseMessage GetAllWhatever()
{
return Request.CreateResponse(HttpStatusCode.OK, new List<Whatever>(), Configuration.Formatters.JsonFormatter);
}
ce code est pénible pour les tests unitaires, mais c'est également possible comme ceci:
sut = new WhateverController() { Configuration = new HttpConfiguration() };
sut.Configuration.Formatters.Add(new Mock<JsonMediaTypeFormatter>().Object);
sut.Request = new HttpRequestMessage();
Cela a les en-têtes corrects définis. Semble un peu plus élégant.
public JsonResult<string> TestMethod()
{
return Json("your string or object");
}
pour ceux qui utilisent OWIN
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
devient (dans Startup.cs):
public void Configuration(IAppBuilder app)
{
OwinConfiguration = new HttpConfiguration();
ConfigureOAuth(app);
OwinConfiguration.Formatters.Clear();
OwinConfiguration.Formatters.Add(new DynamicJsonMediaTypeFormatter());
[...]
}
Vous pouvez utiliser dans WebApiConfig.cs:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));