En utilisant le plus récent API Web ASP.NET, dans Chrome Je vois du XML - comment puis-je le changer pour demander JSON afin que je puisse le voir dans le navigateur? Je crois que cela fait simplement partie des en-têtes de demande, est-ce que je me trompe?
Je viens d'ajouter ce qui suit dans la classe App_Start / WebApiConfig.cs
de mon projet d'API Web MVC.
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html") );
Cela garantit que vous obtenez JSON sur la plupart des requêtes, mais vous pouvez obtenir xml
lorsque vous envoyez text/xml
.
Si vous avez besoin de la réponse Content-Type
comme application/json
, veuillez vérifier réponse de Todd ci-dessous .
NameSpace
utilise System.Net.Http.Headers
;
Si vous faites cela dans la WebApiConfig
, vous obtiendrez JSON par défaut, mais cela vous permettra quand même de renvoyer du XML si vous passez text/xml
en tant que requête Accept
en-tête.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}
}
Si vous n'utilisez pas le type de projet MVC et que vous ne disposiez donc pas de cette classe pour commencer, voir cette réponse pour plus de détails sur la manière de l'incorporer.
J'aime approche de Felipe Leusin mieux - assurez-vous que les navigateurs utilisent JSON sans compromettre la négociation de contenu des clients qui souhaitent réellement utiliser XML. La seule chose qui me manquait était que les en-têtes de réponse contenaient toujours le type de contenu: text/html. Pourquoi était-ce un problème? Parce que j'utilise le extension JSON Chrome , qui inspecte le type de contenu, et je n'obtiens pas le joli formatage auquel je suis habitué. J'ai corrigé cela avec un formateur personnalisé qui accepte les requêtes text/html et renvoie les réponses application/json:
public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
public BrowserJsonFormatter() {
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
this.SerializerSettings.Formatting = Formatting.Indented;
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) {
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}
Inscrivez-vous comme ça:
config.Formatters.Add(new BrowserJsonFormatter());
L'utilisation de RequestHeaderMapping fonctionne encore mieux, car elle définit également le Content-Type = application/json
dans l'en-tête de la réponse, ce qui permet à Firefox (avec le complément JSONView) de formater la réponse au format JSON.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept",
"text/html",
StringComparison.InvariantCultureIgnoreCase,
true,
"application/json"));
Conseil n ° 3 de MVC4 - Suppression du formateur XML de l’API Web ASP.Net
Dans Global.asax
ajoutez la ligne:
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
ainsi:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.RegisterTemplateBundles();
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}
Dans le WebApiConfig.cs , ajoutez à la fin de la fonction Register :
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
Source .
Dans le Global.asax j'utilise le code ci-dessous. Mon URI pour obtenir JSON est http://www.digantakumar.com/api/values?json=true
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("json", "true", "application/json"));
}
Examinez la négociation de contenu dans WebAPI. Ces ( Partie 1 & Partie 2 ) des articles de blog merveilleusement détaillés et détaillés expliquent comment cela fonctionne.
En bref, vous avez raison et il vous suffit de définir les en-têtes de demande Accept
ou Content-Type
. Étant donné que votre action n'est pas codée pour renvoyer un format spécifique, vous pouvez définir Accept: application/json
.
Comme la question est spécifique à Chrome, vous pouvez obtenir le extension Postman qui vous permet de définir le type de contenu de la demande.
Une option rapide consiste à utiliser la spécialisation MediaTypeMapping. Voici un exemple d'utilisation de QueryStringMapping dans l'événement Application_Start:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));
Maintenant, chaque fois que l'URL contient la chaîne de requête? A = b dans ce cas, la réponse Json sera affichée dans le navigateur.
Ce code fait de json ma valeur par défaut et me permet d’utiliser également le format XML. Je vais simplement annexer le xml=true
.
GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
Merci tout le monde!
N'utilisez pas votre navigateur pour tester votre API.
Au lieu de cela, essayez d'utiliser un client HTTP qui vous permet de spécifier votre requête, telle que CURL ou même Fiddler.
Le problème avec ce problème est dans le client, pas dans l'API. L'API Web se comporte correctement, à la demande du navigateur.
La plupart des réponses ci-dessus sont parfaitement logiques. Puisque vous voyez les données formatées au format XML, cela signifie que le formateur XML est appliqué. Vous pouvez donc visualiser le format JSON en supprimant simplement XMLFormatter du paramètre HttpConfiguration, comme suit:
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();
}
jSON étant le format par défaut
J'ai utilisé un filtre d'action global pour supprimer Accept: application/xml
lorsque l'en-tête User-Agent
contient "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();
}
}
Semble travailler.
J'ai trouvé le Chrome app "Avancé REST Client" parfaitement adapté aux services REST. Vous pouvez définir le type de contenu sur application/json
, entre autres: client avancé REST client
Le formatage correct est renvoyé par le formateur de type de support. Comme d'autres l'ont mentionné, vous pouvez le faire dans la classe WebApiConfig
:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
...
// Configure Web API to return JSON
config.Formatters.JsonFormatter
.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
...
}
}
Pour plus, vérifiez:
Si vos actions renvoient du code XML (ce qui est le cas par défaut) et que vous n’avez besoin que d’une méthode spécifique pour renvoyer JSON, vous pouvez alors utiliser un ActionFilterAttribute
et l’appliquer à cette action spécifique.
Attribut de filtre:
public class JsonOutputAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
ObjectContent content = actionExecutedContext.Response.Content as ObjectContent;
var value = content.Value;
Type targetType = actionExecutedContext.Response.Content.GetType().GetGenericArguments()[0];
var httpResponseMsg = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
RequestMessage = actionExecutedContext.Request,
Content = new ObjectContent(targetType, value, new JsonMediaTypeFormatter(), (string)null)
};
actionExecutedContext.Response = httpResponseMsg;
base.OnActionExecuted(actionExecutedContext);
}
}
Application à l'action:
[JsonOutput]
public IEnumerable<Person> GetPersons()
{
return _repository.AllPersons(); // the returned output will be in JSON
}
Notez que vous pouvez omettre le mot Attribute
dans la décoration d'action et utiliser simplement [JsonOutput]
au lieu de [JsonOutputAttribute]
.
Je ne comprends pas pourquoi la réponse est complexe. Bien sûr, il existe de nombreuses façons de le faire, avec QueryStrings, en-têtes et options ... mais ce que je crois être la meilleure pratique est simple. Vous demandez une URL simple (ex: http://yourstartup.com/api/cars
) et vous obtenez en retour JSON. Vous obtenez JSON avec l'en-tête de réponse approprié:
Content-Type: application/json
En cherchant une réponse à cette même question, j'ai trouvé ce fil et je devais continuer parce que cette réponse acceptée ne fonctionnait pas exactement. J'ai trouvé une réponse que je trouve trop simple pour ne pas être la meilleure:
Définir le formateur WebAPI par défaut
Je vais ajouter mon conseil ici aussi.
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());
}
J'ai une question de savoir d'où viennent les défauts (du moins ceux que je vois). Sont-ils .NET par défaut, ou peut-être créés ailleurs (par quelqu'un d'autre sur mon projet). Anways, espérons que cela aide.
selon la dernière version de ASP.net WebApi 2,
sous WebApiConfig.cs
, cela fonctionnera
config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
Voici une solution similaire à jayson.centeno et à d'autres réponses, mais en utilisant l'extension intégrée 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 solution visait principalement à prendre en charge le format $ pour OData dans les premières versions de WebApi, mais elle s'appliquait également à la mise en œuvre non-OData et renvoyait l'en-tête Content-Type: application/json; charset=utf-8
dans la réponse.
Il vous permet de fixer &$format=json
ou &$format=xml
à la fin de votre uri lors du test avec un navigateur. Cela n'interfère pas avec les autres comportements attendus lors de l'utilisation d'un client non navigateur, dans lequel vous pouvez définir vos propres en-têtes.
config.Formatters.Remove(config.Formatters.XmlFormatter);
Vous pouvez utiliser comme ci-dessous:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
Ajoutez simplement ces deux lignes de code sur votre classe WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//add this two line
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
............................
}
}
Vous venez de changer le App_Start/WebApiConfig.cs
comme ceci:
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}"
);
}
De MSDNCréation d'une application à une seule page avec ASP.NET et AngularJS (environ 41 minutes).
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// ... possible routing etc.
// Setup to return json and camelcase it!
var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
formatter.SerializerSettings.ContractResolver =
new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
}
Il devrait être à jour, je l'ai essayé et cela a fonctionné.
Un certain temps s'est écoulé depuis que cette question a été posée (et sa réponse), mais une autre option consiste à remplacer l'en-tête Accept sur le serveur lors du traitement de la demande à l'aide d'un MessageHandler, comme indiqué ci-dessous:
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);
}
}
Où someOtherCondition
peut être n'importe quoi, y compris le type de navigateur, etc. Cela s'applique aux cas conditionnels où nous ne voulons parfois que remplacer la négociation de contenu par défaut. Sinon, comme indiqué dans les autres réponses, vous supprimeriez simplement un formateur inutile de la configuration.
Vous aurez besoin de l'enregistrer bien sûr. Vous pouvez le faire globalement:
public static void Register(HttpConfiguration config) {
config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler());
}
ou sur une route à la fois:
config.Routes.MapHttpRoute(
name: "SpecialContentRoute",
routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}",
defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional },
constraints: null,
handler: new ForceableContentTypeDelegationHandler()
);
Et puisqu'il s'agit d'un gestionnaire de messages, il s'exécutera à la fois sur la requête et sur la réponse du pipeline, un peu comme un HttpModule
. Vous pouvez donc facilement reconnaître le remplacement avec un en-tête personnalisé:
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;
}
}
Voici le moyen le plus simple que j'ai utilisé dans mes applications. Ajouter donné ci-dessous 3 lignes de code dans la fonction App_Start\\WebApiConfig.cs
dans la fonction Register
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
L'API Web Asp.net sérialise automatiquement votre objet renvoyé en JSON et, lorsque le application/json
est ajouté dans l'en-tête, le navigateur ou le destinataire comprendra que vous renvoyez le résultat JSON.
Après avoir utilisé la réponse de Felipe Leusin pendant des années, après une récente mise à jour des bibliothèques principales et de Json.Net, j’ai rencontré un System.MissingMethodException
: SupportedMediaTypes. La solution dans mon cas, si cela est utile aux autres personnes rencontrant la même exception inattendue, consiste à installer System.Net.Http
. NuGet le supprime apparemment dans certaines circonstances. Après une installation manuelle, le problème a été résolu.
WebApiConfig est l'endroit où vous pouvez configurer si vous voulez générer en json ou xml. par défaut c'est xml. dans la fonction register, nous pouvons utiliser les formats HttpConfiguration Formatters pour formater la sortie. System.Net.Http.Headers => MediaTypeHeaderValue ("text/html") est requis pour obtenir la sortie au format json.