Comment puis-je obtenir l'API Web ASP.NET pour renvoyer JSON au lieu de XML à l'aide de Chrome?

1220

En utilisant la nouvelle API Web ASP.NET , dans Chrome, je vois XML - comment puis-je le changer pour demander JSON afin que je puisse le voir dans le navigateur? Je crois que cela ne fait partie que des en-têtes de demande, ai-je raison?

naspinski
la source
8
Il y a une discussion ici pour rendre le retour JSON uniquement le comportement par défaut: github.com/aspnet/Mvc/issues/1765
Natan

Réponses:

1738

Je viens d'ajouter les éléments suivants en App_Start / WebApiConfig.csclasse dans 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 l'obtenir XMLlorsque vous envoyez text/xml.

Si vous avez besoin de la réponse Content-Type, application/jsonveuillez vérifier la réponse de Todd ci-dessous .

NameSpaceutilise System.Net.Http.Headers.

Felipe Leusin
la source
115
Il s'agit d'une réponse étonnamment négligée, et bien que la question d'origine n'était pas totalement claire, cela fait directement de JSON la réponse par défaut pour un navigateur Web (qui envoie Accept: text / html). Bon travail.
gregmac
16
+1 De loin la meilleure réponse. J'imagine qu'il y a une tonne de personnes qui choisissent de supprimer complètement XML simplement parce qu'ils ne voient pas JSON dans le navigateur.
Derek Hunziker
3
J'ai découvert qu'en faisant cela, les données fournies par un tiers contenant des balises HTML break se sont retrouvées avec des retours chariot. Le JSON n'était alors pas valide. Mieux vaut utiliser la réponse acceptée si cela vous affecte.
Stonetip
23
Notez que l'en- Content-Typetête de la réponse sera toujours text/html.
Mrchief
78
C'est horrible. L'en-tête du type de contenu de réponse doit être application / json. Cette "solution" en fait du texte / html.
meffect
501

Si vous faites cela dans le, WebApiConfigvous obtiendrez JSON par défaut, mais cela vous permettra toujours de renvoyer XML si vous passez text/xmlcomme en- Accepttête de demande

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'aviez donc pas cette classe pour commencer, consultez cette réponse pour plus de détails sur la façon de l'incorporer.

Glenn Slaven
la source
51
Juste pour noter, le comportement d'origine est correct. Demandes Chrome application/xmlavec une priorité de 0,9 et */*avec une priorité de 0,8. En supprimant, application/xmlvous supprimez la possibilité pour l'API Web de renvoyer XML si le client le demande spécifiquement. Par exemple, si vous envoyez "Accepter: application / xml", vous recevrez toujours JSON.
porges
11
Est-ce moi ou la première phrase est-elle incorrecte? Le code semble supprimer totalement XML, pas simplement changer la valeur par défaut.
NickG
6
@NickG: une solution qui est négligée ici et à mon humble avis est une bien meilleure option (en gardant application / xml) est la solution proposée par Felipe Leusin plus bas sur cette page. Utilisation de config.Formatters.XmlFormatter.SupportedMediaTypes.Add (new MediaTypeHeaderValue ("text / html"));
Cohen
1
Alors, comment le faisons-nous via la configuration Web pour obtenir json par défaut et XML si demandé?
Kyle
4
La réponse de @Felipse Leusin ci-dessous est en fait plus courte et fonctionne mieux.
Ken Smith
314

L'utilisation de RequestHeaderMapping fonctionne encore mieux, car elle définit également l' Content-Type = application/jsonen-tête de réponse, ce qui permet à Firefox (avec le module complémentaire JSONView) 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"));
dmit77
la source
6
Il s'agit de la solution la plus simple et la plus simple et Fiddler détecte également le type de contenu renvoyé en tant que josn.
Steve Johnson
4
Agréable! Où suggéreriez-vous de mettre cela dans le code?
Tim Abell
9
Il devrait aller dans WebApiConfig.cs
Animesh
9
A travaillé pour moi. J'avais besoin d'ajouter un utilisant System.Net.Http.Formatting;
bbsimonbb
1
Lien pour ma propre convenance: Cette réponse joue bien avec une autre étape de configuration que j'effectue habituellement: stackoverflow.com/a/28337589/398630 .
BrainSlugs83
309

J'aime l'approche de Felipe Leusin - assurez-vous que les navigateurs obtiennent JSON sans compromettre la négociation de contenu des clients qui souhaitent réellement XML. Le seul élément manquant pour moi était que les en-têtes de réponse contenaient toujours le type de contenu: texte / html. Pourquoi était-ce un problème? Parce que j'utilise l' extension JSON Formatter 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 simple 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 ceci:

config.Formatters.Add(new BrowserJsonFormatter());
Todd Menier
la source
24
Dans le constructeur, ajoutez this.SerializerSettings.Formatting = Formatting.Indented;si vous le souhaitez joli-imprimé sans extension de navigateur.
Alastair Maw
10
pourquoi voudriez-vous qu'il soit assez imprimé sur le fil?
meffect
8
Est -ce pas @ dmit77 de réponse mieux (plus concis) que celui - ci?
H.Wolper du
8
@eddiegroves vous ne voulez pas de jolie impression sur le fil. Vous voulez que le serveur envoie le moins de bits sur le fil (c'est-à-dire: pas d'espaces). Ensuite, vous voulez que le navigateur le formate bien, avec des addons et autres. Javascript doit analyser le JSON habituellement, pourquoi le
ralentir
13
Pour les googleurs qui recherchent: n'oubliez pas d'ajouter using System.Net.Http.Formattingetusing Newtonsoft.Json
Berriel
186

Astuce MVC4 # 3 - Suppression du formateur XML de l'API Web ASP.Net

En Global.asaxajouter 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();
}
Yakir Manor
la source
9
Fonctionne - beaucoup mieux d'avoir JSON comme valeur par défaut au lieu de XML.
whitneyland
5
mais pouvez-vous toujours renvoyer xml alors?
Thomas Stock
99
Je l'ai testé et tu ne peux pas. Donc, cela supprime le support XML .. Soyez prévenu, chers utilisateurs de Google
Thomas Stock
3
Si vous jetez un œil à ma réponse ci-dessous, cela permettra au xml d'être renvoyé si vous le souhaitez, mais permet au site de répondre avec JSON au navigateur
Glenn Slaven
3
@GlennSlaven oui, votre réponse devrait être celle indiquée comme correcte.
radu florescu
114

Dans WebApiConfig.cs , ajoutez à la fin de la fonction Register :

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

Source .

Michael Vashchinsky
la source
XmlFormatter est-il nouveau dans MVC4?
Glenn Slaven
1
Dans MVC5, cela peut être fait en remplaçant config par GlobalConfiguration.Configuration
Steven
4
Pour un projet qui ne doit prendre en charge que JSON et ne peut en aucun cas être autorisé à émettre du XML, c'est de loin la meilleure option.
Luc C
1
config.Formatters.Add (config.Formatters.JsonFormatter);
Cas Bloem
3
C'est terrible. - Cela retournera toujours JSON, peu importe quoi, même si le client demande spécifiquement XML dans l'en-tête Content-Type.
BrainSlugs83
94

dans le Global.asax, j'utilise le code ci-dessous. Mon URI pour obtenir JSON esthttp://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"));
}
Diganta Kumar
la source
2
Elle est bonne. Quelle est votre méthode attendez-vous un paramètre? comme localhost: 61044 / api / values ​​/ getdate? json = true, date = 2012-08-01
LT.Nolo
quel type de format de retour d'API Web de données par défaut. est-ce json ou webapi? merci
Thomas
54

Jetez un œil à la négociation de contenu dans WebAPI. Ces articles ( partie 1 et partie 2 ) merveilleusement détaillés et approfondis expliquent comment cela fonctionne.

En bref, vous avez raison et il suffit de définir les en Accept- Content-Typetêtes ou de demander. Étant donné que votre action n'est pas codée pour renvoyer un format spécifique, vous pouvez définir Accept: application/json.

Aaron Daniels
la source
6
"pour que je puisse le voir dans le navigateur"
Spongman
1
@Spongman, oui vous le pouvez. Mais utilisez une extension comme REST Client - la plupart des navigateurs en ont une comme elle. La saisie directe de l'URL dans un navigateur est 1. Trop limitative (pas de contrôle sur les en-têtes, ne peut pas publier de données, etc.); 2. Incorrect - Le navigateur ne consomme pas l'API Web car elle est destinée à être consommée - vous ne pouvez pas vous fier à le tester correctement. Donc, encore une fois, un bon module complémentaire client REST pourrait résoudre ce problème.
Ivaylo Slavov
45

Comme la question est spécifique à Chrome, vous pouvez obtenir l' extension Postman qui vous permet de définir le type de contenu de la demande.

Facteur

Chris S
la source
Dans Firefox, accédez simplement à about: config, recherchez accept.default et changez le contenu de la network.http.accept.defaultconfiguration en text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7.
Bjartur Thorlacius
Ou mieux encore, juste text/html,application/xhtml+xml;q=1.0,*/*;q=0.7pour éviter que des hôtes bogués tels que Bitbucket ne servent accidentellement votre JSON de navigateur au lieu de HTML.
Bjartur Thorlacius
L'URL est morte. Un nouveau est chrome.google.com/webstore/detail/postman/… .
Falcon Momot
35

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.

suhair
la source
2
C'était très utile. Vous pouvez également utiliser UriPathExtensionMapping au lieu de QueryStringMapping si vous souhaitez utiliser path.to/item.json
nuzzolilo
32

Ce code fait de json ma valeur par défaut et me permet également d'utiliser le format XML. Je vais juste 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!

jayson.centeno
la source
1
C'est la réponse la plus flexible (et devrait vraiment être la configuration par défaut de nos jours). Pour ajouter à cette réponse, JSON est la valeur par défaut, y compris à partir du navigateur. Pour afficher XML, ajoutez une chaîne de requête
:? Xml
J'ai essayé un certain nombre de stratégies. Avait un test simple pour XML et JSON et cela a fonctionné hors de la boîte
pat capozzi
23

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 demande, 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.

dmyoko
la source
30
Pourquoi ne pas utiliser le navigateur? C'est un outil évident pour cela.
Anders Lindén
4
Je pense que le point ici est correct et important - nous ne devons pas trop réparer une partie fonctionnelle de l'application (l'infrastructure MVC WebAPI) si le problème est causé par le client. Le vrai cas d'utilisation d'un Api doit être correctement utilisé (en fournissant des en-têtes corrects), ce qui relève de la responsabilité de l'application. Je ne suis pas d'accord pour rejeter complètement le navigateur - pour les tests, il existe de nombreux outils pour presque tous les navigateurs (les extensions de type Rest Client pour commencer).
Ivaylo Slavov du
6
Cela devrait probablement être un commentaire.
bonh
17

La plupart des réponses ci-dessus sont parfaitement logiques. Étant donné que vous voyez des données formatées au format XML, cela signifie que le formateur XML est appliqué, vous pouvez donc voir le format JSON simplement en supprimant 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

pavan kumar
la source
12

J'ai utilisé un filtre d'action global pour supprimer Accept: application/xmllorsque l'en- User-Agenttête 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.

Roger Lipscombe
la source
11

J'ai trouvé l'application Chrome "Advanced REST Client" excellente pour travailler avec les services REST. Vous pouvez définir le Content-Type application/jsonentre autres: Client REST avancé

Mike Rowley
la source
10

Le retour du format correct se fait par le formateur de type média. Comme d'autres l'ont mentionné, vous pouvez le faire en WebApiConfigclasse:

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 en savoir plus, consultez:

Dans le cas où vos actions retournent du XML (ce qui est le cas par défaut) et que vous avez juste besoin 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);
    }
}

S'appliquer à l'action:

[JsonOutput]
public IEnumerable<Person> GetPersons()
{
    return _repository.AllPersons(); // the returned output will be in JSON
}

Notez que vous pouvez omettre le mot Attributesur la décoration d'action et utiliser juste à la [JsonOutput]place de [JsonOutputAttribute].

Empilés
la source
7
        config.Formatters.Remove(config.Formatters.XmlFormatter);
Gaurav Dubey
la source
3
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant la manière et / ou la raison pour laquelle il résout le problème améliorerait la valeur à long terme de la réponse. Veuillez lire ce stackoverflow.com/help/how-to-answer
SR
6

selon la dernière version d'ASP.net WebApi 2,

sous WebApiConfig.cs, cela fonctionnera

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
À
la source
6

Je ne comprends pas pourquoi il y a toute cette complexité dans la réponse. Bien sûr, il existe de nombreuses façons de le faire, avec QueryStrings, des en-têtes et des options ... mais ce que je pense être la meilleure pratique est simple. Vous demandez une URL simple (ex:) http://yourstartup.com/api/carset 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 car cette réponse acceptée ne fonctionne 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

J'ajouterai également 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());
}

J'ai une question d'où viennent les défauts (du moins ceux que je vois). S'agit-il de valeurs par défaut .NET, ou peut-être créées ailleurs (par quelqu'un d'autre sur mon projet). En tout cas, j'espère que cela vous aidera.

pseudo
la source
5

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 était principalement destinée à prendre en charge le format $ pour OData dans les premières versions de WebApi, mais elle s'applique également à l'implémentation non-OData et renvoie l'en- Content-Type: application/json; charset=utf-8tête dans la réponse.

Il vous permet de virer de bord &$format=jsonou &$format=xmljusqu'à la fin de votre uri lors d'un test avec un navigateur. Il n'interfère pas avec les autres comportements attendus lors de l'utilisation d'un client non navigateur où vous pouvez définir vos propres en-têtes.

mdisibio
la source
5

Vous pouvez utiliser comme ci-dessous:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
Akshay Kapoor
la source
Si vous créez une application WebAPI pour simplement transmettre des messages JSON, pensez à cette réponse.
allen1
4

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


          ............................
      }
}
Md. Sabbir Ahamed
la source
3

Vous changez juste App_Start/WebApiConfig.cscomme 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}"
       );
    }
vaheeds
la source
La suppression d'un formateur n'est généralement pas une bonne idée, vous supprimez des fonctionnalités.
naspinski
En fait, dans ce cas, cela fonctionne bien pour moi, et beaucoup d'autres suggèrent une méthode comme celle-ci. Je l'ai appris de myview.rahulnivi.net/building-spa-angular-mvc-5 book!
vaheeds
2

À partir de MSDN Création d'une application à page unique 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é.

lko
la source
2

Un certain temps s'est écoulé depuis que cette question a été posée (et répondue), mais une autre option consiste à remplacer l'en-tête Accept sur le serveur pendant le traitement de la demande à l'aide d'un MessageHandler 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ù nous voulons seulement parfois remplacer la négociation de contenu par défaut. Sinon, selon les autres réponses, vous supprimeriez simplement un formateur inutile de la configuration.

Vous devrez bien sûr l'enregistrer. Vous pouvez soit le faire globalement:

  public static void Register(HttpConfiguration config) {
      config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler());
  }

ou itinéraire par itinéraire:

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 s'exécutera à la fois sur les extrémités de demande et de réponse du pipeline, tout comme un HttpModule. Ainsi, vous pouvez 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;
    }
}
rism
la source
2

Voici le moyen le plus simple que j'ai utilisé dans mes applications. Ajouter ci-dessous 3 lignes de code App_Start\\WebApiConfig.csdans la Registerfonction

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));

L'API Web Asp.net sérialisera automatiquement votre objet de retour en JSON et au fur et à mesure de l' application/jsonajout dans l'en-tête, le navigateur ou le destinataire comprendra que vous retournez le résultat JSON.

Vikas Bansal
la source
1

WebApiConfig est l'endroit où vous pouvez configurer si vous voulez sortir en json ou xml. par défaut, c'est xml. dans la fonction de registre, nous pouvons utiliser les formats HttpConfiguration pour formater la sortie. System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") est requis pour obtenir la sortie au format json. entrez la description de l'image ici

rocky_pps
la source
1

En utilisant la réponse de Felipe Leusin pendant 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, si tout va bien utile à d'autres rencontrant la même exception inattendue, est d'installer System.Net.Http. NuGet le supprime apparemment dans certaines circonstances. Après une installation manuelle, le problème a été résolu.

Charles Burns
la source
-3

Je suis étonné de voir autant de réponses nécessitant un codage pour changer un cas d'utilisation unique (GET) dans une API au lieu d'utiliser un outil approprié qui doit être installé une fois et peut être utilisé pour n'importe quelle API (propre ou tierce partie) et tout cas d'utilisation.

La bonne réponse est donc:

  1. Si vous souhaitez uniquement demander json ou un autre type de contenu, installez Requestly ou un outil similaire et modifiez l'en-tête Accept.
  2. Si vous souhaitez également utiliser POST et que json, xml, etc. sont bien formatés, utilisez une extension de test API appropriée comme Postman ou ARC .
user3285954
la source
Certains préfèrent faire les choses sans ajouter de ballonnement sous la forme d'outils et de bibliothèques supplémentaires.
tno2007
Il est toujours faux d'apporter des modifications à l'API uniquement parce que quelqu'un utilise le mauvais outil pour le travail. Un navigateur Web n'est pas conçu pour tester des API, pas même pour afficher la sortie des API mais pour afficher des documents. C'est encore pire si quelqu'un pense qu'un outil de testeur d'API est gonflé au lieu de faire partie de la boîte à outils obligatoire pour tout développeur d'API, et honnêtement, j'ajouterais également des développeurs frontaux car ils doivent également interagir et expérimenter avec des API. Ce n'est probablement pas suffisant non plus car le navigateur sans compléments ne permet pas de définir des en-têtes, de publier sur une API ou même d'inspecter les en-têtes de réponse.
user3285954
Je comprends ce que vous dites et vous ne vous trompez pas. Mais juste hors sujet, la raison pour laquelle vous obtenez un vote négatif est le ton sur lequel vous répondez à la question. Vous semblez très combatif et vous rencontrez ce développeur qui pense qu'il sait tout, et c'est très désagréable. Je suis certain que vous êtes un excellent développeur, à en juger par vos réponses. Mais, vous devez apprendre, en particulier dans un environnement professionnel d'assurance qualité comme celui-ci, à aborder et à convaincre les gens d'une manière plus conviviale et plus humaine. Peut-être, donnez d'abord la réponse qu'ils veulent, puis expliquez une meilleure façon et motivez pourquoi c'est mieux.
tno2007