使用更新的ASP。NET Web API,在Chrome中我看到XML -我如何将其更改为请求JSON,以便我可以在浏览器中查看它?我相信这只是请求头的一部分,我是正确的吗?


当前回答

在最新版本的ASP.net WebApi 2中,在WebApiConfig.cs下,这将工作:

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

其他回答

一个快速的选择是使用MediaTypeMapping专门化。下面是一个在Application_Start事件中使用QueryStringMapping的例子:

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

现在,只要url包含querystring(在这种情况下,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"));

谢谢大家!

看看WebAPI中的内容协商。这些(第1部分和第2部分)非常详细和彻底的博客文章解释了它是如何工作的。

简而言之,您是对的,只需要设置Accept或Content-Type请求头。如果你的Action没有返回特定的格式,你可以设置Accept: application/json。

从这个问题被问到(和回答)已经过去了一段时间,但是另一个选择是在请求处理过程中使用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;
    }
}

只需在WebApiConfig类中添加这两行代码

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


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