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


75

Я використовую 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цілком дійсний заголовок для відповіді? Чому я отримую цей виняток?

Відповіді:


116

Погляньте на властивість 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.
}

1
Що робити, якщо у відповіді немає вмісту (так само і .Contentє null)? Я хочу встановити заголовок Content-Type, хоча вмісту немає, інакше Firefox скаржиться на помилку "елемент не знайдено".
Jez

Ви також можете спробувати налаштувати response.StatusCode = HttpStatusCode.NoContentзамість того, щоб додавати поле заголовка Content-Type.
dtb

1
Класно, манекен response.Content = new StringContent("");спрацював. Мені все ще залишається цікаво, чому response.Headersвзагалі існує, однак.
Jez

Для заголовків, які не Contentпов’язані.
dtb

5
Це просто смішно. Я дуже рада, що WebApi закінчено. Хай живе MVC.
Кріс Марісіч

1

Щось не вистачає у веб-API ASP: 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=...
    • тож давайте збережемо кілька байтів мережі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.