2013-06-06 4 views
3

В моем приложении я делаю несколько javascript-запросов для своих контроллеров Api, чтобы получить некоторые строки в формате html. Когда эти запросы сделаны с Accept: */* HTTP-заголовком (метод jQuery $.get), поэтому по умолчанию используется JsonMediaTypeFormatter, а данные возвращаются с Content-Type: application/json в формате JSON.WebApi: */* тип обработки мультимедиа

Я хотел бы обрабатывать */* как text/html. Так что я попытался создать пользовательский MediaTypeFormatter, который поддерживает тип */* средств массовой информации, но это дает мне следующую ошибку

«MediaTypeHeaderValue» из */* не может быть использовано в качестве поддерживаемого типа СМИ, потому что это СМИ range.`

В качестве альтернативы, я всегда мог бы предоставить правильные ожидаемые типы данных в своих запросах, но мне любопытно, есть ли способ обрабатывать типы носителей */*.

ответ

7

Такое поведение обусловлено следующим:

алгоритм кон-нег по умолчанию в Web API имеет следующий порядковый номер для выбора форматирования для ответа:

  1. Сравнение форматирования на основе типа картона.
  2. Согласование форматирования на основе типа медиаконтента Accept Accept.
  3. Согласование форматирования на основе типа носителя заголовка Content Content-Type.
  4. Согласование форматирования на основе того, может ли он сериализовать тип данных ответа.

Теперь JsonMediaTypeFormatter поставляется с встроенным отображением типа носителя под названием XmlHttpRequestHeaderMapping, который инспектирует входящий запрос и видит, если запрос имеет заголовок x-requested-with: XMLHttpRequest, а также, если есть не принимать заголовок или если Accept заголовка только имеющего */*.

Поскольку ваш запрос в основном, вероятно, глядя, как показано ниже, в соответствии с порядком старшинства JsonMediaTypeFormatter выбран в качестве одного пишущего ответ:

GET /api/something
Accept: */*
x-requested-with: XMLHttpRequest

Решение для вашей проблемы будет это явно попросить «text/html», поскольку это то, что вы ожидаете.

GET /api/something
Accept: text/html
x-requested-with: XMLHttpRequest

Пара очень старых сообщений в блоге о содержании переговоров, которые я написал: http://blogs.msdn.com/b/kiranchalla/archive/2012/02/25/content-negotiation-in-asp-net-mvc4-web-api-beta-part-1.aspx
http://blogs.msdn.com/b/kiranchalla/archive/2012/02/27/content-negotiation-in-asp-net-mvc4-web-api-beta-part-2.aspx

2

Большой вопрос.

Вы не можете установить */*, чтобы быть поддерживаемым типом носителя, но то, что вы можете сделать, это установить ваш форматтер, чтобы он был первым. Web API выберет первый форматтер в коллекции форматирования, который может выписать тип, если нет заголовка Accept или если заголовок Accept содержит */*.

Так вы хотите, чтобы настроить веб-API, как это:

config.Formatters.Insert(0, new MyHtmlFormatter()); 
+0

, что была моя первая мысль, но по какой-то причине 'JsonMediaTypeFormatter' вызывается первым в любом случае. Мой форматировщик вызывается только тогда, когда ожидаемый тип данных устанавливается в text/html в моих запросах. –

+2

JsonMediaTypeFormatter имеет сопоставление заголовка запроса для XmlHttpRequest. если ваш запрос имеет этот заголовок, тогда всегда выбирается JsonMediaTypeFormatter. Форматы, которые сопоставляются с отображением типа медиа (здесь Json's RequestHeaderMapping), всегда ковыряют совпадения в заголовке Accept. FYI: проверьте этот исходный код: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Net.Http.Formatting/Formatting/XmlHttpRequestHeaderMapping.cs –

+0

@KiranChalla, о, вау, спасибо. Не всегда, хотя XMLHttpRequests с правильным заголовком 'Accept' обрабатывается моим Formatter. Поэтому мне интересно, есть ли способ изменить это поведение для «пустых» заголовков Accept. –

Смежные вопросы