Консолидация содержимого для возврата HTML

После чтения этого сообщения в блоге о том, как вернуть HTML из Web API 2 с помощью IHttpActionResult, я хотел как-то "подключить" этот IHttpActionResult к моему ApiController на основе заголовка Accept, который отправляется с запросом.

Указанные действия контроллера, имеющие такую ​​же подпись:

public MyObject Get(int id)
{
    return new MyObject();
}

Если запрос указывает Accept: text/html, этот IHttpActionResult должен использоваться для возврата HTML. Это возможно? Кроме того, будет оценено некоторое понимание того, как работает этот конвейер согласования контента для json или xml (которые имеют встроенную поддержку).

Ответ 1

Если мы продолжим обсуждение IHttpActionResult в сторону моментов, процесс Content-negotiation в Web API управляется через formatters. Таким образом, вам понадобится создать новый форматтер для обработки типа носителя text/html.

Web API предоставляет алгоритм по умолчанию, который он использует для согласования контента, называемого DefaultContentNegotiator, который является реализацией службы IContentNegotiator.

Теперь этот алгоритм согласования может быть запущен либо Web API автоматически для вас, как в следующих случаях:

Использование # 1:

public MyObject Get(int id)
{
   return new MyObject();
}

ИЛИ

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

Использование # 2:

public HttpResponseMessage Get()
{
    HttpResponseMessage response = new HttpResponseMessage();

    IContentNegotiator defaultNegotiator = this.Configuration.Services.GetContentNegotiator();
    ContentNegotiationResult negotationResult = defaultNegotiator.Negotiate(typeof(string), this.Request, this.Configuration.Formatters);

    response.Content = new ObjectContent<string>("Hello", negotationResult.Formatter, negotationResult.MediaType);
    return response;
}

Что касается IHttpActionResults:
В следующем сценарии Ok<> - это метод ярлыков для генерации экземпляра типа OkNegotiatedContentResult<>.

public IHttpActionResult Get()
{
    return Ok<string>("Hello");
}

Дело в том, что этот тип OkNegotiatedContentResult<> аналогичен описанному выше сценарию Использование # 2. т.е. они запускают переговорщика внутри страны.

Итак, если вы планируете поддерживать тип носителя text/html, тогда вам нужно написать собственный форматировщик и добавить его в сборщик форматирования веб-API, а затем, когда вы используете Ok<string>("Hello") с заголовком Accept text/html, вы должны увидеть ответ в text/html. Надеюсь, это поможет.