Answers:
我只是App_Start / WebApiConfig.cs
在我的MVC Web API项目中的类中添加以下内容。
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html") );
这样可以确保您在大多数查询中都可以获取JSON,但是XML
在发送时可以获取JSON text/xml
。
如果您需要得到答复Content-Type
,application/json
请检查以下Todd的回答。
NameSpace
正在使用System.Net.Http.Headers
。
Content-Type
标头仍为text/html
。
如果您在中执行此操作,则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项目类型,因此没有此类,那么请参阅此答案以获取有关如何合并它的详细信息。
application/xml
的优先级为0.9,*/*
优先级为0.8。通过删除,application/xml
可以消除Web API在客户端特别要求时返回XML的功能。例如,如果您发送“ Accept:application / xml”,您仍然会收到JSON。
使用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"));
我最喜欢Felipe Leusin的方法 -确保浏览器获取JSON,而又不损害来自实际需要XML的客户端的内容协商。对我而言,唯一缺少的是响应头仍然包含content-type:text / html。为什么会有问题呢?因为我使用的是JSON Formatter Chrome扩展程序,它检查内容类型,所以我没有惯用的漂亮格式。我用一个简单的自定义格式化程序修复了该问题,该格式化程序接受文本/ html请求并返回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");
}
}
像这样注册:
config.Formatters.Add(new BrowserJsonFormatter());
this.SerializerSettings.Formatting = Formatting.Indented;
如果您希望它的外观漂亮而不带浏览器扩展。
using System.Net.Http.Formatting
和using Newtonsoft.Json
MVC4快速提示#3 –从ASP.Net Web API删除XML格式器
在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();
}
在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扩展程序,该扩展程序可让您设置请求内容类型。
network.http.accept.default
配置内容更改为text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7
。
text/html,application/xhtml+xml;q=1.0,*/*;q=0.7
为了避免诸如Bitbucket之类的漏洞主机意外地为您的浏览器JSON代替HTML。
一种快速的选择是使用MediaTypeMapping专用化。这是在Application_Start事件中使用QueryStringMapping的示例:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));
现在,在这种情况下,只要网址包含查询字符串?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"));
谢谢大家!
不要使用浏览器来测试您的API。
而是尝试使用允许您指定请求的HTTP客户端,例如CURL甚至Fiddler。
此问题的问题在于客户端,而不是API。根据浏览器的请求,Web API的行为正确。
以上大多数答案都是很合理的。由于您看到的是以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是默认格式
Accept: application/xml
当User-Agent
标题包含“ 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();
}
}
似乎可以工作。
返回正确的格式由媒体类型格式化程序完成。正如其他人提到的,您可以在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"));
...
}
}
有关更多信息,请检查:
如果您的操作正在返回XML(默认情况下是这种情况),并且您只需要一种特定的方法来返回JSON,则可以使用an ActionFilterAttribute
并将其应用于该特定操作。
过滤器属性:
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);
我不清楚为什么答案中会包含所有这些复杂性。当然,可以使用QueryStrings,标头和选项通过多种方式来实现此目的,但是我认为最好的做法很简单。您请求一个纯URL(例如:),http://yourstartup.com/api/cars
然后返回JSON。您将获得带有正确响应头的JSON:
Content-Type: application/json
在寻找这个相同问题的答案时,我找到了这个线索,并且不得不继续前进,因为这个公认的答案无法正常工作。我确实找到了一个答案,我觉得这很简单,不能成为最佳答案:
我也会在这里添加提示。
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());
}
我确实有一个关于默认值(至少是我所看到的)来自何处的问题。它们是.NET默认值,还是在其他地方(由我项目中的其他人创建)创建。Anways,希望这会有所帮助。
这是一个类似于jayson.centeno和其他答案的解决方案,但使用来自的内置扩展名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
}
该解决方案主要是为了在WebApi的早期版本中为OData支持$ format,但它也适用于非OData实现,并Content-Type: application/json; charset=utf-8
在响应中返回
标头。
使用浏览器进行测试时,它可让您补充&$format=json
或&$format=xml
结束uri。使用非浏览器客户端可以在其中设置自己的标头时,它不会干扰其他预期行为。
您可以如下使用:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
只需在WebApiConfig类 上添加这两行代码
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//add this two line
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
............................
}
}
您只需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}"
);
}
从MSDN 使用ASP.NET和AngularJS构建单页应用程序(大约需要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();
}
它应该是最新的,我尝试过并且有效。
自问(并回答)此问题以来已经过去了一段时间,但是另一种选择是在请求处理期间使用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
可以是任何内容,包括浏览器类型等。这将用于有条件的情况下,只有在某些情况下,我们才需要覆盖默认的内容协商。否则,按照其他答案,您只需从配置中删除不必要的格式化程序即可。
您当然需要注册。您可以全局执行以下操作:
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()
);
并且由于这是一个消息处理程序,它可以在管道的请求和响应端上运行,就像一个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;
}
}
这是我在应用程序中使用过的最简单的方法。App_Start\\WebApiConfig.cs
在Register
函数中添加以下三行代码
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结果。
令我惊讶的是,有如此多的答复要求通过编码来更改一个 API中的单个用例(GET),而不是使用适当的工具,该工具必须安装一次并可以用于任何 API(自己或第三方),并且所有用例。
因此,好的答案是: