Không thể đặt tiêu đề Loại-Nội dung trên tiêu đề HttpResponseMessage?


75

Tôi đang sử dụng ASP.NET WebApi để tạo API RESTful. Tôi đang tạo một phương thức PUT trong một trong các bộ điều khiển của mình và mã trông như thế này:

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;
}

Khi tôi PUT đến vị trí đó bằng trình duyệt qua AJAX, nó sẽ cho tôi Ngoại lệ này:

Tên tiêu đề được sử dụng sai. Đảm bảo rằng tiêu đề yêu cầu được sử dụng với HttpRequestMessage, tiêu đề phản hồi với HttpResponseMessage và tiêu đề nội dung với đối tượng HttpContent.

Nhưng không phải Content-Typemột tiêu đề hoàn toàn hợp lệ cho một phản hồi? Tại sao tôi nhận được ngoại lệ này?

Câu trả lời:


116

Hãy xem Thuộc tính 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
Điều gì sẽ xảy ra nếu phản hồi không có nội dung ( .Contentnull)? Tôi muốn đặt tiêu đề Loại-Nội dung ngay cả khi không có nội dung, nếu không thì Firefox phàn nàn với lỗi "không tìm thấy phần tử".
Jez

Bạn cũng có thể thử cài đặt response.StatusCode = HttpStatusCode.NoContentthay vì thêm trường tiêu đề Loại-Nội dung.
dtb 14/11/12

1
Tuyệt, hình nộm response.Content = new StringContent("");đã hoạt động. response.HeadersMặc dù vậy, tôi vẫn tự hỏi tại sao lại tồn tại.
Jez

Đối với các tiêu đề không Contentliên quan.
dtb

5
Điều này thật nực cười. Tôi rất vui vì WebApi đã hoàn thành. MVC muôn năm.
Chris Marisic

1

Một cái gì đó bị thiếu trong ASP Web API: EmptyContentloại. Nó sẽ cho phép gửi một phần thân trống trong khi vẫn cho phép tất cả các tiêu đề nội dung cụ thể.

Đặt lớp sau ở đâu đó trong mã của bạn:

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;
    }
}

Sau đó sử dụng nó như bạn muốn. Bây giờ bạn có một đối tượng nội dung cho các tiêu đề phụ của bạn.

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

Tại sao sử dụng EmptyContentthay vì new StringContent(string.Empty)?

  • StringContentlà một lớp nặng thực thi rất nhiều mã (vì nó kế thừa ByteArrayContent)
    • vì vậy chúng ta hãy tiết kiệm một vài nano giây
  • StringContent sẽ thêm một tiêu đề bổ sung vô ích / có vấn đề: Content-Type: plain/text; charset=...
    • vì vậy hãy tiết kiệm một vài byte mạng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.