Как заставить ASP.NET Web API возвращать JSON вместо XML с помощью Chrome?

Используя новый ASP.NET Web API, в Chrome, я вижу XML - как я могу его изменить, чтобы запросить JSON, чтобы я можете просмотреть его в браузере? Я действительно верю, что это всего лишь часть заголовков запросов, я прав в этом?

1153
задан naspinski 24 марта '12 в 2:04
источник поделиться
28 ответов

Я просто добавляю следующее в класс 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;

1414
ответ дан Felipe Leusin 07 нояб. '12 в 23:25
источник поделиться

Если вы сделаете это в 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 и, следовательно, не имели этого класса для начала, см. этот ответ для получения подробной информации о том, как его включить.

462
ответ дан Glenn Slaven 19 сент. '12 в 5:53
источник поделиться

Мне нравится подход Felipe Leusin - убедитесь, что браузеры получают JSON без компрометации согласования контента с клиентами, которые действительно хотят XML. Единственным недостающим моментом для меня было то, что заголовки ответов по-прежнему содержали контент-тип: text/html. Почему это проблема? Потому что я использую расширение

Зарегистрируйся так:

config.Formatters.Add(new BrowserJsonFormatter());
246
ответ дан Todd Menier 13 дек. '13 в 2:52
источник поделиться

Использование 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"));
167
ответ дан dmit77 26 сент. '14 в 23:48
источник поделиться

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();
}
164
ответ дан Yakir Manor 02 апр. '12 в 19:11
источник поделиться

В WebApiConfig.cs добавьте в конец функции Регистрация:

// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);

Источник.

94
ответ дан Michael Vashchinsky 06 янв. '13 в 1:43
источник поделиться

В 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"));
}
85
ответ дан Diganta Kumar 06 июля '12 в 10:00
источник поделиться

Посмотрите на согласование контента в WebAPI. Эти (Часть 1 и Часть 2) чудесно подробные и подробные сообщения в блогах объясняют, как это работает.

Короче говоря, вы правы, и вам просто нужно установить заголовки запросов Accept или Content-Type. Если ваше действие не закодировано для возврата определенного формата, вы можете установить Accept: application/json.

47
ответ дан Aaron Daniels 24 марта '12 в 7:24
источник поделиться

Поскольку вопрос специфичен для Chrome, вы можете получить расширение Postman, которое позволяет вам установить тип содержимого запроса.

Postman

35
ответ дан Chris S 27 сент. '13 в 13:40
источник поделиться

Одним быстрым вариантом является использование специализации MediaTypeMapping. Ниже приведен пример использования QueryStringMapping в событии Application_Start:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));

Теперь, когда URL-адрес содержит запрос, a = b, в браузере будет отображаться ответ Json.

29
ответ дан suhair 27 марта '12 в 8:08
источник поделиться

Этот код делает 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"));

Спасибо всем!

27
ответ дан jayson.centeno 03 сент. '13 в 4:48
источник поделиться

Не используйте браузер для тестирования вашего API.

Вместо этого попробуйте использовать HTTP-клиент, который позволяет вам указать ваш запрос, такой как CURL или даже Fiddler.

Проблема с этой проблемой возникает в клиенте, а не в API. Веб-API ведет себя правильно, в соответствии с запросом браузера.

15
ответ дан dmyoko 15 июля '12 в 3:24
источник поделиться

Я использовал глобальный фильтр действий для удаления 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();
    }
}

Кажется, работает.

7
ответ дан Roger Lipscombe 23 июня '13 в 17:47
источник поделиться

Большая часть приведенных выше ответов имеет смысл. Поскольку вы видите, что данные отформатированы в формате 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 является стандартным форматом

6
ответ дан pavan kumar 13 апр. '17 в 9:26
источник поделиться

Я обнаружил, что приложение Chrome "Advanced REST Client" отлично работает с службами REST. Вы можете установить Content-Type на application/json между прочим: Расширенный клиент REST

5
ответ дан Mike Rowley 29 марта '12 в 0:57
источник поделиться

Вот решение, подобное 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 при тестировании с помощью браузера. Это не мешает другим ожидаемым действиям при использовании не-браузерного клиента, где вы можете установить свои собственные заголовки.

3
ответ дан mdisibio 12 янв. '16 в 20:06
источник поделиться

Мне непонятно, почему в этом есть вся эта сложность. Конечно, есть много способов сделать это, с 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, надеюсь, что это поможет.

2
ответ дан Nick 09 окт. '15 в 19:19
источник поделиться

в соответствии с последней версией ASP.net WebApi 2,

под WebApiConfig.cs, это будет работать

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
2
ответ дан A.T. 27 окт. '16 в 13:26
источник поделиться

Вы просто измените 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}"
       );
    }
2
ответ дан vaheeds 08 февр. '16 в 8:03
источник поделиться

Просто добавьте эти две строки кода в класс WebApiConfig

public static class WebApiConfig
{
     public static void Register(HttpConfiguration config)
     {
          //add this two line 
          config.Formatters.Clear();
          config.Formatters.Add(new JsonMediaTypeFormatter());


          ............................
      }
}
1
ответ дан Md. Sabbir Ahamed 10 нояб. '16 в 14:11
источник поделиться

Вот самый простой способ, который я использовал в своих приложениях. Добавьте приведенные ниже 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.

1
ответ дан Vikas Bansal 28 мая '16 в 13:49
источник поделиться

Прошло некоторое время с момента запроса (и ответа), но другой вариант - переопределить заголовок 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;
    }
}
1
ответ дан rism 06 дек. '15 в 9:32
источник поделиться
        config.Formatters.Remove(config.Formatters.XmlFormatter);
1
ответ дан Gaurav Dubey 01 июля '17 в 7:31
источник поделиться

Возврат правильного формата выполняется форматом медиа-типа. Как уже упоминалось, вы можете сделать это в классе 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].

1
ответ дан Stacked 08 дек. '16 в 22:03
источник поделиться

WebApiConfig - это место, где вы можете настроить, хотите ли вы выводить в json или xml. по умолчанию это xml. в функции register мы можем использовать HttpConfiguration Formatters для форматирования вывода. System.Net.Http.Headers = > MediaTypeHeaderValue ( "text/html" ) требуется получить выход в формате json. введите описание изображения здесь

0
ответ дан Parag 25 сент. '16 в 3:13
источник поделиться

От 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();
    }

Он должен быть текущим, я попробовал его, и он сработал.

0
ответ дан lko 30 сент. '14 в 22:19
источник поделиться

Самый простой способ:

 GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
-1
ответ дан Leo 28 нояб. '16 в 17:01
источник поделиться

Добавление $format = json в конец MVC4 + webapi-функции теперь возвращает результат как json, а $format = xml возвращает XML. Это нормально в Chrome, поскольку он отображает данные JSON на экране, но в IE вам будет предложено загрузить результирующие данные json.

-4
ответ дан JSobell 05 авг. '13 в 1:24
источник поделиться

Другие вопросы по меткам или Задайте вопрос