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

avatar
naspinski
23 марта 2012 в 23:04
901176
29
1220

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

Источник
Natan
6 января 2015 в 17:43
8

Здесь обсуждается, как сделать возврат JSON только поведением по умолчанию: github.com/aspnet/Mvc/issues/1765

Ответы (29)

avatar
Felipe Leusin
7 ноября 2012 в 20:25
1800

Примечание. Прочтите комментарии к этому ответу, он может вызвать уязвимость XSS, если вы используете обработку ошибок по умолчанию для WebAPI

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

gregmac
15 января 2013 в 01:44
118

Это удивительно недооцененный ответ, и хотя исходный вопрос не был полностью ясен, это напрямую делает JSON ответом по умолчанию для веб-браузера (который отправляет Accept: text / html). Молодец.

tponthieux
15 августа 2013 в 01:34
1

Мне это нравится намного больше, чем требование параметра запроса json = true.

Derek Hunziker
16 ноября 2013 в 09:51
17

+1 Однозначно лучший ответ. Я полагаю, что есть масса людей, которые решают полностью удалить XML только потому, что они не видят JSON в браузере.

Todd Menier
12 декабря 2013 в 23:54
0

Отличная работа. Мой ответ немного расширяет это, принимая text / html, но возвращая application / json, на случай, если вы используете расширение Chrome, которое ожидает его для форматирования.

surfmuggle
13 декабря 2013 в 13:21
0

@Felipe: Вы добавили свою строку выше в Global.asax? Вы имеете в виду: GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));?

Felipe Leusin
13 декабря 2013 в 22:11
2

Я давно не работал с Web API, но уверен, что это так.

Stonetip
14 марта 2014 в 15:03
4

Когда я это сделал, я обнаружил, что данные, предоставленные третьей стороной с тегами разрыва HTML, заканчиваются возвратом каретки. Тогда JSON был недействительным. Лучше использовать принятый ответ, если вас это беспокоит.

Mrchief
2 мая 2014 в 17:29
25

Обратите внимание, что заголовок ответа Content-Type по-прежнему будет text/html.

user20358
2 июля 2014 в 08:45
2

почему текст / html? Разве это не тип для json: application / json? Когда я использовал решение выше и поместил application / json вместо text / html, я получил ответ в XML. Разве этот счетчик не интуитивно понятен? application / json должно было работать. В чем причина этого?

Northstrider
10 июля 2014 в 21:01
84

Это ужасно. Заголовок типа содержимого ответа должен быть application / json. Это «решение» делает его text / html.

Felipe Leusin
11 июля 2014 в 14:40
0

Это было решение для отображения на хроме. Хотя он и не идеален, он подходит, но если вам нужен Content-Type как application / json, вы можете проверить ответ Тодда.

Curtis Yallop
20 мая 2015 в 22:02
2

Обратите внимание, что если в поле заголовка запроса «Accept» указано «application / json» (т.е. установлено в запросе ajax GET), он должен вернуть json. Mine делает это, но отображает xml, если вы открываете URL-адрес в chrome (где для подтверждения запроса не установлено значение json).

Wilson
16 июля 2015 в 17:38
0

В моем случае конфигурация не требовалась. По умолчанию использовалась json-сериализация. В соответствии с правилами согласования контента, если нет соглашения, контент будет преобразован в json.

Eugene
30 мая 2016 в 12:55
3

Если вы хотите заблокировать только json, я предлагаю вам очистить все форматеры и включить только Json. GlobalConfiguration.Configuration.Formatters.Clear(); GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());

BBi7
16 июля 2016 в 03:31
0

Меня раздражает, что Stack Overflow не позволяет мне отозвать свой голос, потому что это не то, что я ищу. Верблюд, вероятно, потому, что люди бросают вызов, думая, что это решение правильное. Почему MS не настраивает это должным образом с помощью JSON по умолчанию? Я сделал это через сертифицированный класс Microsoft и постараюсь найти подходящее решение.

Camilo Terevinto
11 января 2017 в 19:53
0

Почему / как JSON поддерживает HTML?

BrainSlugs83
5 мая 2017 в 16:05
0

Только 40 человек заметили, что есть способ получше. (через @meffect просто переназначьте тип ответа вместо установки неправильного значения по умолчанию.)

user3285954
30 ноября 2017 в 23:06
1

Это глупый взлом, а не хороший ответ. Зачем изменять свой код для чего-то настолько простого, как установка заголовка запроса? Если вы так увлечены написанием кода для этого, рекомендуем писать тесты. И я предполагаю, что Наспински и другие поняли, что они не могут тестировать POST, PUT, DELETE и т. Д. С помощью простого браузера.

Doug McClean
27 декабря 2017 в 23:41
4

Этот ответ потенциально может раскрыть уязвимость XSS. WebAPI будет включать полный URL-адрес в ответ 404, и поскольку тип содержимого - text / html, браузер с радостью выполнит любой JavaScript, включенный в строку запроса.

JPatel
5 января 2018 в 07:25
0

Подробную конфигурацию можно найти по ссылке: docs.microsoft.com/en-us/aspnet/web-api/overview/…

Jeff Dammeyer
7 февраля 2020 в 14:51
4

Я согласен с @meffect, это "прекрасный" ответ для среды разработки, но если вы используете это решение в производственной среде, вы подвергнетесь атакам XSS.

elliotwesoff
12 марта 2020 в 23:33
1

Почему так много разработчиков, использующих MS, согласны с хакерскими ответами? Ваш веб-клиент будет получать ответы, несовместимые с запрошенным форматом. Когда вы запрашиваете text / html, вы должны получать HTML. Когда вы запрашиваете application / json, вы должны получить обратно JSON. Шиш.

ptf
7 сентября 2020 в 14:13
2

Как указывали другие, это вызывает уязвимость XSS на странице веб-api 404, поскольку URL-адрес, вызывающий 404, включен в качестве содержимого на странице ошибки 404. НЕ ИСПОЛЬЗУЙТЕ.

avatar
Charles Burns
13 апреля 2018 в 19:42
1

Используя ответ Фелипе Леусина в течение многих лет, после недавнего обновления основных библиотек и Json.Net я столкнулся с System.MissingMethodException: SupportedMediaTypes. В моем случае решение, которое, надеюсь, будет полезным для других, столкнувшихся с таким же непредвиденным исключением, - это установить System.Net.Http. NuGet, по-видимому, удаляет его при некоторых обстоятельствах. После ручной установки проблема была решена.

avatar
Akshay Kapoor
11 апреля 2018 в 10:21
6

Вы можете использовать как показано ниже:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
allen1
31 декабря 2018 в 20:35
0

Если вы создаете приложение веб-API для простой передачи сообщений JSON, рассмотрите этот ответ.

avatar
user3285954
30 ноября 2017 в 23:01
-3

Я удивлен, увидев так много ответов, требующих кодирования для изменения одного варианта использования (GET) в одного API вместо использования подходящего инструмента, который нужно установить один раз и который можно использовать для любой API (собственный или сторонний) и все варианты использования.

Итак, хороший ответ:

  1. Если вы хотите запросить только json или другой тип контента, установите Requestly или аналогичный инструмент и измените заголовок Accept.
  2. Если вы хотите также использовать POST и иметь хорошо отформатированный json, xml и т. Д., Используйте подходящее расширение для тестирования API, например Postman или ARC.
  3. .
tno2007
24 февраля 2020 в 16:15
0

Некоторые предпочитают делать что-то, не добавляя лишних инструментов и библиотек.

user3285954
24 февраля 2020 в 20:51
0

По-прежнему неправильно вносить изменения в API только потому, что кто-то использует не тот инструмент для работы. Веб-браузер не предназначен для тестирования API, даже не для просмотра вывода API, а для просмотра документов. Еще хуже, если кто-то думает, что инструмент для тестирования API - это раздутый инструмент, а не часть обязательного набора инструментов для любого разработчика API, и, честно говоря, я бы также добавил разработчиков интерфейса, потому что им также нужно взаимодействовать и экспериментировать с API. Вероятно, этого также недостаточно, потому что браузер без надстроек не позволяет устанавливать заголовки, отправлять сообщения в API или даже проверять заголовки ответов.

tno2007
25 февраля 2020 в 00:18
0

Я понимаю, что вы говорите, и вы не ошиблись. Но не по теме, причина, по которой вас отвергают, - это тон, которым вы отвечаете на вопрос. Вы говорите очень агрессивно и производите впечатление разработчика, который думает, что знает все, а это очень неприятно. Я уверен, что вы отличный разработчик, судя по вашим отзывам. Но вы должны научиться, особенно в такой профессиональной среде QA, обращаться к людям и убеждать их более дружелюбно и по-человечески. Возможно, сначала дайте ответ, который они хотят, затем объясните лучший способ и мотивируйте, почему он лучше.

avatar
Gaurav Dubey
1 июля 2017 в 04:31
8
        config.Formatters.Remove(config.Formatters.XmlFormatter);
S.R
1 июля 2017 в 04:52
3

Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа. Пожалуйста, прочтите этот coderhelper.com/help/how-to-answer

avatar
pavan kumar
13 апреля 2017 в 06:26
18

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

avatar
Stacked
8 декабря 2016 в 19:03
11

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

avatar
Md. Sabbir Ahamed
10 ноября 2016 в 11:11
5

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

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


          ............................
      }
}
avatar
A.T.
27 октября 2016 в 10:26
8

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

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

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
avatar
rocky_pps
25 сентября 2016 в 00:13
1

WebApiConfig - это место, где вы можете настроить, хотите ли вы выводить в json или xml. По умолчанию это xml. В функции регистрации мы можем использовать HttpConfiguration Formatters для форматирования вывода.

System.Net.Http.Headers => MediaTypeHeaderValue("text/html") необходим для получения вывода в формате json.

enter image description here

avatar
Vikas Bansal
28 мая 2016 в 10:49
2

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

avatar
vaheeds
8 февраля 2016 в 05:03
3

Просто измените 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}"
       );
    }
naspinski
8 февраля 2016 в 15:36
0

Удаление форматтера, как правило, не является хорошей идеей, вы удаляете функциональность.

vaheeds
8 февраля 2016 в 19:03
0

На самом деле в этом случае у меня это работает хорошо, также многие другие предлагают такой способ. Я узнал об этом из книги myview.rahulnivi.net/building-spa-angular-mvc-5!

avatar
mdisibio
12 января 2016 в 17:06
5

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

avatar
rism
6 декабря 2015 в 06:32
2

Прошло некоторое время с тех пор, как этот вопрос был задан (и дан ответ), но другой вариант - переопределить заголовок 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;
    }
}
avatar
Nick
9 октября 2015 в 16:19
6

Мне непонятно, почему в ответе столько сложности. Конечно, есть много способов сделать это с помощью 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 по умолчанию или, возможно, созданы где-то еще (кем-то другим в моем проекте). Всегда, надеюсь, это поможет.

avatar
lko
30 сентября 2014 в 19:19
2

Из 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();
    }

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

avatar
dmit77
26 сентября 2014 в 20:48
336

Использование 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"));
Steve Johnson
7 марта 2015 в 21:06
8

Это наиболее экономичное и простое решение, и Fiddler также определяет тип содержимого, возвращаемый как josn.

Tim Abell
22 мая 2015 в 02:40
4

Отлично! Где бы вы посоветовали поместить это в код?

Animesh
25 июня 2015 в 08:11
11

Он должен быть в WebApiConfig.cs

KingOfHypocrites
6 июля 2015 в 15:47
0

Также отличное исправление для расширения jsonformatter, которое ломается без этого.

KingOfHypocrites
6 июля 2015 в 15:50
0

по какой-то причине расширение форматирования jsonp ломается, хотя при этом ... github.com/WebApiContrib/WebApiContrib.Formatting.Jsonp

bbsimonbb
9 февраля 2016 в 10:03
9

Работал у меня. Мне нужно было добавить , используя System.Net.Http.Formatting;

BrainSlugs83
5 мая 2017 в 16:03
1

Связывание для моего удобства: этот ответ прекрасно сочетается с другим шагом настройки, который я обычно выполняю: coderhelper.com/a/28337589/398630.

Phileosophos
13 сентября 2017 в 16:24
2

И чтобы было ясно, это просто меняет значение по умолчанию. Вы всегда можете получить JSON или XML, просто включив соответствующий заголовок «Принять».

user20072008
16 мая 2019 в 23:35
0

Он отлично работает с JSON, но не возвращает правильно отформатированный XML.

DMadden51
21 июля 2020 в 14:48
0

Это отлично работает с новейшими версиями браузеров при использовании .NET Framework.

Fab
7 августа 2020 в 09:33
0

Работает отлично ! Вы можете добавить приведенный ниже код, чтобы вернуть JSON с отступом: var jsonFormat = config.Formatters.OfType<JsonMediaTypeFormatter>().First(); jsonFormat.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; (необходимо добавить using System.Net.Http.Formatting; using Newtonsoft.Json.Serialization;)

avatar
Todd Menier
12 декабря 2013 в 23:52
322

Мне больше всего нравится подход Фелипе Леусина - убедитесь, что браузеры получают JSON без ущерба для согласования содержимого со стороны клиентов, которым действительно нужен XML. Единственное, чего мне не хватало, это то, что заголовки ответов все еще содержали content-type: 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());
Alastair Maw
15 мая 2014 в 14:48
24

В конструкторе добавьте this.SerializerSettings.Formatting = Formatting.Indented;, если хотите, чтобы он выглядел красиво без расширения браузера.

Nick
1 июля 2014 в 17:49
1

Идеально. У меня были проблемы с решением Фелипе, возвращающим Content-Type text/html, и это исправило его (и сделало ответ правильным!) Я объединил ваш ответ с ответом suhair, чтобы я получил JSON, отправленный в браузер по умолчанию, но у меня есть возможность добавления в строку запроса "format = xml" или "format = json" для выбора определенного средства форматирования. Спасибо!

Northstrider
10 июля 2014 в 21:04
11

почему вы хотите, чтобы он красиво печатал по проводам?

eddiegroves
21 июля 2014 в 06:20
1

@meffect pretty-printing предпочтительнее при просмотре в браузере. Клиенты, запрашивающие json через application / json, все равно будут возвращать json без отступа.

H.Wolper
1 декабря 2014 в 12:00
9

Разве ответ @ dmit77 не лучше (более краткий), чем этот?

Todd Menier
15 декабря 2014 в 18:31
0

@AlastairMaw хорошая идея, добавил ваше предложение, поэтому красивая печать работает без расширения для браузера.

Northstrider
12 февраля 2015 в 20:53
8

@eddiegroves, ты не хочешь красиво печатать по проводам. Вы хотите, чтобы сервер отправлял по сети наименьшее количество бит (т.е. без пробелов). Затем вы хотите, чтобы браузер красиво его отформатировал, добавив надстройки и тому подобное. Javascript обычно должен анализировать JSON, зачем делать его медленнее, вводя ненужное форматирование

Jester
3 сентября 2015 в 20:10
2

Спасибо, Тодд, лучший ответ: 1) правильный тип возврата, 2) сохраняет красивое форматирование ТОЛЬКО из браузера И 3) мне не нужно добавлять новый тип подтверждения в Firefox, и Chrome также работает! Сладость.

Berriel
16 сентября 2015 в 01:46
13

Для тех, кто ищет: не забудьте добавить using System.Net.Http.Formatting и using Newtonsoft.Json

wize
26 января 2016 в 19:49
1

Чтобы убедиться, что международные символы возвращаются правильно, установите правильную кодировку, добавив строку headers.ContentType.CharSet = "utf-8"; в конец функции SetDefaultContentHeaders().

DonDon
24 ноября 2016 в 06:09
0

Решение не работает с IE (например, все еще просит загрузить файл json). Что-нибудь исправить?

avatar
Chris S
27 сентября 2013 в 10:40
45

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

Postman

Bjartur Thorlacius
6 июня 2018 в 10:48
0

В Firefox просто перейдите в about: config, найдите accept.default и измените содержимое конфигурации network.http.accept.default на text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7.

Bjartur Thorlacius
6 июня 2018 в 11:01
0

Или еще лучше, просто text/html,application/xhtml+xml;q=1.0,*/*;q=0.7, чтобы избежать случайного обслуживания ошибочными хостами, такими как Bitbucket, JSON вашего браузера вместо HTML.

Falcon Momot
2 июля 2018 в 04:34
0

URL мертв. Новый - chrome.google.com/webstore/detail/postman/….

avatar
jayson.centeno
3 сентября 2013 в 01:48
34

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

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

raider33
30 марта 2014 в 14:04
1

Это наиболее гибкий ответ (и в наши дни он действительно должен быть конфигурацией по умолчанию). Чтобы добавить к этому ответу, по умолчанию используется JSON, в том числе из браузера. Для просмотра XML добавьте строку запроса:? Xml = true

pat capozzi
17 июня 2015 в 21:55
0

Пробовал ряд стратегий. Был простой тест как для XML, так и для JSON, и это сработало из коробки

avatar
Roger Lipscombe
23 июня 2013 в 14:47
11

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

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

avatar
Michael Vashchinsky
5 января 2013 в 22:43
119

В WebApiConfig.cs добавьте в конец функции Register :

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

Источник.

Glenn Slaven
31 июля 2013 в 22:41
0

XmlFormatter является новым в MVC4?

Steven
19 сентября 2013 в 13:50
1

В MVC5 это можно сделать, заменив config на GlobalConfiguration.Configuration

Luc C
15 июля 2014 в 12:45
5

Для проекта, который должен поддерживать только JSON и ни при каких обстоятельствах не может быть разрешено испускать XML, это, безусловно, лучший вариант.

Cas Bloem
16 апреля 2015 в 13:41
1

config.Formatters.Add (config.Formatters.JsonFormatter);

BrainSlugs83
5 мая 2017 в 21:30
3

Это ужасно. - Это всегда будет возвращать JSON независимо от того, что, даже если клиент специально запрашивает XML в заголовке Content-Type.

cdiggins
5 ноября 2020 в 04:42
1

Проекты, которые не тестируют XML-версию API так тщательно, как их версия JSON, должны выбрать это. Объекты сериализуются по-разному разными программами форматирования согласно ссылке, которую указал Майкл. Например: средства форматирования XML не сериализуют поля, доступные только для чтения, в отличие от средства форматирования JSON.

avatar
Glenn Slaven
19 сентября 2012 в 02:53
510

Если вы сделаете это в WebApiConfig, вы получите JSON по умолчанию, но он все равно позволит вам возвращать XML, если вы передадите text/xml в качестве заголовка запроса Accept.

Примечание: это удаляет поддержку для application/xml

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 и, следовательно, у вас не было этого класса для начала, см. Этот ответ, чтобы узнать, как его включить.

porges
26 марта 2013 в 21:20
51

Следует отметить, что исходное поведение правильное. Chrome запрашивает application/xml с приоритетом 0,9 и */* с приоритетом 0,8. Удаляя application/xml, вы лишаете веб-API возможности возвращать XML, если клиент запрашивает именно это. например если вы отправите «Accept: application / xml», вы все равно получите JSON.

Sylvain
29 марта 2013 в 16:38
0

Основываясь на комментарии @ Porges, я предлагаю заключить две строки, удаляющие поддержку XML, в директиву #if DEBUG. Таким образом, в dev вы можете использовать адресную строку Chrome для тестирования вашего api и получения json по умолчанию, и вы по-прежнему будете предлагать поддержку XML в своей среде prod.

NickG
9 апреля 2013 в 18:24
12

Это я, или первое предложение неверно? Код, похоже, полностью удаляет XML, а не просто меняет значение по умолчанию.

Cohen
3 июля 2013 в 10:09
0

@NickG: да и нет, он удаляет поддержку application / xml, но вы все равно можете использовать text / xml. (Хотя text / xml считается устаревшим)

Cohen
3 июля 2013 в 10:10
6

@NickG: решение, которое здесь упускается из виду, и IMHO - гораздо лучший вариант (сохранение application / xml) - это решение, предложенное Фелипе Леусином ниже на этой странице. Использование config.Formatters.XmlFormatter.SupportedMediaTypes.Add (new MediaTypeHeaderValue ("text / html"));

Kyle
3 сентября 2013 в 01:40
1

Итак, как нам сделать это через веб-конфигурацию, чтобы мы получали json по умолчанию и XML по запросу?

Ken Smith
9 сентября 2013 в 13:20
4

Ответ @Felipse Leusin ниже на самом деле короче и работает лучше.

avatar
dmyoko
15 июля 2012 в 00:24
22

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

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

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

Anders Lindén
18 сентября 2012 в 06:37
32

Почему бы не использовать браузер? Это очевидный инструмент для этого.

Ivaylo Slavov
25 апреля 2014 в 21:30
5

Я думаю, что здесь правильный и важный момент - мы не должны переопределять рабочую часть приложения (инфраструктуру MVC WebAPI), если проблема вызвана клиентом. Реальный вариант использования Api - это правильное использование (путем предоставления правильных заголовков), за что отвечает приложение. Я не согласен с тем, чтобы полностью отказаться от браузера - для тестирования есть множество инструментов практически для любого браузера (для начала, расширения, подобные Rest Client).

bonh
14 мая 2015 в 19:14
8

Вероятно, это должен быть комментарий.

avatar
Diganta Kumar
6 июля 2012 в 07:00
99

В 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"));
}
LT.Nolo
5 сентября 2012 в 13:04
2

Великий. Какой ваш метод ожидает параметр? например localhost: 61044 / api / values ​​/ getdate? json = true, date = 2012-08-01

avatar
Yakir Manor
2 апреля 2012 в 16:11
189

Быстрый совет №3 по MVC4 - удаление средства форматирования 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();
}
whitneyland
15 апреля 2012 в 22:38
9

Работает - гораздо приятнее использовать JSON по умолчанию вместо XML.

Thomas Stock
4 июля 2012 в 00:37
5

но можно ли тогда вернуть xml?

Thomas Stock
4 июля 2012 в 00:42
100

Я проверил это, и вы не можете. Таким образом, это удаляет поддержку XML. Будьте осторожны, уважаемые гуглеры.

Glenn Slaven
24 сентября 2012 в 01:17
3

Если вы посмотрите на мой ответ ниже, это позволит вернуть xml, если вы хотите, но позволит сайту отвечать JSON в браузере.

radu florescu
14 октября 2012 в 16:46
3

@GlennSlaven, да, ваш ответ должен быть помечен как правильный.

shashwat
21 февраля 2013 в 15:14
0

Добавление только последней строки GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); сработало для меня. Я получал ошибку во всех остальных строках. Это Web Form Apllication

avatar
Mike Rowley
28 марта 2012 в 21:57
10

Мне показалось, что приложение Chrome «Advanced REST Client» отлично подходит для работы со службами REST. Среди прочего вы можете установить Content-Type на application/json: Расширенный клиент REST

avatar
suhair
27 марта 2012 в 05:08
35

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

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

Теперь всякий раз, когда URL-адрес содержит строку запроса? A = b, в этом случае в браузере будет отображаться ответ Json.

nuzzolilo
13 апреля 2012 в 23:28
2

Это было очень полезно. Вы также можете использовать UriPathExtensionMapping вместо QueryStringMapping, если хотите использовать path.to/item.json

avatar
Aaron Daniels
24 марта 2012 в 04:24
54

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

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

Spongman
5 марта 2013 в 19:19
6

"чтобы я мог просмотреть его в браузере"

Ivaylo Slavov
25 апреля 2014 в 21:37
1

@Spongman, да, ты можешь. Но используйте такое расширение, как REST Client - оно есть в большинстве браузеров. Прямой ввод URL-адреса в браузере - 1. Слишком ограничен (нет контроля над заголовками, нельзя публиковать данные и т. Д.); 2. Неправильно - браузер не использует веб-API, поскольку он предназначен для использования - вы не можете полагаться на его правильное тестирование. Итак, опять же, хорошая надстройка клиента REST исправит это.