Wie kann ich die ASP.NET-Web-API dazu bringen, JSON anstelle von XML mit Chrome zurückzugeben?


1220

Bei Verwendung der neueren ASP.NET-Web-API wird in Chrome XML angezeigt. Wie kann ich es ändern, um JSON anzufordern, damit ich es im Browser anzeigen kann? Ich glaube, es ist nur ein Teil der Anforderungsheader. Stimmt das?


8
Es gibt eine Diskussion hier, um die Rückgabe von JSON nur zum Standardverhalten zu machen: github.com/aspnet/Mvc/issues/1765
Natan

Antworten:


1737

Ich füge App_Start / WebApiConfig.csin meinem MVC- Web-API- Projekt nur Folgendes in der Klasse hinzu .

config.Formatters.JsonFormatter.SupportedMediaTypes
    .Add(new MediaTypeHeaderValue("text/html") );

Das stellt sicher, dass Sie JSON für die meisten Abfragen erhalten, aber Sie können es erhalten, XMLwenn Sie senden text/xml.

Wenn Sie die Antwort haben müssen , Content-Typewie application/jsonüberprüfen Sie bitte Todd Antwort unten .

NameSpaceverwendet System.Net.Http.Headers.


115
Dies ist eine überraschend übersehene Antwort, und obwohl die ursprüngliche Frage nicht ganz klar war, ist JSON damit direkt die Standardantwort für einen Webbrowser (der Accept: text / html sendet). Gut gemacht.
Gregmac

16
+1 Mit Abstand die beste Antwort. Ich stelle mir vor, es gibt eine Menge Leute, die sich dafür entscheiden, XML vollständig zu entfernen, nur weil sie JSON nicht im Browser sehen.
Derek Hunziker

3
Als ich dies tat, stellte ich fest, dass Daten, die von einem Drittanbieter mit HTML-Break-Tags bereitgestellt wurden, zu Wagenrückläufen führten. Der JSON war dann ungültig. Verwenden Sie besser die akzeptierte Antwort, wenn dies Sie betrifft.
Stonetip

23
Beachten Sie, dass der Content-TypeHeader der Antwort weiterhin angezeigt wird text/html.
Mrchief

78
Das ist schrecklich. Der Header des Antwortinhaltstyps sollte application / json sein. Diese "Lösung" macht es Text / HTML.
Meffect

501

Wenn Sie diese in das tun WebApiConfigwerden Sie JSON standardmäßig, aber es wird immer noch ermöglichen es Ihnen , XML zurück , wenn Sie passieren text/xmlals AcceptAnforderungskopf

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

Wenn Sie den MVC-Projekttyp nicht verwenden und diese Klasse daher zunächst nicht hatten, finden Sie in dieser Antwort Einzelheiten zur Einbindung.


51
Nur zu beachten, das ursprüngliche Verhalten ist korrekt. Chrome-Anfragen application/xmlmit einer Priorität von 0,9 und */*einer Priorität von 0,8. Durch Entfernen application/xmlentfernen Sie die Möglichkeit für die Web-API, XML zurückzugeben, wenn der Client dies ausdrücklich anfordert. Wenn Sie beispielsweise "Accept: application / xml" senden, erhalten Sie weiterhin JSON.
porges

11
Bin ich es oder ist der erste Satz falsch? Der Code scheint XML vollständig zu entfernen und nicht nur die Standardeinstellung zu ändern.
NickG

6
@NickG: Eine Lösung, die hier übersehen wird und IMHO eine viel bessere Option ist (Anwendung / XML beibehalten), ist die von Felipe Leusin auf dieser Seite vorgeschlagene Lösung. Verwenden von config.Formatters.XmlFormatter.SupportedMediaTypes.Add (neuer MediaTypeHeaderValue ("text / html"));
Cohen

1
Wie machen wir das über die Webkonfiguration, damit wir standardmäßig JSON und XML erhalten, wenn dies angefordert wird?
Kyle

4
@Felipse Leusins ​​Antwort unten ist tatsächlich kürzer und funktioniert besser.
Ken Smith

313

Die Verwendung von RequestHeaderMapping funktioniert noch besser, da auch der Content-Type = application/jsonAntwortheader festgelegt wird, sodass Firefox (mit JSONView-Add-On) die Antwort als JSON formatieren kann.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", 
                              "text/html",
                              StringComparison.InvariantCultureIgnoreCase,
                              true, 
                              "application/json"));

6
Dies ist die schlankste und einfachste Lösung, und Fiddler erkennt auch den Inhaltstyp, der als josn zurückgegeben wird.
Steve Johnson

4
Nett! Wo würden Sie vorschlagen, dies in den Code aufzunehmen?
Tim Abell

9
Es sollte in WebApiConfig.cs
Animesh

9
Hat für mich gearbeitet. Ich musste ein using System.Net.Http.Formatting
Bbsimonbb

1
Verknüpfen für meine eigene Bequemlichkeit: Diese Antwort passt gut zu einem anderen Einrichtungsschritt, den ich normalerweise durchführe: stackoverflow.com/a/28337589/398630 .
BrainSlugs83

308

Ich mag den Ansatz von Felipe Leusin am besten - stellen Sie sicher, dass Browser JSON erhalten, ohne die Inhaltsverhandlung von Clients zu beeinträchtigen, die tatsächlich XML möchten. Das einzige fehlende Teil für mich war, dass die Antwortheader immer noch den Inhaltstyp enthielten: text / html. Warum war das ein Problem? Weil ich die JSON Formatter Chrome-Erweiterung verwende , die den Inhaltstyp überprüft, und nicht die hübsche Formatierung bekomme, die ich gewohnt bin. Ich habe das mit einem einfachen benutzerdefinierten Formatierer behoben, der Text- / HTML-Anforderungen akzeptiert und Anwendungs- / JSON-Antworten zurückgibt:

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

Registrieren Sie sich wie folgt:

config.Formatters.Add(new BrowserJsonFormatter());

24
Fügen this.SerializerSettings.Formatting = Formatting.Indented;Sie im Konstruktor hinzu, wenn Sie möchten, dass es ohne Browsererweiterung hübsch gedruckt wird.
Alastair Maw

10
warum soll es schön über den Draht gedruckt werden?
Meffect

8
Ist die Antwort von @ dmit77 nicht besser (prägnanter) als diese?
H. Wolper

8
@eddiegroves du willst nicht hübsch über den Draht drucken. Sie möchten, dass der Server die geringste Anzahl von Bits über die Leitung sendet (dh keine Leerzeichen). Dann soll der Browser es schön formatieren, mit Addons und so. Javascript muss den JSON normalerweise analysieren, warum sollte er langsamer gemacht werden, indem unnötige Formatierungen eingeführt werden
Meffect

13
Für die Googler, die suchen: Vergessen Sie nicht hinzuzufügen using System.Net.Http.Formattingundusing Newtonsoft.Json
Berriel

186

MVC4-Kurztipp 3 - Entfernen des XML-Formatierers aus der ASP.Net-Web-API

In Global.asaxdie Zeile:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

wie so:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    BundleTable.Bundles.RegisterTemplateBundles();
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}

9
Funktioniert - viel schöner, wenn JSON anstelle von XML der Standard ist.
Whitneyland

5
Aber können Sie dann trotzdem XML zurückgeben?
Thomas Stock

99
Ich habe es getestet und du kannst nicht. Das entfernt also die XML-Unterstützung. Ihr seid gewarnt, liebe Google-Leute
Thomas Stock

3
Wenn Sie sich meine Antwort unten ansehen, wird XML weiterhin zurückgegeben, wenn Sie möchten, aber die Site kann mit JSON auf den Browser antworten
Glenn Slaven

3
@GlennSlaven Ja, deine Antwort sollte die richtige sein.
Radu Florescu

114

Fügen Sie in der Datei WebApiConfig.cs am Ende der Registerfunktion Folgendes hinzu :

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

Quelle .


Ist XmlFormatter neu in MVC4?
Glenn Slaven

1
In MVC5 kann dies durch Ersetzen der Konfiguration durch GlobalConfiguration.Configuration
Steven

4
Für ein Projekt, das nur JSON unterstützen darf und unter keinen Umständen XML ausgeben darf, ist dies bei weitem die beste Option.
Luc C

1
config.Formatters.Add (config.Formatters.JsonFormatter);
Cas Bloem

3
Das ist furchtbar. - Dies gibt immer JSON zurück, egal was passiert, auch wenn der Client im Content-Type-Header speziell nach XML fragt.
BrainSlugs83

94

In der Global.asax verwende ich den folgenden Code. Meine URI, um JSON zu erhalten, isthttp://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"));
}

2
Tolle Sache. Was ist Ihre Methode erwarten einen Parameter? wie localhost: 61044 / api / values ​​/ getdate? json = true, date = 2012-08-01
LT.Nolo

Welche Art von Format der Daten-Web-API wird standardmäßig zurückgegeben? ist es json oder webapi? danke
Thomas

54

Schauen Sie sich die Inhaltsverhandlung in der WebAPI an. Diese ( Teil 1 & Teil 2 ) wunderbar detaillierten und gründlichen Blog-Beiträge erklären, wie es funktioniert.

Kurz gesagt, Sie haben Recht und müssen nur die Acceptoder Content-TypeAnforderungsheader festlegen. Da Ihre Aktion nicht für die Rückgabe eines bestimmten Formats codiert ist, können Sie festlegen Accept: application/json.


6
"damit ich es im Browser sehen kann"
Spongman

1
@ Spongman, ja du kannst. Verwenden Sie jedoch eine Erweiterung wie REST Client - die meisten Browser haben eine solche. Die direkte Eingabe der URL in einem Browser ist 1. Zu einschränkend (keine Kontrolle über Header, kann keine Daten veröffentlichen usw.); 2. Falsch - Der Browser verwendet die Web-API nicht so, wie sie verwendet werden soll. Sie können sich nicht darauf verlassen, dass sie ordnungsgemäß getestet wird. Ein gutes REST-Client-Add-On würde das also wieder beheben.
Ivaylo Slavov

45

Da die Frage Chrome-spezifisch ist, können Sie die Postman-Erweiterung erhalten , mit der Sie den Inhaltstyp der Anforderung festlegen können.

Briefträger


Gehen Sie in Firefox einfach zu about: config, suchen Sie nach accept.default und ändern Sie den Inhalt der network.http.accept.defaultKonfiguration in text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7.
Bjartur Thorlacius

Oder noch besser, nur um text/html,application/xhtml+xml;q=1.0,*/*;q=0.7zu vermeiden, dass fehlerhafte Hosts wie Bitbucket versehentlich Ihren Browser-JSON anstelle von HTML bedienen.
Bjartur Thorlacius


35

Eine schnelle Option ist die Verwendung der MediaTypeMapping-Spezialisierung. Hier ist ein Beispiel für die Verwendung von QueryStringMapping im Application_Start-Ereignis:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));

Immer wenn die URL in diesem Fall den Querystring? A = b enthält, wird die Json-Antwort im Browser angezeigt.


2
Das war sehr nützlich. Sie können auch UriPathExtensionMapping anstelle von QueryStringMapping verwenden, wenn Sie path.to/item.json
nuzzolilo

32

Dieser Code macht json zu meiner Standardeinstellung und ermöglicht mir auch die Verwendung des XML-Formats. Ich werde nur die anhängen xml=true.

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

Vielen Dank an alle!


1
Dies ist die flexibelste Antwort (und sollte heutzutage wirklich die Standardkonfiguration sein). Um diese Antwort zu ergänzen, ist JSON die Standardeinstellung, auch vom Browser. Um XML anzuzeigen, fügen Sie eine
Abfragezeichenfolge

Versuchte eine Reihe von Strategien. Hatte einen einfachen Test für XML und JSON und dies funktionierte
sofort

23

Verwenden Sie Ihren Browser nicht zum Testen Ihrer API.

Versuchen Sie stattdessen, einen HTTP-Client zu verwenden, mit dem Sie Ihre Anforderung angeben können, z. B. CURL oder sogar Fiddler.

Das Problem mit diesem Problem liegt im Client, nicht in der API. Die Web-API verhält sich gemäß der Anforderung des Browsers korrekt.


30
Warum nicht den Browser benutzen? Es ist ein offensichtliches Werkzeug dafür.
Anders Lindén

4
Ich denke, der Punkt hier ist richtig und wichtig - wir sollten einen funktionierenden Teil der Anwendung (die MVC WebAPI-Infrastruktur) nicht überfixieren, wenn das Problem vom Client verursacht wird. Der eigentliche Anwendungsfall für eine API ist die ordnungsgemäße Verwendung (durch Angabe korrekter Header), für die die Anwendung verantwortlich ist. Ich bin jedoch nicht damit einverstanden, den Browser vollständig zu verwerfen - zum Testen gibt es für fast jeden Browser zahlreiche Tools (zunächst Rest Client-ähnliche Erweiterungen).
Ivaylo Slavov

6
Dies sollte wahrscheinlich ein Kommentar sein.
Bonh

17

Die meisten der oben genannten Antworten sind absolut sinnvoll. Da Daten im XML-Format formatiert werden, bedeutet dies, dass der XML-Formatierer angewendet wird. Sie können also das JSON-Format anzeigen, indem Sie den XMLFormatter wie folgt aus dem Parameter HttpConfiguration entfernen

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

da JSON das Standardformat ist


12

Ich habe einen globalen Aktionsfilter verwendet, um zu entfernen, Accept: application/xmlwenn der User-AgentHeader "Chrome" enthält:

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

Scheint zu funktionieren.



10

Die Rückgabe des richtigen Formats erfolgt durch den Medientyp-Formatierer. Wie bereits erwähnt, können Sie dies in der WebApiConfigKlasse tun :

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

        ...
    }
}

Weitere Informationen finden Sie unter:

Wenn Ihre Aktionen XML zurückgeben (was standardmäßig der Fall ist) und Sie nur eine bestimmte Methode benötigen, um JSON zurückzugeben, können Sie eine verwenden ActionFilterAttributeund auf diese bestimmte Aktion anwenden.

Filterattribut:

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

Auf die Aktion anwenden:

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

Beachten Sie, dass Sie das Wort Attributeauf der Aktionsdekoration weglassen und [JsonOutput]stattdessen anstelle von verwenden können [JsonOutputAttribute].


7
        config.Formatters.Remove(config.Formatters.XmlFormatter);

3
Während dieser Code die Frage möglicherweise beantwortet, würde die Bereitstellung eines zusätzlichen Kontexts darüber, wie und / oder warum das Problem gelöst wird, den langfristigen Wert der Antwort verbessern. Bitte lesen Sie diese stackoverflow.com/help/how-to-answer
SR

6

gemäß der neuesten Version von ASP.net WebApi 2,

unter WebApiConfig.cswird dies funktionieren

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);

6

Mir ist unklar, warum die Antwort all diese Komplexität enthält. Sicher, es gibt viele Möglichkeiten, wie Sie dies mit QueryStrings, Headern und Optionen tun können ... aber was ich für die beste Vorgehensweise halte, ist einfach. Sie fordern eine einfache URL an (z. B. :) http://yourstartup.com/api/carsund erhalten dafür JSON. Sie erhalten JSON mit dem richtigen Antwortheader:

Content-Type: application/json

Auf der Suche nach einer Antwort auf dieselbe Frage fand ich diesen Thread und musste weitermachen, da diese akzeptierte Antwort nicht genau funktioniert. Ich habe eine Antwort gefunden, die meiner Meinung nach einfach zu einfach ist, um nicht die beste zu sein:

Legen Sie den Standard-WebAPI-Formatierer fest

Ich werde auch hier meinen Tipp hinzufügen.

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

Ich habe eine Frage, woher die Standardeinstellungen (zumindest die, die ich sehe) stammen. Sind sie .NET-Standardeinstellungen oder wurden sie möglicherweise woanders erstellt (von jemand anderem in meinem Projekt)? Ich hoffe, das hilft.


5

Hier ist eine Lösung ähnlich der von jayson.centeno und anderen Antworten, jedoch mit der integrierten Erweiterung von 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
 }

Die Lösung war in erster Linie auf die Unterstützung des $ -Formats für OData in den frühen Versionen von WebApi ausgerichtet, gilt jedoch auch für die Nicht-OData-Implementierung und gibt den Content-Type: application/json; charset=utf-8Header in der Antwort zurück.

Es ermöglicht Ihnen, beim Testen mit einem Browser zu heften &$format=jsonoder &$format=xmlbis zum Ende Ihres Uri. Es beeinträchtigt nicht das andere erwartete Verhalten, wenn Sie einen Nicht-Browser-Client verwenden, in dem Sie Ihre eigenen Header festlegen können.


5

Sie können wie folgt verwenden:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());

Wenn Sie eine WebAPI-App zum Übergeben von JSON-Nachrichten erstellen, sollten Sie diese Antwort berücksichtigen.
Allen1

4

Fügen Sie einfach diese beiden Codezeilen zu Ihrer WebApiConfig- Klasse hinzu

public static class WebApiConfig
{
     public static void Register(HttpConfiguration config)
     {
          //add this two line 
          config.Formatters.Clear();
          config.Formatters.Add(new JsonMediaTypeFormatter());


          ............................
      }
}

3

Sie ändern einfach Folgendes App_Start/WebApiConfig.cs:

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

Das Entfernen eines Formatierers ist im Allgemeinen keine gute Idee. Sie entfernen Funktionen.
Naspinski

Eigentlich funktioniert es in diesem Fall gut für mich, auch viele andere schlagen einen solchen Weg vor. Ich habe es aus dem Buch myview.rahulnivi.net/building-spa-angular-mvc-5 gelernt !
Vaheeds

2

Von MSDN Erstellen einer Einzelseitenanwendung mit ASP.NET und AngularJS (ca. 41 Minuten).

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

Es sollte aktuell sein, ich habe es versucht und es hat funktioniert.


2

Es ist einige Zeit vergangen, seit diese Frage gestellt (und beantwortet) wurde. Eine andere Möglichkeit besteht darin, den Accept-Header auf dem Server während der Anforderungsverarbeitung mithilfe eines MessageHandlers wie folgt zu überschreiben:

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

Wo someOtherConditionkann etwas sein, einschließlich Browsertyp usw. Dies wäre für bedingte Fälle, in denen wir nur manchmal die Standardaushandlung von Inhalten überschreiben möchten. Andernfalls würden Sie gemäß anderen Antworten einfach einen unnötigen Formatierer aus der Konfiguration entfernen.

Sie müssen es natürlich registrieren. Sie können dies entweder global tun:

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

oder auf einer Route für Route Basis:

config.Routes.MapHttpRoute(
   name: "SpecialContentRoute",
   routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}",
   defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional },
   constraints: null,
   handler: new ForceableContentTypeDelegationHandler()
);

Und da dies ein Nachrichtenhandler ist, wird er sowohl am Anforderungs- als auch am Antwortende der Pipeline ausgeführt, ähnlich wie bei einem HttpModule. So können Sie die Überschreibung leicht mit einem benutzerdefinierten Header bestätigen:

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

2

Hier ist der einfachste Weg, den ich in meinen Anwendungen verwendet habe. Fügen Sie die unten angegebenen 3 Codezeilen App_Start\\WebApiConfig.csin die RegisterFunktion ein

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

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

Die Asp.net-Web-API serialisiert Ihr zurückgegebenes Objekt automatisch in JSON und wenn das application/jsonim Header hinzugefügt wird, wird der Browser oder der Empfänger verstehen, dass Sie das JSON-Ergebnis zurückgeben.


1

WebApiConfig ist der Ort, an dem Sie konfigurieren können, ob Sie in JSON oder XML ausgeben möchten. Standardmäßig ist es XML. In der Registerfunktion können wir HttpConfiguration Formatters verwenden, um die Ausgabe zu formatieren. System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") ist erforderlich, um die Ausgabe im json-Format abzurufen. Geben Sie hier die Bildbeschreibung ein


1

Mit Felipe Leusin ‚s Antwort jahrelang nach einer letzten Aktualisierung der Kernbibliotheken und von Json.Net, lief ich in ein System.MissingMethodException: SupportedMediaTypes. Die Lösung in meinem Fall, die hoffentlich für andere hilfreich ist, bei denen dieselbe unerwartete Ausnahme auftritt, ist die Installation System.Net.Http. NuGet entfernt es anscheinend unter bestimmten Umständen. Nach einer manuellen Installation wurde das Problem behoben.


-3

Ich bin erstaunt zu sehen, dass so viele Antworten eine Codierung erfordern, um einen einzelnen Anwendungsfall (GET) in einer API zu ändern, anstatt ein geeignetes Tool zu verwenden, das einmal installiert werden muss und für jede API (eigene oder Drittanbieter) und alle verwendet werden kann Anwendungsfälle.

Die gute Antwort lautet also:

  1. Wenn Sie nur json oder einen anderen Inhaltstyp anfordern möchten, installieren Sie Requestly oder ein ähnliches Tool und ändern Sie den Accept-Header.
  2. Wenn Sie auch POST verwenden möchten und JSON, XML usw. gut formatiert haben, verwenden Sie eine geeignete API-Testerweiterung wie Postman oder ARC .

Einige bevorzugen es, Dinge zu tun, ohne das Aufblähen in Form zusätzlicher Tools und Bibliotheken hinzuzufügen.
tno2007

Es ist immer noch falsch, Änderungen an der API vorzunehmen, nur weil jemand das falsche Tool für den Job verwendet. Ein Webbrowser dient nicht zum Testen von APIs, nicht einmal zum Anzeigen der Ausgabe von APIs, sondern zum Anzeigen von Dokumenten. Es ist noch schlimmer, wenn jemand der Meinung ist, dass ein API-Tester-Tool nicht Teil des obligatorischen Toolkits für einen API-Entwickler ist, und ehrlich gesagt würde ich auch Front-End-Entwickler hinzufügen, da diese ebenfalls mit APIs interagieren und experimentieren müssen. Es ist wahrscheinlich auch nicht genug, weil der Browser ohne Addins es nicht erlaubt, Header zu setzen, auf einer API zu posten oder sogar Antwortheader zu überprüfen.
user3285954

Ich verstehe, was du sagst und du liegst nicht falsch. Der Grund, warum Sie abgelehnt werden, ist der Ton, in dem Sie die Frage beantworten. Sie klingen sehr kämpferisch und wirken wie ein Entwickler, der glaubt, alles zu wissen, und das ist sehr unangenehm. Ich bin mir sicher, dass Sie ein großartiger Entwickler sind, gemessen an Ihren Antworten. Vor allem in einem professionellen QS-Umfeld wie diesem müssen Sie jedoch lernen, Menschen freundlicher und menschlicher anzusprechen und zu überzeugen. Vielleicht geben Sie zuerst die gewünschte Antwort, erklären dann einen besseren Weg und motivieren, warum es besser ist.
tno2007
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.