【问题标题】:How to change default Web API 2 to JSON formatter?如何将默认 Web API 2 更改为 JSON 格式化程序?
【发布时间】:2014-10-03 04:36:50
【问题描述】:

我有一个返回一些产品数据的 Web API 项目。它根据请求的 Accept 标头 (JSON/XML) 正确协商返回类型。问题是,如果没有指定 Accept 标头,它会返回 XML,但我希望它默认返回 JSON

http://website.com/MyPage?type=json // returns json
http://website.com/MyPage?type=xml // returns xml
http://website.com/MyPage // returns xml by default

这是我当前的代码如下:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(
new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml")));

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

【问题讨论】:

    标签: c# asp.net-web-api asp.net-web-api2


    【解决方案1】:

    仅供参考,请小心拦截 text/html 媒体类型,因为这也会格式化来自服务器的 404 响应。就我而言,这导致了潜在的安全问题,因为:

    • 恶意用户浏览到http://api.mysite.com/one/two?test=%3Cscript%3Ealert(%27hi%27)%3C/script%3E
    • Web API 返回 404 对象,其中包括 URL。由于上面的属性,这是 JSON 格式。
    • 浏览器认为返回的对象其实是text/html,所以只是渲染了JSON对象
    • 这会导致嵌入在 URL 中的脚本标记执行。在我上面的示例 URL 中,它只是一个警报,但它也可能是 window.location 或任何险恶的东西

    【讨论】:

      【解决方案2】:

      我认为你应该改变如下。 Global.asax:

      /*For Indented formatting:*/       
       GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
      
          /*Response as default json format
           * example (http://localhost:9090/WebApp/api/user/)
           */
          GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
      
          /*Response as json format depend on request type
           * http://localhost:9090/WebApp/api/user/?type=json
           */
          GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(
          new QueryStringMapping("type", "json", new MediaTypeHeaderValue("application/json")));
      
          /*Response as xml format depend on request type
           * http://localhost:9090/WebApp/api/user/?type=xml
           */
          GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(
          new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml")));
      

      【讨论】:

        【解决方案3】:
        config.EnableSystemDiagnosticsTracing();
        
        GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
        
        // Adding formatter for Json   
        config.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("type", "json", new MediaTypeHeaderValue("application/json")));
        
        // Adding formatter for XML   
        config.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml")));
        

        【讨论】:

          【解决方案4】:

          以上答案都不适合我。问题是我从GlobalConfiguration 获取格式化程序,而不是使用new HttpConfiguration() 创建的config 对象这是对我有用的代码:

          public class WebApiConfig
          {
              public static HttpConfiguration Register()
              {
          
                  var config = new HttpConfiguration();
                  // This next line could stay if you want xml formatting
                  config.Formatters.Remove(config.Formatters.XmlFormatter);
          
                  // This next commented out line was causing the problem
                  //var jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
          
                  // This next line was the solution
                  var jsonFormatter = config.Formatters.JsonFormatter;
                  jsonFormatter.UseDataContractJsonSerializer = false; // defaults to false, but no harm done
                  jsonFormatter.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
                  jsonFormatter.SerializerSettings.Formatting = Formatting.None;
                  jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();           
          
                  // remaining irrelevant code commented out
                  return config;
              }
          }
          

          【讨论】:

            【解决方案5】:

            将此添加到您的App_Start/WebApiConfig.cs

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

            【讨论】:

            • 在使用 Owin 时,您需要使用 WebApiConfig.Register() 中创建的 config 对象和 new Httpconfiguration(),而不是 GlobalConfiguration.Configuration 更多信息 here
            • 这是一个指向my answer below 的链接,我将其包含在内,因为我不得不把所有的头发都扯掉才能让它发挥作用,并希望能减轻别人的痛苦。
            • @Alastair,感谢您的贡献:)。并且downvoter,当你对某人投反对票时,请留下评论。
            【解决方案6】:

            或者只是删除 XmlFormatter

            var formatters = GlobalConfiguration.Configuration.Formatters;
            formatters.Remove(formatters.XmlFormatter);
            

            【讨论】:

            【解决方案7】:

            我认为 Web API 只是使用了它可以在 Formatters 集合中找到的第一个格式化程序。您可以使用类似的东西更改排序

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

            但似乎默认情况下 JSON 格式化程序应该是第一个格式化程序,因此您可能需要检查您是否已经在某处修改此集合。

            【讨论】:

              猜你喜欢
              • 2013-12-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-05-28
              • 2023-03-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多