Đặt nội dung trong đối tượng HttpResponseMessage?


180

Vài tháng trước, Microsoft đã quyết định thay đổi lớp HttpResponseMessage. Trước đây, bạn có thể chỉ cần chuyển một kiểu dữ liệu vào hàm tạo, sau đó trả về tin nhắn với dữ liệu đó, nhưng không còn nữa.

Bây giờ, bạn cần sử dụng thuộc tính Nội dung để đặt nội dung của tin nhắn. Vấn đề là nó thuộc loại HTTPContent và dường như tôi không thể tìm cách chuyển đổi một chuỗi, ví dụ, thành HTTPContent.

Có ai biết làm thế nào để đối phó với vấn đề này? Cảm ơn rất nhiều.

Câu trả lời:


216

Đối với một chuỗi cụ thể, cách nhanh nhất là sử dụng StringContent constructor

response.Content = new StringContent("Your response text");

Có một số hậu duệ lớp httpContent bổ sung cho các tình huống phổ biến khác.


Xem bài đăng của tôi dưới đây để tạo các loại StringContent có nguồn gốc của riêng bạn (ví dụ JSON, XML, v.v.).
bytedev

135

Bạn nên tạo phản hồi bằng Request.CreateResponse :

HttpResponseMessage response =  Request.CreateResponse(HttpStatusCode.BadRequest, "Error message");

Bạn có thể chuyển các đối tượng không chỉ các chuỗi cho CreatResponse và nó sẽ tuần tự hóa chúng dựa trên tiêu đề Chấp nhận của yêu cầu. Điều này tiết kiệm cho bạn từ việc chọn thủ công một định dạng.


Nó tự động hoạt động với các loại nội dung để bạn có thể thực hiện xml / json mà không cần thêm mã

Tôi nghĩ sẽ đúng hơn CreateErrorResponse()nếu gọi nếu phản hồi là lỗi, vì đây là ví dụ trong câu trả lời này. Trong thử thách tôi đang sử dụng: this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "message", exception); Và, đây là câu trả lời chính xác nếu bạn hoàn toàn lo lắng về việc tôn trọng tiêu đề Chấp nhận của người gọi, mà không cần thêm shenanigans. (Và bạn đang sử dụng WebAPI)
JMD

2
@FlorinDumitrescu Quan điểm của ông là CHỈ này hoạt động khi bạn thừa kế ApiController. Nếu bạn chỉ thừa kế Controllerthay vào đó, nó không hoạt động và bạn phải tự tạo nó: HttpResponseMessage msg = new HttpResponseMessage(); msg.Content = new StringContent("hi"); msg.StatusCode = HttpStatusCode.OK;
vapcguy

64

Rõ ràng cách mới để làm điều đó được chi tiết ở đây:

http://aspnetwebstack.codeplex.com/discussions/350492

Để trích dẫn Henrik,

HttpResponseMessage response = new HttpResponseMessage();

response.Content = new ObjectContent<T>(T, myFormatter, "application/some-format");

Vì vậy, về cơ bản, người ta phải tạo ra một loại ObjectContent, dường như có thể được trả về dưới dạng một đối tượng HttpContent.


31
myFormatter là gì
Greg Z.

1
@ user1760329 nó sẽ là một new JsonMediaTypeFormatter();hoặc tương tự tùy thuộc vào định dạng của bạn
John

1
ObjectContentkhông được tìm thấy, sử dụng WCF
Medet Tleukabiluly

2
Tôi sẽ không coi đây là "cách mới để thực hiện" - bài viết mà bạn tham khảo liệt kê nó như một cách thay thế trong trường hợp bạn muốn có "quyền kiểm soát hoàn toàn định dạng [loại phương tiện] bạn muốn sử dụng"
Bern

Cảm ơn @praetor. Điều này thực sự hữu ích với tôi
Người dùng SO

53

Giải pháp đơn dòng đơn giản nhất là sử dụng

return new HttpResponseMessage( HttpStatusCode.OK ) {Content =  new StringContent( "Your message here" ) };

Đối với nội dung JSON được tuần tự hóa:

return new HttpResponseMessage( HttpStatusCode.OK ) {Content =  new StringContent( SerializedString, System.Text.Encoding.UTF8, "application/json" ) };

điều này không hiệu quả với tôi vì IHttpActionResult yêu cầu trả về loại FeedbackMessageResult. Xem câu trả lời của tôi dưới đây cho những gì tôi đã kết thúc với. Cũng lưu ý, tôi đã thực hiện yếu tố trong JsonContent của nashawn (như xuất phát từ lớp cơ sở StringContent).
Adam Cox

1
Chỉ cần bọc httpResponseMessage sau đó: trả về FeedbackMessageResult mới (trả về httpResponseMessage mới (HttpStatusCode.OK) {new StringContent ("Tin nhắn của bạn ở đây")}); :)
Simon Mattes

41

Đối với bất kỳ đối tượng T bạn có thể làm:

return Request.CreateResponse<T>(HttpStatusCode.OK, Tobject);

5
Ngoại trừ Requestchỉ có sẵn với một CreateResponsephương pháp nếu bạn đang kế thừa ApiController. Nó sẽ không hoạt động nếu sử dụng Controller.
vapcguy

15

Bạn có thể tạo các loại nội dung chuyên ngành của riêng bạn. Ví dụ: một cho nội dung Json và một cho nội dung Xml (sau đó chỉ cần gán chúng cho HttpResponseMessage.Content):

public class JsonContent : StringContent
{
    public JsonContent(string content)
        : this(content, Encoding.UTF8)
    {
    }

    public JsonContent(string content, Encoding encoding)
        : base(content, encoding, "application/json")
    {
    }
}

public class XmlContent : StringContent
{
    public XmlContent(string content) 
        : this(content, Encoding.UTF8)
    {
    }

    public XmlContent(string content, Encoding encoding)
        : base(content, encoding, "application/xml")
    {
    }
}

thực hiện rất gọn gàng và sạch sẽ.
Sam

3

Lấy cảm hứng từ câu trả lời của Simon Mattes, tôi cần phải đáp ứng IHttpActionResult loại trả về bắt buộc của FeedbackMessageResult. Cũng sử dụng JsonContent của nashawn, tôi đã kết thúc với ...

        return new System.Web.Http.Results.ResponseMessageResult(
            new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.OK)
            {
                Content = new JsonContent(JsonConvert.SerializeObject(contact, Formatting.Indented))
            });

Xem câu trả lời của nashawn cho JsonContent.


phép nội suy chuỗi có vẻ không cần thiết
Igor Pashchuk

0

Không có nghi ngờ rằng bạn là Florin chính xác. Tôi đã làm việc trong dự án này và thấy rằng đoạn mã này:

product = await response.Content.ReadAsAsync<Product>();

Có thể được thay thế bằng:

response.Content = new StringContent(string product);

1
Câu trả lời này dường như không liên quan đến câu hỏi và không chỉ ra cách đi từ một đối tượng (Sản phẩm) đến một chuỗi
mageos
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.