Как заставить ASP.NET Web API возвращать JSON вместо XML с помощью Chrome?
Используя новый ASP.NET Web API, в Chrome, я вижу XML - как я могу его изменить, чтобы запросить JSON, чтобы я можете просмотреть его в браузере? Я действительно верю, что это всего лишь часть заголовков запросов, я прав в этом?
Ответы
Ответ 1
Я просто добавляю следующее в класс App_Start / WebApiConfig.cs
в проект MVC Web API.
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html") );
Это гарантирует, что вы получите json для большинства запросов, но вы можете получить xml
при отправке text/xml
.
Если вам нужен ответ Content-Type
как application/json
, пожалуйста, проверьте ответ Todd ниже.
NameSpace
использует System.Net.Http.Headers
;
Ответ 2
Если вы сделаете это в 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 и, следовательно, не имели этого класса для начала, см. этот ответ для получения подробной информации о том, как его включить.
Ответ 3
Мне нравится подход Felipe Leusin - убедитесь, что браузеры получают JSON без компрометации согласования контента с клиентами, которые действительно хотят XML. Единственным недостающим моментом для меня было то, что заголовки ответов по-прежнему содержали контент-тип: text/html. Почему это проблема? Потому что я использую расширение
Зарегистрируйся так:
config.Formatters.Add(new BrowserJsonFormatter());
Ответ 4
Использование 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"));
Ответ 5
MVC4 Quick Tip # 3-Извлечение XML Formatter из веб-интерфейса ASP.Net
В 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();
}
Ответ 6
В WebApiConfig.cs добавьте в конец функции Регистрация:
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
Источник.
Ответ 7
В Global.asax я использую следующий код. Мой URI для получения JSON 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"));
}
Ответ 8
Посмотрите на согласование контента в WebAPI. Эти (Часть 1 и Часть 2) чудесно подробные и подробные сообщения в блогах объясняют, как это работает.
Короче говоря, вы правы, и вам просто нужно установить заголовки запросов Accept
или Content-Type
. Если ваше действие не закодировано для возврата определенного формата, вы можете установить Accept: application/json
.
Ответ 9
Поскольку вопрос специфичен для Chrome, вы можете получить расширение Postman, которое позволяет вам установить тип содержимого запроса.
![Postman]()
Ответ 10
Одним быстрым вариантом является использование специализации MediaTypeMapping. Ниже приведен пример использования QueryStringMapping в событии Application_Start:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));
Теперь, когда URL-адрес содержит запрос, a = b, в браузере будет отображаться ответ Json.
Ответ 11
Этот код делает 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"));
Спасибо всем!
Ответ 12
Не используйте браузер для тестирования вашего API.
Вместо этого попробуйте использовать HTTP-клиент, который позволяет вам указать ваш запрос, такой как CURL или даже Fiddler.
Проблема с этой проблемой возникает в клиенте, а не в API. Веб-API ведет себя правильно, в соответствии с запросом браузера.
Ответ 13
Я использовал глобальный фильтр действий для удаления 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();
}
}
Кажется, работает.
Ответ 14
Большая часть приведенных выше ответов имеет смысл.
Поскольку вы видите, что данные отформатированы в формате XML, это означает, что применяется формат XML, SO, вы можете видеть формат 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 является стандартным форматом
Ответ 15
Я обнаружил, что приложение Chrome "Advanced REST Client" отлично работает с службами REST. Вы можете установить Content-Type на application/json
между прочим:
Расширенный клиент REST
Ответ 16
Вот решение, подобное 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
}
Решение было в основном ориентировано на поддержку формата $OData в ранних выпусках WebApi, но оно также относится к реализации без OData и возвращает
Content-Type: application/json; charset=utf-8
в ответе.
Это позволяет вам привязать &$format=json
или &$format=xml
к концу вашего uri при тестировании с помощью браузера. Это не мешает другим ожидаемым действиям при использовании не-браузерного клиента, где вы можете установить свои собственные заголовки.
Ответ 17
Мне непонятно, почему в этом есть вся эта сложность. Конечно, есть много способов сделать это, с 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, надеюсь, что это поможет.
Ответ 18
Вы просто измените 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}"
);
}
Ответ 19
в соответствии с последней версией ASP.net WebApi 2,
под WebApiConfig.cs
, это будет работать
config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
Ответ 20
Прошло некоторое время с момента запроса (и ответа), но другой вариант - переопределить заголовок 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;
}
}
Ответ 21
Вот самый простой способ, который я использовал в своих приложениях. Добавьте приведенные ниже 3 строки кода в App_Start\\WebApiConfig.cs
в Register
функцию
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
Web-API Asp.net автоматически преобразует ваш возвращаемый объект в JSON и добавит application/json
в заголовок, чтобы браузер или получатель понимали, что вы возвращаете результат JSON.
Ответ 22
Просто добавьте эти две строки кода в класс WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//add this two line
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
............................
}
}
Ответ 23
Возврат правильного формата выполняется форматом медиа-типа.
Как уже упоминалось, вы можете сделать это в классе 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]
.
Ответ 24
config.Formatters.Remove(config.Formatters.XmlFormatter);
Ответ 25
От 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();
}
Он должен быть текущим, я попробовал его, и он сработал.
Ответ 26
WebApiConfig - это место, где вы можете настроить, хотите ли вы выводить в json или xml. по умолчанию это xml. в функции register мы можем использовать HttpConfiguration Formatters для форматирования вывода.
System.Net.Http.Headers = > MediaTypeHeaderValue ( "text/html" ) требуется получить выход в формате json.
![введите описание изображения здесь]()
Ответ 27
Самый простой способ:
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
Ответ 28
Добавление $format = json в конец MVC4 + webapi-функции теперь возвращает результат как json, а $format = xml возвращает XML.
Это нормально в Chrome, поскольку он отображает данные JSON на экране, но в IE вам будет предложено загрузить результирующие данные json.