如何让ASP.NET Web API使用Chrome返回JSON而不是XML?
使用更新的ASP.NET Web API ,在Chrome中,我看到了XML – 如何将其更改为请求JSON,以便在浏览器中查看它? 我相信这只是请求标题的一部分,我正确吗?
我只是在我的MVC Web API项目的App_Start / WebApiConfig.cs
类中添加以下内容。
config.Formatters.JsonFormatter.SupportedMediaTypes .Add(new MediaTypeHeaderValue("text/html") );
这确保你在大多数查询中获得json,但是当你发送text/xml
时候你可以得到text/xml
。
如果您需要将应答Content-Type
作为application/json
请在下面检查Todd的答案 。
NameSpace
使用System.Net.Http.Headers
;
如果您在WebApiConfig
执行此操作,则默认情况下会获得JSON,但如果您通过text/xml
作为请求Accept
标头,它仍将允许您返回XML
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); } }
如果您没有使用MVC项目types,因此没有开始使用这个类, 请参阅此答案以了解如何合并它的详细信息。
我最喜欢Felipe Leusin的方法 – 确保浏览器获得JSON,而不会影响实际需要XML的客户端的内容协商。 对我来说唯一缺失的部分是响应头文件仍然包含content-type:text / html。 为什么这是一个问题? 因为我使用的JSON格式化Chrome扩展 ,它检查内容types,我没有得到我习惯的漂亮的格式。 我修复了一个简单的自定义格式化程序接受文本/ HTML请求,并返回应用程序/ 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"); } }
注册如下:
config.Formatters.Add(new BrowserJsonFormatter());
MVC4快速提示#3 – 从ASP.Net Web API中删除XML Formatter
在Global.asax
添加行:
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
像这样:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); BundleTable.Bundles.RegisterTemplateBundles(); GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); }
使用RequestHeaderMapping的效果甚至更好,因为它还将响应头中的Content-Type = application / json设置为允许Firefox(使用JSONView插件)将响应格式化为JSON。
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings .Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", "text/html", StringComparison.InvariantCultureIgnoreCase, true, "application/json"));
在WebApiConfig.cs中 ,添加到Register函数的末尾:
// Remove the XML formatter config.Formatters.Remove(config.Formatters.XmlFormatter);
来源 。
在Global.asax中我使用下面的代码。 我得到JSON的URI是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")); }
看看WebAPI中的内容协商。 这些( 第1部分和第2部分 )奇妙详细和全面的博客文章解释它是如何工作的。
简而言之,你是对的,只需要设置Accept
或Content-Type
请求头。 鉴于你的行动没有编码返回一个特定的格式,你可以设置Accept: application/json
。
由于问题是特定于Chrome,您可以使用Postman扩展名来设置请求内容types。
一个快速的select是使用MediaTypeMapping专业化。 以下是在Application_Start事件中使用QueryStringMapping的示例:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));
现在,只要url包含查询string?a = b在这种情况下,Json响应将显示在浏览器中。
这段代码使json成为我的默认,并允许我使用XML格式。 我只是追加xml=true
。
GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml")); GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
感谢大家!
不要使用您的浏览器来testing您的API。
相反,尝试使用HTTP客户端,允许您指定您的请求,如CURL,甚至Fiddler。
这个问题在客户端,而不是在API中。 根据浏览器的请求,Web API的行为是正确的。
当User-Agent
头包含“Chrome”时,我使用全局操作filter来删除Accept: application/xml
:
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(); } }
似乎工作。
上面的大部分答案都是非常有意义的。 由于您看到的数据是以XML格式格式化的,这意味着应用了XML格式化程序,所以只需从HttpConfiguration参数中删除XMLFormatter就可以看到JSON格式
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(); }
因为JSON是默认的格式
我发现Chrome应用程序“高级REST客户端”非常适合使用REST服务。 您可以将Content-Type设置为application/json
等等: 高级REST客户端
这里是类似于jayson.centeno和其他答案的解决scheme,但使用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 }
该解决scheme主要面向在WebApi的早期版本中支持OData的$ format,但也适用于非OData实现,并返回Content-Type: application/json; charset=utf-8
在响应中Content-Type: application/json; charset=utf-8
头。
它允许您在使用浏览器进行testing时将&$format=json
或&$format=xml
到您的uri的末尾。 在使用非浏览器客户端的情况下,它不会影响其他预期的行为,您可以在其中设置自己的标题。
你只App_Start/WebApiConfig.cs
像这样改变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}" ); }
根据最新版本的ASP.net WebApi 2,
在WebApiConfig.cs
下,这将工作
config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter); config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
我不清楚为什么答案中有这么复杂的东西。 当然有很多方法可以做到这一点,QueryStrings,标题和选项…但我认为最好的做法很简单。 您请求一个普通的URL(例如:http: http://yourstartup.com/api/cars
),并返回您获得JSON。 你得到正确的响应头JSON:
Content-Type: application/json
在寻找这个同样的问题的答案,我发现这个线程,并不得不继续下去,因为这个接受的答案不能正常工作。 我确实find了一个我觉得太简单而不是最好的答案:
设置默认的WebAPI格式化程序
我也会在这里添加我的提示。
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()); }
我确实有一个问题,即默认值(至less是我所看到的)的来源。 他们是.NET的默认值,或者也许创build别的地方(由我的项目上的其他人)。 反正,希望这有助于。
这个问题被询问(和回答)已经过去了一段时间,但另一个select是在使用MessageHandler进行请求处理期间覆盖服务器上的Accept头,如下所示:
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
可以是任何东西,包括浏览器types等。这将是有条件的情况下,有时我们只是想要覆盖默认的内容协商。 否则,根据其他答案,您只需从configuration中删除不必要的格式化程序。
你当然需要注册。 您可以在全球范围内执行此操作
public static void Register(HttpConfiguration config) { config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler()); }
或通过路线的路线:
config.Routes.MapHttpRoute( name: "SpecialContentRoute", routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}", defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional }, constraints: null, handler: new ForceableContentTypeDelegationHandler() );
由于这是一个消息处理程序,它将在pipe道的请求和响应两端运行,就像HttpModule
。 所以你可以很容易地用自定义标题确认覆盖:
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; } }
这是我在我的应用程序中使用的最简单的方法。 在Register
函数的App_Start\\WebApiConfig.cs
中添加下面3行代码
var formatters = GlobalConfiguration.Configuration.Formatters; formatters.Remove(formatters.XmlFormatter); config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
Asp.net的web API会自动将你的返回对象序列化为JSON,并且当application/json
被添加到头部时,浏览器或接收者将会明白你正在返回JSON结果。
只需在WebApiConfig类中添加这两行代码即可
public static class WebApiConfig { public static void Register(HttpConfiguration config) { //add this two line config.Formatters.Clear(); config.Formatters.Add(new JsonMediaTypeFormatter()); ............................ } }
媒体格式化程序返回正确的格式。 正如其他人提到的,你可以在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")); ... } }
更多,请检查:
- ASP.NET Web API 2中的媒体格式器 。
- ASP.NET Web API中的内容协商 。
如果您的操作正在返回XML(默认情况下是这种情况),并且您只需要特定的方法来返回JSON,则可以使用ActionFilterAttribute
并将其应用于该特定操作。
filter属性:
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); } }
申请行动:
[JsonOutput] public IEnumerable<Person> GetPersons() { return _repository.AllPersons(); // the returned output will be in JSON }
请注意,您可以在操作修饰中省略“ Attribute
”一词,只使用[JsonOutput]
而不是[JsonOutputAttribute]
。
config.Formatters.Remove(config.Formatters.XmlFormatter);
从MSDN 使用ASP.NET和AngularJS构build单页面应用程序 (大约41分钟)。
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(); }
它应该是最新的,我试过了,它的工作。
WebApiConfig是您可以configuration您是否要以json或xml输出的地方。 默认情况下是xml。 在注册函数中,我们可以使用HttpConfiguration Formatters来格式化输出。 System.Net.Http.Headers => MediaTypeHeaderValue(“text / html”)需要以json格式获取输出。
最简单的方法:
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
将$ format = json附加到MVC4 + webapi函数的末尾,现在将返回结果作为json,$ format = xml返回XML。 这在Chrome中很好,因为它在屏幕上显示JSON数据,但在IE中,系统会提示您下载结果的json数据。