Подтвердить что ты не робот

Не удается установить заголовок Content-Type в заголовках HttpResponseMessage?

Я использую ASP.NET WebApi для создания RESTful API. Я создаю метод PUT в одном из моих контроллеров, и код выглядит следующим образом:

public HttpResponseMessage Put(int idAssessment, int idCaseStudy, string value) {
    var response = Request.CreateResponse();
    if (!response.Headers.Contains("Content-Type")) {
        response.Headers.Add("Content-Type", "text/plain");
    }

    response.StatusCode = HttpStatusCode.OK;
    return response;
}

Когда я перейду в это место с помощью браузера через AJAX, он дает мне это исключение:

Неправильное имя заголовка. Убедитесь, что заголовки запросов используются с HttpRequestMessage, заголовки ответов с HttpResponseMessage и заголовки содержимого с объектами HttpContent.

Но не является ли Content-Type вполне допустимым заголовком для ответа? Почему я получаю это исключение?

4b9b3361

Ответ 1

Посмотрите на Свойство HttpContentHeaders.ContentType:

response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");

if (response.Content == null)
{
    response.Content = new StringContent("");
    // The media type for the StringContent created defaults to text/plain.
}

Ответ 2

В ASP Web API чего-то не хватает: тип EmptyContent. Это позволит отправлять пустое тело, в то же время разрешая все заголовки, зависящие от содержимого.

Поместите следующий класс где-нибудь в вашем коде:

public class EmptyContent : HttpContent
{
    protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
    {
        return Task.CompletedTask;
    }
    protected override bool TryComputeLength(out long length)
    {
        length = 0L;
        return true;
    }
}

Тогда используйте это как хотите. Теперь у вас есть объект содержимого для ваших дополнительных заголовков.

response.Content = new EmptyContent();
response.Content.Headers.LastModified = file.DateUpdatedUtc;

Зачем использовать EmptyContent вместо new StringContent(string.Empty)?

  • StringContent - это тяжелый класс, который выполняет много кодов (потому что он наследует ByteArrayContent)
    • так что давайте сэкономим несколько наносекунд
  • StringContent добавит дополнительный бесполезный/проблемный заголовок: Content-Type: plain/text; charset=... Content-Type: plain/text; charset=...
    • так что давайте сохраним несколько сетевых байтов