ASP.NET Web API가 항상 JSON을 반환하도록 강제하는 방법은 무엇입니까?


103

ASP.NET Web API는 기본적으로 콘텐츠 협상을 수행하며 Accept헤더 에 따라 XML 또는 JSON 또는 기타 유형을 반환합니다 . 나는 이것을 필요로하지 않습니다 / 원하지 않습니다. Web API에 항상 JSON을 반환하도록 지시하는 방법 (속성 등)이 있습니까?


json을 제외한 모든 포맷터를 제거 할 수 있습니다.GlobalConfiguration.Configuration.Formatters
Claudio Redi

답변:


75

ASP.NET Web API에서 JSON 만 지원 – 올바른 방법

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"));
    }
}

4
코드의 첫 부분도 잘라내어 붙여 넣을 수 있습니까? 내 Global.asax에 "config"개체가 표시되지 않습니다. 그 변수의 출처는 어디입니까? 이 기사도 설명하지 않습니다.
BuddyJoe 2013-08-13

3
확인 공공 정적 무효 등록 (HttpConfiguration 설정) {...} 프로젝트 생성에 VS2012에 의해 gererated 된 WebApiConfig.cs 파일 방법
드미트리 파블로프

이것이 AcceptXML 을 사용하는 클라이언트 가 JSON을 얻고 406을 얻지 못한다 는 의미에서 JSON을 강제 합니까?
Luke Puplett 2014 년

1
내 자신의 의견 / 질문에 답할 수 있습니다 Accept. 헤더에 관계없이 XML을 반환합니다 .
Luke Puplett 2014 년

2
이것은 내 swashbuckle 통합을 깨뜨리고 github ( github.com/domaindrivendev/Swashbuckle/issues/219 ) 의이 문제와 관련된 것 같습니다 . 이 방법을 사용하고 싶지만 아래 방법이 GlobalConfiguration...Clear()실제로 작동합니다.
seangwright

167

모든 포맷터를 지우고 Json 포맷터를 다시 추가하십시오.

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

편집하다

Global.asax내부에 추가했습니다 Application_Start().


그리고 어떤 파일에 .. ?? global.ascx .. ??
shashwat

당신의 위해 Application_Start () 메소드에서
Jafin

6
필립 W는 여기를 참조하십시오 지금 더 좋은 방법 : 가지고 strathweb.com/2013/06/...
티엔 마

7
@TienDo-Filip 자신의 블로그에 연결?
Phill

10

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());
        }
    }
}

9
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

이렇게하면 XML 포맷터가 지워 지므로 기본값은 JSON 형식입니다.


필요한 모든 것을 완벽하게
tfa

4

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));
    }
}

2

하나의 메서드에 대해서만 그렇게하려면 메서드를 HttpResponseMessage대신 반환 하는 것으로 선언하고 다음 IEnumerable<Whatever>을 수행하십시오.

    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();

당신이 수있는 방법이 무엇인가를 원하는 경우에만 만들 msdn.microsoft.com/en-us/library/...
엘리자베스


0

WebApiConfig.cs에서 사용할 수 있습니다.

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

0

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());

            [...]
        }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.