Використовуючи новіший веб-API ASP.NET , у Chrome я бачу XML - як я можу змінити його, щоб запросити JSON, щоб я міг його переглянути у браузері? Я вважаю, що це лише частина заголовків запитів, чи я в цьому правильний?
Використовуючи новіший веб-API ASP.NET , у 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
ви видаляєте можливість веб-API повертати XML, якщо клієнт спеціально цього вимагає. наприклад, якщо ви надішлете "Прийняти: 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 , яке перевіряє тип вмісту, і я не отримую гарного форматування, до якого я звик. Я вирішив це за допомогою простого користувальницького форматера, який приймає текстові / html запити та повертає відповіді програми / 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-формату з веб-API 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();
}
У WebApiConfig.cs додайте до кінця функції Реєстрація :
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
Джерело .
У 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"));
}
Погляньте на узгодження контенту в 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, випадково обслуговувати ваш браузер 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 "Розширений клієнт REST" відмінним для роботи з послугами REST. Ви можете встановити тип вмісту 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-адресу (наприклад:), 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 та інші відповіді, але з використанням вбудованого розширення від 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
до кінця свого урі. Це не заважає іншій очікуваній поведінці під час використання клієнта, який не переглядає браузер, де ви можете встановити власні заголовки.
Ви можете використовувати як нижче:
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 для форматування виводу. System.Net.Http.Headers => MediaTypeHeaderValue ("текст / html") потрібно отримати вихід у форматі json.
Використовуючи відповідь Феліпе Леусіна протягом багатьох років, після недавнього оновлення основних бібліотек та Json.Net, я наткнувся на System.MissingMethodException
: SupportedMediaTypes. У моєму випадку, сподіваємось, корисним для інших, хто відчуває такий же несподіваний виняток, є встановлення System.Net.Http
. NuGet, очевидно, видаляє його за деяких обставин. Після встановлення вручну проблему було вирішено.
Я здивований, коли я бачив так багато відповідей, що вимагають кодування для зміни одного випадку використання (GET) в одному API, замість того, щоб використовувати належний інструмент, що має бути встановлено один раз, і його можна використовувати для будь-якого API (власного чи третього боку) та всіх випадки використання.
Тож хороша відповідь: