Mit der neueren ASP.NET Web API in Chrome sehe ich XML - wie kann ich es ändern, um JSON anzufordern, damit ich kann im Browser anzeigen? Ich glaube, es ist nur ein Teil der Anforderungsheader, bin ich richtig?
In meinem MVC-Web-API-Projekt füge ich in der Klasse App_Start / WebApiConfig.cs
Folgendes hinzu.
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html") );
Das stellt sicher, dass Sie bei den meisten Abfragen JSON erhalten, aber Sie können xml
erhalten, wenn Sie text/xml
senden.
Wenn Sie die Antwort Content-Type
als application/json
benötigen, überprüfen Sie bitte Todd's Antwort unten .
NameSpace
verwendet System.Net.Http.Headers
;
Wenn Sie dies in der WebApiConfig
tun, erhalten Sie standardmäßig JSON, können aber trotzdem XML zurückgeben, wenn Sie text/xml
als Anforderungsheader Accept
übergeben
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 nicht zu Beginn hatten, siehe diese Antwort für Einzelheiten zur Einbindung.
Ich mag Felipe Leusins Ansatz am besten - stelle sicher, dass Browser JSON erhalten, ohne die Inhaltsaushandlung von Clients zu beeinträchtigen, die tatsächlich XML wollen. Das einzige fehlende Teil für mich war, dass die Antwort-Header immer noch den Inhaltstyp "text/html" enthielten. Warum war das ein Problem? Weil ich die JSON Formatter Chrome -Erweiterung verwende, die den Inhaltstyp überprüft, und ich 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());
Die Verwendung von RequestHeaderMapping funktioniert sogar noch besser, da der Content-Type = application/json
im Antwortheader 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"));
MVC4 Quick Tip Nr. 3 - Entfernen des XML-Formatierers von der ASP.Net-Web-API
Fügen Sie in Global.asax
die folgende Zeile hinzu:
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();
}
Fügen Sie in der Datei WebApiConfig.cs am Ende der Funktion Register hinzu :
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
Quelle .
In der Global.asax verwende ich den folgenden Code. Mein URI für JSON ist 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"));
}
Schauen Sie sich die Inhaltsverhandlung im 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 Anforderungsheader Accept
oder Content-Type
setzen. Da Ihre Aktion nicht so programmiert ist, dass sie ein bestimmtes Format zurückgibt, können Sie Accept: application/json
einstellen.
Da die Frage Chrome-spezifisch ist, können Sie die Postman-Erweiterung erhalten, mit der Sie den Anforderungsinhaltstyp festlegen können.
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"));
Wenn die URL in diesem Fall den Querystring? A = b enthält, wird die Json-Antwort im Browser angezeigt.
Dieser Code macht json zu meinem Standard und ermöglicht mir, auch das XML-Format zu verwenden. Ich werde einfach den xml=true
anhängen.
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!
Verwenden Sie nicht Ihren Browser, um Ihre API zu testen.
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.
Die meisten der oben genannten Antworten sind absolut sinnvoll. Da Sie sehen, dass Daten im XML-Format formatiert sind, 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
Ich habe einen globalen Aktionsfilter verwendet, um Accept: application/xml
zu entfernen, wenn der User-Agent
-Header "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.
Ich fand die Chrome App "Advanced REST Client" hervorragend für die Arbeit mit REST Services. Sie können den Content-Type unter anderem auf application/json
setzen: Advanced REST client
Die Rückgabe des richtigen Formats erfolgt durch den Medientyp-Formatierer. Wie bereits erwähnt, können Sie dies in der Klasse WebApiConfig
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 ein ActionFilterAttribute
verwenden und es 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 Attribute
in der Aktionsdekoration weglassen und nur [JsonOutput]
anstelle von [JsonOutputAttribute]
verwenden können.
Mir ist nicht klar, warum die Antwort so komplex ist. Sicher, es gibt viele Möglichkeiten, dies mit QueryStrings, Headern und Optionen zu tun, aber was ich für die beste Vorgehensweise halte, ist einfach. Sie fordern eine einfache URL an (z. B. http://yourstartup.com/api/cars
) und erhalten dafür JSON. Sie erhalten JSON mit dem richtigen Antwortheader:
Content-Type: application/json
Auf der Suche nach einer Antwort auf dieselbe Frage habe ich diesen Thread gefunden und musste weitermachen, da diese akzeptierte Antwort nicht genau funktioniert. Ich habe eine Antwort gefunden, die ich für zu einfach halte, um nicht die beste zu sein:
Legen Sie den Standard-WebAPI-Formatierer fest
Ich werde hier auch 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 stammen (zumindest die, die ich sehe). Handelt es sich um .NET-Standardeinstellungen, oder handelt es sich um etwas, das an einer anderen Stelle erstellt wurde (von jemand anderem in meinem Projekt)? Ich hoffe immer, das hilft.
gemäß der neuesten Version von ASP.net WebApi 2,
unter WebApiConfig.cs
wird dies funktionieren
config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
Hier ist eine Lösung, die jayson.centeno's und anderen Antworten ähnlich ist, aber die eingebaute Erweiterung von System.Net.Http.Formatting
verwendet.
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 früheren Versionen von WebApi ausgerichtet. Sie gilt jedoch auch für die Nicht-OData-Implementierung und gibt den Header Content-Type: application/json; charset=utf-8
in der Antwort zurück.
Es ermöglicht Ihnen, &$format=json
oder &$format=xml
beim Testen mit einem Browser bis zum Ende Ihrer URL anzuheften. Wenn Sie einen Nicht-Browser-Client verwenden, in dem Sie Ihre eigenen Header festlegen können, beeinträchtigt dies nicht das erwartete Verhalten.
config.Formatters.Remove(config.Formatters.XmlFormatter);
Sie können wie folgt verwenden:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
Fügen Sie einfach diese beiden Codezeilen in Ihre Klasse WebApiConfig ein
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//add this two line
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
............................
}
}
Sie ändern einfach den App_Start/WebApiConfig.cs
wie folgt:
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}"
);
}
From MSDNErstellen einer Einzelseitenanwendung mit ASP.NET und AngularJS (ungefähr 41 Minuten in).
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.
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 mit einem MessageHandler 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);
}
}
Wobei someOtherCondition
alles sein kann, einschließlich des Browsertyps usw. Dies gilt für bedingte Fälle, in denen nur gelegentlich die standardmäßige Inhaltsaushandlung außer Kraft gesetzt werden soll. Andernfalls würden Sie, wie in den anderen Antworten angegeben, 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 auf Routenbasis:
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 Message-Handler ist, wird er sowohl am Anforderungs- als auch am Antwortende der Pipeline ausgeführt, ähnlich wie ein 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;
}
}
Hier ist der einfachste Weg, den ich in meinen Anwendungen verwendet habe. Fügen Sie die folgenden 3 Codezeilen in die Funktion App_Start\\WebApiConfig.cs
in Register
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 zu JSON und fügt application/json
in die Kopfzeile ein, damit der Browser oder der Empfänger versteht, dass Sie das JSON-Ergebnis zurückgeben.
Nachdem ich die Antwort von Felipe Leusin jahrelang nach einem kürzlichen Update der Kernbibliotheken und von Json.Net verwendet hatte, stieß ich auf System.MissingMethodException
: SupportedMediaTypes. In meinem Fall besteht die Lösung, die hoffentlich auch für andere hilfreich ist, darin, System.Net.Http
zu installieren. NuGet entfernt es anscheinend unter bestimmten Umständen. Nach einer manuellen Installation wurde das Problem behoben.
In WebApiConfig können Sie konfigurieren, ob Sie in json oder xml ausgeben möchten. standardmäßig ist es xml. In der Registerfunktion können wir HttpConfiguration-Formatierer verwenden, um die Ausgabe zu formatieren. System.Net.Http.Headers => MediaTypeHeaderValue ("text/html") ist erforderlich, um die Ausgabe im json-Format zu erhalten.