【问题标题】:How to force ASP.NET Web API to always return JSON?如何强制 ASP.NET Web API 始终返回 JSON?
【发布时间】:2012-09-19 16:44:02
【问题描述】:

ASP.NET Web API 默认进行内容协商 - 将根据 Accept 标头返回 XML 或 JSON 或其他类型。我不需要/不想要这个,有没有办法(比如属性或其他东西)告诉 Web API 总是返回 JSON?

【问题讨论】:

  • 您也许可以从GlobalConfiguration.Configuration.Formatters中删除除json之外的所有格式化程序

标签: asp.net-mvc asp.net-web-api


【解决方案1】:

清除所有格式化程序并重新添加 Json 格式化程序。

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

编辑

我将它添加到Global.asax 内的Application_Start()。

【讨论】:

  • 在哪个文件中..?? global.ascx..??
  • 在你的 Application_Start() 方法中
  • Filip W 现在有了更好的方法 :),在此处查看 strathweb.com/2013/06/…
  • @TienDo - 链接到 Filip 自己的博客?
  • 设置最好放在App_Start\WebApiConfig.cs文件中。
【解决方案2】:

Supporting only JSON in ASP.NET Web API – THE RIGHT WAY

将 IContentNegotiator 替换为 JsonContentNegotiator:

var jsonFormatter = new JsonMediaTypeFormatter();
//optional: set serializer settings here
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));

JsonContentNegotiator 实现:

public class JsonContentNegotiator : IContentNegotiator
{
    private readonly JsonMediaTypeFormatter _jsonFormatter;

    public JsonContentNegotiator(JsonMediaTypeFormatter formatter) 
    {
        _jsonFormatter = formatter;    
    }

    public ContentNegotiationResult Negotiate(
            Type type, 
            HttpRequestMessage request, 
            IEnumerable<MediaTypeFormatter> formatters)
    {
        return new ContentNegotiationResult(
            _jsonFormatter, 
            new MediaTypeHeaderValue("application/json"));
    }
}

【讨论】:

  • 代码的第一部分也是在哪里剪切和粘贴的?我在 Global.asax 中没有看到“配置”对象。那个变量是从哪里来的?文章也没有解释。
  • 在 WebApiConfig.cs 文件中检查 public static void Register(HttpConfiguration config) { ... } 方法,该文件已由 VS2012 在项目创建时生成
  • 这是否会强制使用 JSON,因为客户端 Accepting XML 将获得 JSON,而 不会获得 406?
  • 我可以回答我自己的评论/问题:无论Accept 标头如何,它都会返回 XML。
  • 这破坏了我的 swashbuckle 集成,它似乎与 github 上的这个问题有关(github.com/domaindrivendev/Swashbuckle/issues/219)。我想使用这种方法,但下面使用GlobalConfiguration...Clear() 的方法确实有效。
【解决方案3】:

Philip W 有正确的答案,但为了清楚起见和完整的工作解决方案,编辑您的 Global.asax.cs 文件如下所示:(注意我必须将参考 System.Net.Http.Formatting 添加到生成的股票文件)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace BoomInteractive.TrainerCentral.Server {
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication {
        protected void Application_Start() {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //Force JSON responses on all requests
            GlobalConfiguration.Configuration.Formatters.Clear();
            GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
        }
    }
}

【讨论】:

    【解决方案4】:
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
    

    这会清除 XML 格式化程序,因此默认为 JSON 格式。

    【讨论】:

    • 完善所有需要的东西
    【解决方案5】:

    受到 Dmitry Pavlov 出色答案的启发,我对其稍作修改,以便可以插入任何我想强制执行的格式化程序。

    归功于德米特里。

    /// <summary>
    /// A ContentNegotiator implementation that does not negotiate. Inspired by the film Taken.
    /// </summary>
    internal sealed class LiamNeesonContentNegotiator : IContentNegotiator
    {
        private readonly MediaTypeFormatter _formatter;
        private readonly string _mimeTypeId;
    
        public LiamNeesonContentNegotiator(MediaTypeFormatter formatter, string mimeTypeId)
        {
            if (formatter == null)
                throw new ArgumentNullException("formatter");
    
            if (String.IsNullOrWhiteSpace(mimeTypeId))
                throw new ArgumentException("Mime type identifier string is null or whitespace.");
    
            _formatter = formatter;
            _mimeTypeId = mimeTypeId.Trim();
        }
    
        public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
        {
            return new ContentNegotiationResult(_formatter, new MediaTypeHeaderValue(_mimeTypeId));
        }
    }
    

    【讨论】:

      【解决方案6】:

      这设置了正确的标题。看起来更优雅一些。

      public JsonResult<string> TestMethod() 
      {
      return Json("your string or object");
      }
      

      【讨论】:

      【解决方案7】:

      如果您只想对一种方法执行此操作,则将您的方法声明为返回 HttpResponseMessage 而不是 IEnumerable&lt;Whatever&gt; 并执行以下操作:

          public HttpResponseMessage GetAllWhatever()
          {
              return Request.CreateResponse(HttpStatusCode.OK, new List<Whatever>(), Configuration.Formatters.JsonFormatter);
          }
      

      这段代码对于单元测试来说很痛苦,但也可以这样:

          sut = new WhateverController() { Configuration = new HttpConfiguration() };
          sut.Configuration.Formatters.Add(new Mock<JsonMediaTypeFormatter>().Object);
          sut.Request = new HttpRequestMessage();
      

      【讨论】:

      【解决方案8】:

      对于那些使用 OWIN 的人

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

      变成(在 Startup.cs 中):

         public void Configuration(IAppBuilder app)
              {
                  OwinConfiguration = new HttpConfiguration();
                  ConfigureOAuth(app);
      
                  OwinConfiguration.Formatters.Clear();
                  OwinConfiguration.Formatters.Add(new DynamicJsonMediaTypeFormatter());
      
                  [...]
              }
      

      【讨论】:

        【解决方案9】:

        你可以在WebApiConfig.cs中使用:

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

        【讨论】:

          【解决方案10】:
           public System.Web.Http.Results.JsonResult<MeineObjekt> Get()
              {
                  return Json(new MeineObjekt()
                  {
                      Cod = "C4666",               
                      Payment = 10.0m,
                      isEnough = false
                  });
              }
          

          【讨论】:

            猜你喜欢
            • 2021-06-01
            • 2018-11-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多