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



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

849   29  

29 ответов:

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

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

мне нравится Фелипе Leusin-х best-убедитесь, что браузеры получают JSON без ущерба для согласования контента с клиентами, которые на самом деле хотят XML. Единственная недостающая часть для меня заключалась в том, что заголовки ответов все еще содержали content-type: text/html. Почему это было проблемой? Потому что я использую расширение JSON Formatter Chrome, который проверяет тип контента, и я не получаю красивое форматирование, к которому я привык. Я исправил это с помощью простого пользовательского форматирования, принимает текстовые / 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());

использование 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"));

MVC4 с быстрый Подсказка #3–Удаление XML-файл форматирования с ASP.Net веб-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 добавить в конец зарегистрироваться:

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

источник.

на глобальные.асакс Я использую код ниже. Мой 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

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

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

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

на 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}"
       );
    }

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

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

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);

просто добавьте эти две строки кода на вашем WebApiConfig класс

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


          ............................
      }
}
        config.Formatters.Remove(config.Formatters.XmlFormatter);

С 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 in Register функции

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));

Asp.net веб-API автоматически сериализует возвращаемый объект в JSON и как application/json добавляется в заголовок, так что браузер или получатель поймет, что вы возвращаете результат JSON.

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

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

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());

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

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

Так что хороший ответ:

  1. если вы хотите только запросить JSON или другой тип контента install Requestly или аналогичный инструмент и изменить заголовок Accept.
  2. если вы хотите использовать POST тоже и иметь красиво отформатированный json, xml и т. д. используйте правильное расширение тестирования API, например почтальон или ARC.

Comments

    Ничего не найдено.