Comment puis-je obtenir ASP.NET API Web pour retourner JSON au lieu de XML en utilisant Chrome?
utilisant le nouveau ASP.NET Web API , dans Chrome je vois XML - Comment puis-je le changer pour demander JSON pour que je puisse le voir dans le navigateur? Je crois que ce n'est qu'une partie des en-têtes de la demande, n'est-ce pas?
29 réponses
je viens d'ajouter ce qui suit dans la classe App_Start / WebApiConfig.cs
dans mon projet D'API Web MVC.
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html") );
qui fait que vous obtenez json sur la plupart des requêtes, mais vous pouvez obtenir xml
quand vous envoyez text/xml
.
si vous avez besoin de la réponse Content-Type
comme application/json
s'il vous plaît cocher la réponse de Todd ci-dessous .
NameSpace
est l'utilisation de System.Net.Http.Headers
;
si vous faites cela dans le WebApiConfig
vous obtiendrez JSON par défaut, mais il vous permettra toujours de retourner XML si vous passez text/xml
comme la 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 n'avez donc pas cette classe pour commencer, voir cette réponse pour les détails sur la façon de l'incorporer.
j'aime Felipe Leusin de l'approche best - assurez-vous que les navigateurs obtenir JSON sans compromettre la négociation de contenu à partir de clients qui veulent réellement XML. La seule pièce manquante pour moi était que les en-têtes de réponse contenaient toujours content-type: text/html. Pourquoi est-ce un problème? Parce que j'utilise l'extension JSON Formatter Chrome , qui inspecte le type de contenu, et je n'ai pas le joli formatage auquel je suis habitué. J'ai arrangé ça avec un simple formatteur personnalisé qui accepte les requêtes texte/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");
}
}
Registre de la sorte:
config.Formatters.Add(new BrowserJsonFormatter());
en utilisant RequestHeaderMapping fonctionne encore mieux, car il définit également le Content-Type = application/json
dans l'en-tête de réponse, ce qui permet à Firefox (avec jsonview add-on) de formater la réponse en JSON.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept",
"text/html",
StringComparison.InvariantCultureIgnoreCase,
true,
"application/json"));
MVC4 Quick Tip #3-Suppression du formatage XML ASP.Net API Web
dans Global.asax
ajouter la ligne:
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
comme suit:
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 , ajouter à la fin de la Registre fonction:
// 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"));
}
regardez la négociation de contenu dans le WebAPI. Ceux-ci ( Partie 1 & Partie 2 ) merveilleusement détaillé et complet billets de blog expliquer comment cela fonctionne.
en bref, vous avez raison, et vous avez juste besoin de définir les en-têtes de requête Accept
ou Content-Type
. Étant donné que votre Action n'est pas codée pour retourner un format spécifique, vous pouvez définir Accept: application/json
.
comme la question est spécifique au Chrome, vous pouvez obtenir le Postman extension qui vous permet de définir le type de contenu de la requête.
une option rapide est D'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 quand l'url contient le querystring ?a=b dans ce cas, la réponse de Json s'affichera dans le navigateur.
ce code rend json par défaut et me permet d'utiliser le format XML. Je vais juste ajouter 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 à tous!
N'utilisez pas votre navigateur pour tester votre API.
à la place, essayez D'utiliser un client HTTP qui vous permet de spécifier votre requête, comme 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, selon la demande du navigateur.
la plupart des réponses ci-dessus sont parfaitement sensées. Puisque vous voyez des données étant formatées dans le format XML ,cela signifie que le formatteur XML est appliqué,de sorte que vous pouvez voir le format JSON simplement en enlevant le XMLFormatter du paramètre HttpConfiguration comme
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();
}
puisque JSON est 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 fonctionner.
j'ai trouvé L'application Chrome" Advanced REST Client " excellent pour travailler avec les services de repos. Vous pouvez définir le type de contenu à application/json
entre autres choses:
client de repos avancé
retourner le bon format est fait par le formatteur de type média.
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, voir:
dans le cas où vos actions sont de retour XML (qui est le cas par défaut) et vous avez besoin juste d'une méthode spécifique pour retourner 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
sur la décoration d'action et n'utiliser que [JsonOutput]
au lieu de [JsonOutputAttribute]
.
Je ne comprends pas pourquoi il y a toute cette complexité dans la réponse. Bien sûr, il y a beaucoup de façons de faire cela, avec des QueryStrings, des en-têtes et des options... mais ce que je crois être la meilleure pratique est simple. Vous demandez une URL simple (ex: http://yourstartup.com/api/cars
) et en retour vous obtenez 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 j'ai dû continuer parce que ceci réponse acceptée ne fonctionne pas exactement. J'ai trouvé une réponse qui me semble trop simple de ne pas être la meilleure:
Définir la valeur par défaut WebAPI formateur
je vais ajouter mon conseil ici.
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());
}
je me demande d'où viennent les valeurs par défaut (au moins celles que je vois). Sont - ils .net par défaut, ou peut-être créé ailleurs (par quelqu'un d'autre sur mon projet). Anways, espère ceci aider.
Voici une solution similaire à jayson. de 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 était principalement axée sur le support du format $ pour OData dans les premières versions de WebApi, mais elle s'applique également à la mise en œuvre Non-OData, et renvoie le
Content-Type: application/json; charset=utf-8
en-tête dans la réponse.
il vous permet de tack &$format=json
ou &$format=xml
à la fin de votre uri lors d'un test avec un navigateur. Il n'interfère pas avec d'autres comportement attendu lors de l'utilisation d'un navigateur client où vous pouvez définir vos propres en-têtes.
il suffit 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}"
);
}
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);
il suffit d'ajouter ces deux lignes de code sur votre WebApiConfig class
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//add this two line
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
............................
}
}
config.Formatters.Remove(config.Formatters.XmlFormatter);
From MSDN Building a Single Page Application with 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 doit ê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 répondue) mais une autre option consiste à outrepasser L'en-tête Accept sur le serveur pendant le traitement de la requête en utilisant un gestionnaire de messagerie comme 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. Ce serait pour les cas conditionnels où seulement parfois nous voulons outrepasser la négociation de contenu par défaut. Sinon, comme dans les autres réponses, vous retireriez simplement une formater à partir de la configuration.
vous aurez besoin de l'enregistrer bien sûr. Vous pouvez soit le faire à l'échelle mondiale:
public static void Register(HttpConfiguration config) {
config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler());
}
ou sur la base d'une route par route:
config.Routes.MapHttpRoute(
name: "SpecialContentRoute",
routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}",
defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional },
constraints: null,
handler: new ForceableContentTypeDelegationHandler()
);
et comme il s'agit d'un gestionnaire de messages, il fonctionnera à la fois aux extrémités de la demande et de la réponse du pipeline, un peu comme un HttpModule
. Ainsi, vous pouvez facilement reconnaître le outrepasser 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 facile que j'ai utilisé dans mes applications. Ajouter donnée ci-dessous 3 lignes de code dans App_Start\WebApiConfig.cs
dans Register
fonction
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
Asp.net L'API web sérialisera automatiquement votre objet de retour à JSON et comme le application/json
est ajouté dans l'en-tête de sorte que le navigateur ou le récepteur comprendra que vous retournez le résultat JSON.
WebApiConfig est l'endroit où vous pouvez configurer si vous voulez afficher en json ou en xml. par défaut, c'est le xml. dans la fonction register, nous pouvons utiliser les Formatteurs HttpConfiguration pour formater la sortie . Système.Net.Http.Headers = > MediaTypeHeaderValue ("text/html") est nécessaire pour obtenir la sortie au format json.
vous pouvez utiliser comme suit:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
en utilisant Felipe Leusin 'S réponse pour des années, après une récente mise à jour des bibliothèques de base et de Json.Net, je suis tombé sur un System.MissingMethodException
: SupportedMediaTypes.
La solution dans mon cas, avec un peu de chance utile pour d'autres personnes éprouvant la même exception inattendue, est d'installer System.Net.Http
. NuGet l'enlève apparemment dans certaines circonstances. Après une installation manuelle, le problème a été résolu.
je suis étonné de voir autant de réponses nécessitant un codage pour changer un cas d'utilisation unique (GET) dans one API au lieu d'utiliser un outil approprié ce qui doit être installé une fois et peut être utilisé pour tout API (propre ou tiers) et tous les cas d'utilisation.
donc la bonne réponse est: