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?

1221
demandé sur DanielV 2012-03-24 03:04:12
la source

29 ответов

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 ;

1553
répondu Felipe Leusin 2017-07-03 22:42:06
la source

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.

477
répondu Glenn Slaven 2017-05-23 15:34:53
la source

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());
283
répondu Todd Menier 2017-05-23 15:10:47
la source

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"));
242
répondu dmit77 2018-06-19 15:50:28
la source

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();
}
174
répondu Yakir Manor 2013-08-06 17:00:36
la source

Dans le WebApiConfig.cs , ajouter à la fin de la Registre fonction:

// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);

Source .

103
répondu Michael Vashchinsky 2016-12-08 23:18:56
la 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"));
}
88
répondu Diganta Kumar 2016-12-08 23:51:49
la source

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 .

48
répondu Aaron Daniels 2012-11-09 23:20:13
la source

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.

Postman

39
répondu Chris S 2013-09-27 14:40:29
la source

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.

31
répondu suhair 2012-03-27 09:08:37
la source

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!

28
répondu jayson.centeno 2016-07-11 18:17:26
la source

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.

18
répondu dmyoko 2014-04-26 01:26:14
la source

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

10
répondu pavan kumar 2017-04-13 09:26:19
la source

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.

8
répondu Roger Lipscombe 2013-06-23 18:47:02
la source

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é

6
répondu Mike Rowley 2015-09-30 10:42:04
la source

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] .

5
répondu Stacked 2016-12-09 19:27:58
la source

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.

4
répondu Nick 2017-05-23 13:31:37
la source

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.

3
répondu mdisibio 2017-05-23 15:18:27
la source

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}"
       );
    }
2
répondu vaheeds 2016-02-08 08:03:12
la source

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);
2
répondu A.T. 2016-10-27 13:26:57
la source

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());


          ............................
      }
}
2
répondu Md. Sabbir Ahamed 2016-11-10 14:11:24
la source
        config.Formatters.Remove(config.Formatters.XmlFormatter);
2
répondu Gaurav Dubey 2017-07-01 07:31:36
la source

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é.

1
répondu lko 2014-09-30 23:19:10
la source

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

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;
    }
}
1
répondu rism 2015-12-06 10:44:25
la source

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.

1
répondu Vikas Bansal 2016-05-28 13:49:51
la source

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. enter image description here

0
répondu Parag 2016-09-25 03:13:10
la source

vous pouvez utiliser comme suit:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
0
répondu Akshay Kapoor 2018-04-11 13:21:38
la source

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.

0
répondu Charles Burns 2018-04-13 22:42:40
la source

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:

  1. si vous souhaitez seulement demander json ou un autre type de contenu installer Requestly ou un similaire de l'outil et de modifier l'en-tête Accept.
  2. si vous voulez utiliser POST trop et ont joliment formaté json, xml, etc. utilisez une extension de test D'API appropriée comme Postman ou ARC .
-3
répondu user3285954 2017-12-01 02:01:52
la source

Autres questions sur asp.net-web-api json google-chrome