답변:
App_Start / WebApiConfig.cs
MVC 웹 API 프로젝트 에서 클래스에 다음을 추가합니다 .
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html") );
따라서 대부분의 쿼리에서 JSON을 얻을 수 있지만 XML
을 보낼 때 얻을 수 있습니다 text/xml
.
당신이 반응을해야하는 경우 Content-Type
로 application/json
확인하시기 바랍니다 아래 토드의 답변을 .
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
당신은 반환 XML로 클라이언트 요청하는 경우 그 구체적를 웹 API의 기능을 제거합니다. 예를 들어 "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의 접근 방식이 가장 좋습니다. 실제로 XML을 원하는 클라이언트의 컨텐츠 협상을 방해하지 않고 브라우저가 JSON을 얻도록하십시오. 나를 위해 유일하게 누락 된 부분은 응답 헤더에 여전히 content-type : text / html이 포함되어 있다는 것입니다. 왜 문제가 되었습니까? 콘텐츠 형식을 검사 하는 JSON 형식 기 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 웹 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 ,의 끝에 추가 등록 기능 :
// 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과 같은 버그가 많은 호스트가 실수로 HTML 대신 브라우저 JSON을 제공하지 않도록하십시오.
빠른 옵션 중 하나는 MediaTypeMapping 전문화를 사용하는 것입니다. 다음은 Application_Start 이벤트에서 QueryStringMapping을 사용하는 예입니다.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));
이 경우 URL에 쿼리 문자열? 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를 테스트하지 마십시오.
대신 CURL 또는 Fiddler와 같은 요청을 지정할 수있는 HTTP 클라이언트를 사용하십시오.
이 문제의 문제점은 API가 아닌 클라이언트에 있습니다. 브라우저 요청에 따라 웹 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이 기본 형식이므로
헤더에 "Chrome"이 포함 된 Accept: application/xml
경우 전역 작업 필터를 사용하여 제거했습니다 User-Agent
.
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();
}
}
작동하는 것 같습니다.
REST 서비스와 함께 작동하는 Chrome 앱 'Advanced REST Client'가 우수하다는 것을 알았습니다. Content-Type을 다음과 같이 설정할 수 있습니다 application/json
.
Advanced REST client
올바른 형식 반환은 미디어 유형 포맷터에 의해 수행됩니다. 다른 사람들이 언급했듯이 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을 리턴하는 특정 메소드 만 필요한 경우 및를 사용 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 기본값입니까, 아니면 다른 곳에서 (내 프로젝트의 다른 사람에 의해) 만들어 졌습니까? 어쨌든, 이것이 도움이되기를 바랍니다.
다음은 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());
다음 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;
}
}
내 응용 프로그램에서 사용하는 가장 쉬운 방법은 다음과 같습니다. 코드의 3 개 라인 아래에 주어진 추가 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 웹 API는 반환 객체를 JSON으로 자동 직렬화 application/json
하고 헤더에 추가되면 브라우저 또는 수신자가 JSON 결과를 반환한다는 것을 이해할 수 있습니다.
나는 단일 사용 사례 (GET) 변경 코딩을 필요로하는 많은 응답을 참조 깜짝이야 하나의 API를 대신 한 번 설치해야하고 사용할 수 있습니다 어떤 적절한 도구를 사용하여 임의의 모든 API (자신 또는 제 3 자) 및 사용 사례.
따라서 좋은 대답은 다음과 같습니다.