Как я могу получить ASP.NET веб-API для возврата JSON вместо XML с помощью Chrome?
с помощью новой ASP.NET Web API, в Chrome Я вижу XML - как я могу изменить его на запрос JSON Так что я могу просмотреть его в браузере? Я действительно считаю, что это просто часть заголовков запроса, я прав в этом?
29 ответов:
Я просто добавляю следующее в
App_Start / WebApiConfig.csкласс в моем проекте MVC Web API.config.Formatters.JsonFormatter.SupportedMediaTypes .Add(new MediaTypeHeaderValue("text/html") );это гарантирует, что вы получите json на большинстве запросов, но вы можете получить
xmlкогда вы посылаетеtext/xml.Если вам нужно иметь ответ
Content-Typeкакapplication/jsonпожалуйста, проверьте ответ Тодда ниже.
NameSpaceиспользуетSystem.Net.Http.Headers;
если вы сделаете это в
WebApiConfigвы получите JSON по умолчанию, но он все равно позволит вам вернуть XML, если вы передадитеtext/xmlзапросAcceptзаголовок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 и поэтому не имели этого класса для начала,посмотреть этот ответ подробнее о том, как включить его.
мне нравится Фелипе Leusin-х best-убедитесь, что браузеры получают JSON без ущерба для согласования контента с клиентами, которые на самом деле хотят XML. Единственная недостающая часть для меня заключалась в том, что заголовки ответов все еще содержали content-type: text/html. Почему это было проблемой? Потому что я использую расширение JSON Formatter 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());
использование 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"));
MVC4 с быстрый Подсказка #3–Удаление XML-файл форматирования с ASP.Net веб-API
на
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);
на глобальные.асакс Я использую код ниже. Мой URI, чтобы получить JSON-это
http://www.digantakumar.com/api/values?json=trueprotected 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, вы можете получить расширение почтальон что позволяет задать тип контента запроса.
одним из быстрых вариантов является использование специализации MediaTypeMapping. Вот пример использования QueryStringMapping в событии Application_Start:
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.
вместо этого попробуйте использовать HTTP-клиент, который позволяет указать ваш запрос, например CURL или даже Fiddler.
проблема с этой проблемой находится в клиенте, а не в API. Веб-API ведет себя правильно, в соответствии с запросом браузера.
большинство из приведенных выше ответов имеет смысл. Поскольку вы видите, что данные форматируются в формате XML, это означает, что XML formatter применяется,поэтому вы можете увидеть формат JSON, просто удалив XMLFormatter из параметра HttpConfiguration, например
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-это формат по умолчанию
я использовал глобальный фильтр, чтобы удалить
Accept: application/xmlкогдаUser-Agentзаголовок содержит "Chrome":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(); } }кажется, работает.
Я нашел приложение Chrome "Advanced rest Client" отлично подходит для работы с сервисами REST. Вы можете установить Content-Type в
application/jsonсреди прочего: расширенный клиент REST
возврат правильного формата осуществляется с помощью средства форматирования типа носителя. Как уже упоминалось, вы можете сделать это в
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")); ... } }для получения дополнительной информации, проверьте:
- СМИ форматирования данных в Интернете ASP.NET API-интерфейс 2.
- согласование контента в ASP.NET Web API.
в случае, если ваши действия возвращают 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].
мне непонятно, почему в ответе есть вся эта сложность. Конечно, есть много способов сделать это, с помощью QueryStrings, заголовков и опций... но то, что я считаю лучшей практикой, просто. Вы запрашиваете простой URL (например:
http://yourstartup.com/api/cars) и взамен вы получаете JSON. Вы получаете JSON с правильным заголовком ответа:Content-Type: application/jsonВ поисках ответа на этот самый вопрос, я нашел эту тему, и должен был продолжать идти, потому что этот принятый ответ не делает работай точно. Я нашел ответ, который, как мне кажется, слишком прост, чтобы не быть лучшим:
установите форматер WebAPI по умолчанию
Я добавлю свой совет здесь, а также.
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 по умолчанию или, возможно, созданы где-то еще (кем-то другим в моем проекте). Anways, надеюсь, что это помогает.
вот решение, как Джейсон.Сентено это и другие ответы, но с помощью встроенного расширения от
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 }решение было в первую очередь направлено на поддержку $format для OData в ранних версиях WebApi, но оно также применяется к реализации без OData и возвращает
Content-Type: application/json; charset=utf-8заголовок в ответе.это позволяет вам лавировать
&$format=jsonили&$format=xmlдо конца вашего uri при тестировании с помощью браузера. Это не вмешиваться в другое ожидаемое поведение при использовании клиента без браузера, где вы можете установить свои собственные заголовки.
на
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}" ); }
согласно последней версии ASP.net WebApi 2,
под
WebApiConfig.cs, это будет работатьconfig.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter); config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
просто добавьте эти две строки кода на вашем WebApiConfig класс
public static class WebApiConfig { public static void Register(HttpConfiguration config) { //add this two line config.Formatters.Clear(); config.Formatters.Add(new JsonMediaTypeFormatter()); ............................ } }
С 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(); }он должен быть текущим, я попробовал, и это сработало.
прошло некоторое время с тех пор, как этот вопрос был задан (и ответил), но другой вариант-переопределить заголовок Accept на сервере во время обработки запроса с помощью MessageHandler, как показано ниже:
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.csinRegisterфункции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.
WebApiConfig-это место, где вы можете настроить, хотите ли вы выводить в json или xml. по умолчанию это XML. в функции регистра можно использовать HttpConfiguration форматирования для форматирования выходных данных . System.Net.Http.Headers => MediaTypeHeaderValue("text/html") требуется для получения выходных данных в формате json.
вы можете использовать, как показано ниже:
GlobalConfiguration.Configuration.Formatters.Clear(); GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
используя Фелипе Leusin's ответ в течение многих лет, после недавнего обновления основных библиотек и Json.Net я столкнулся с
System.MissingMethodException: SupportedMediaTypes. Решение в моем случае, надеюсь, полезно для других, испытывающих то же самое неожиданное исключение, чтобы установитьSystem.Net.Http. NuGet, по-видимому, удаляет его в некоторых обстоятельствах. После ручной установки проблема была решена.
Я удивлен, увидев так много ответов, требующих кодирования для изменения одного варианта использования (GET) в один API вместо того, чтобы использовать правильный инструмент, который должен быть установлен один раз и может быть использован для любой API (собственный или сторонний) и все варианты использования.
Так что хороший ответ:
- если вы хотите только запросить JSON или другой тип контента install Requestly или аналогичный инструмент и изменить заголовок Accept.
- если вы хотите использовать POST тоже и иметь красиво отформатированный json, xml и т. д. используйте правильное расширение тестирования API, например почтальон или ARC.


Comments