Используя более новый ASP.NET Web API , в Chrome я вижу XML - как я могу изменить его для запроса JSON, чтобы я мог просматривать его в браузере? Я действительно считаю, что это только часть заголовков запроса, я прав в этом?
Используя более новый ASP.NET Web API , в Chrome я вижу XML - как я могу изменить его для запроса JSON, чтобы я мог просматривать его в браузере? Я действительно считаю, что это только часть заголовков запроса, я прав в этом?
Ответы:
Я просто добавляю следующее в 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
.
Content-Type
заголовок ответа по- прежнему будет text/html
.
Если вы сделаете это в, 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 и, следовательно, не имеете этого класса для начала, обратитесь к этому ответу для получения подробных сведений о его включении.
application/xml
с приоритетом 0,9 и */*
приоритетом 0,8. Удаляя, application/xml
вы удаляете возможность для Web API возвращать XML, если клиент запрашивает это специально. Например, если вы отправите «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"));
Мне больше нравится подход Фелипе Леусина - убедитесь, что браузеры получают JSON без ущерба для согласования контента от клиентов, которые действительно хотят XML. Единственное, чего мне не хватало, так это того, что заголовки ответов по-прежнему содержали тип содержимого: text / html. Почему это было проблемой? Потому что я использую расширение JSON Formatter Chrome , которое проверяет тип контента, и я не получаю красивое форматирование, к которому я привык. Я исправил это с помощью простого пользовательского средства форматирования, которое принимает запросы text / 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 - Удаление XML Formatter из ASP.Net Web 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 добавьте в конец функцию Register :
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
Источник .
В Global.asax я использую код ниже. Мой URI для получения JSONhttp://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
or или Content-Type
request. Поскольку ваше действие не закодировано для возврата определенного формата, вы можете установить 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, от случайного обслуживания вашего браузера JSON вместо HTML.
Одним из быстрых вариантов является использование специализации 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, поэтому вы можете увидеть формат 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"));
...
}
}
Для больше, проверьте:
Если ваши действия возвращают 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 (ex:) 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 значениями по умолчанию или, возможно, созданы где-то еще (кем-то другим в моем проекте). Надеюсь, это поможет.
Вот решение, похожее на jayson.centeno и другие ответы, но с использованием встроенного расширения from 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 при тестировании с браузером. Это не мешает другому ожидаемому поведению при использовании клиента без браузера, где вы можете установить свои собственные заголовки.
Вы можете использовать как ниже:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
Просто добавьте эти две строки кода в свой класс WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//add this two line
config.Formatters.Clear();
config.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();
}
Это должно быть текущим, я попробовал, и это работало.
Некоторое время прошло с тех пор, как этот вопрос был задан (и получен ответ), но другой вариант - переопределить заголовок 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.cs
в Register
функцию
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
Веб-API Asp.net автоматически сериализует ваш возвращаемый объект в JSON, и, как только application/json
он добавляется в заголовок, браузер или получатель поймут, что вы возвращаете результат JSON.
WebApiConfig - это место, где вы можете настроить, хотите ли вы выводить данные в формате json или xml. по умолчанию это xml. в функции регистра мы можем использовать HttpConfiguration Formatters для форматирования вывода. System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") требуется для получения вывода в формате json.
Используя ответ Фелипе Леусина в течение многих лет, после недавнего обновления основных библиотек и Json.Net я столкнулся с System.MissingMethodException
: SupportedMediaTypes. Решение в моем случае, которое, надеюсь, поможет другим, столкнувшимся с таким же неожиданным исключением, заключается в установке System.Net.Http
. NuGet, по-видимому, удаляет его при некоторых обстоятельствах. После ручной установки проблема была решена.
Я удивлен, увидев так много ответов, требующих кодирования для изменения одного варианта использования (GET) в одном API вместо использования соответствующего инструмента, который должен быть установлен один раз и может использоваться для любого API (собственного или стороннего) и всех остальных. случаи использования.
Итак, хороший ответ: