Masukkan konten ke dalam objek HttpResponseMessage?

180

Beberapa bulan yang lalu, Microsoft memutuskan untuk mengubah kelas HttpResponseMessage. Sebelumnya, Anda bisa meneruskan tipe data ke konstruktor, dan kemudian mengembalikan pesan dengan data itu, tetapi tidak lagi.

Sekarang, Anda perlu menggunakan properti Konten untuk mengatur konten pesan. Masalahnya adalah bahwa itu adalah tipe HttpContent, dan sepertinya saya tidak dapat menemukan cara untuk mengkonversi string, misalnya, ke HttpContent.

Adakah yang tahu bagaimana menangani masalah ini? Terima kasih banyak.

praetor
sumber

Jawaban:

216

Khusus untuk string, cara tercepat adalah menggunakan konstruktor StringContent

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

Ada sejumlah keturunan kelas HttpContent tambahan untuk skenario umum lainnya.

Jim O'Neil
sumber
Lihat posting saya di bawah ini untuk membuat tipe StringContent turunan Anda sendiri (mis. JSON, XML dll.).
bytedev
135

Anda harus membuat respons menggunakan Request.CreateResponse :

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

Anda dapat mengirimkan objek bukan hanya string ke CreateResponse dan itu akan membuat cerita bersambung berdasarkan pada header Terima permintaan. Ini menyelamatkan Anda dari memilih formatter secara manual.

Florin Dumitrescu
sumber
Secara otomatis bekerja dengan jenis konten sehingga Anda dapat melakukan xml / json tanpa kode tambahan
Saya pikir akan lebih tepat untuk menelepon CreateErrorResponse()jika responsnya adalah kesalahan, seperti dalam contoh jawaban ini. Di dalam try-catch saya, saya menggunakan: this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "message", exception); Dan, ini adalah jawaban yang benar jika Anda sama sekali khawatir tentang menghormati header Terima penelepon, tanpa shenanigans tambahan (dan Anda menggunakan WebAPI)
JMD
2
@FlorinDumitrescu Maksudnya adalah HANYA ini bekerja ketika Anda mewarisi ApiController. Jika Anda hanya mewarisi Controller, itu tidak bekerja, dan Anda harus membuatnya sendiri: HttpResponseMessage msg = new HttpResponseMessage(); msg.Content = new StringContent("hi"); msg.StatusCode = HttpStatusCode.OK;
vapcguy
64

Tampaknya cara baru untuk melakukannya dirinci di sini:

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

Mengutip Henrik,

HttpResponseMessage response = new HttpResponseMessage();

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

Jadi pada dasarnya, kita harus membuat tipe ObjectContent, yang tampaknya dapat dikembalikan sebagai objek HttpContent.

praetor
sumber
31
apa itu myFormatter
Greg Z.
1
@ user1760329 akan menjadi new JsonMediaTypeFormatter();atau serupa tergantung pada format Anda
John
1
ObjectContenttidak ditemukan, menggunakan WCF
Medet Tleukabiluly
2
Saya tidak akan menganggap ini sebagai "cara baru untuk melakukannya" - artikel yang Anda referensi mencantumkannya sebagai alternatif jika Anda ingin memiliki "kendali penuh atas formatter [tipe media] yang ingin Anda gunakan"
Bern
Terima kasih @praetor. Ini sangat membantu saya
SO Pengguna
53

Solusi single-line termudah adalah menggunakan

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

Untuk konten JSON bersambung:

return new HttpResponseMessage( HttpStatusCode.OK ) {Content =  new StringContent( SerializedString, System.Text.Encoding.UTF8, "application/json" ) };
Simon Mattes
sumber
ini tidak berhasil untuk saya karena IHttpActionResult memerlukan jenis returnMessageResult. Lihat jawaban saya di bawah untuk apa yang akhirnya saya dapatkan. Juga perhatikan, saya melakukan faktor dalam Jashontent nashawn (seperti yang diturunkan dari kelas dasar StringContent).
Adam Cox
1
Cukup bungkus HttpResponseMessage lalu: kembalikan ResponseMessageResult baru (kembalikan HttpResponseMessage (HttpStatusCode.OK) baru {new StringContent ("Pesan Anda di sini")}); :)
Simon Mattes
41

Untuk objek T apa pun yang dapat Anda lakukan:

return Request.CreateResponse<T>(HttpStatusCode.OK, Tobject);
ScubaSteve
sumber
5
Kecuali Requesthanya tersedia dengan CreateResponsemetode jika Anda mewarisi ApiController. Ini tidak akan berfungsi jika menggunakan Controller.
vapcguy
15

Anda dapat membuat jenis konten khusus Anda sendiri. Misalnya satu untuk konten Json dan satu untuk konten Xml (kemudian cukup tetapkan ke 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")
    {
    }
}
bytedev
sumber
implementasi sangat rapi dan bersih.
Sam
3

Terinspirasi oleh jawaban Simon Mattes, saya harus memuaskan IHttpActionResult yang diperlukan untuk mengembalikan tipe ResponseMessageResult. Juga menggunakan JsonContent nashawn, saya berakhir dengan ...

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

Lihat jawaban nashawn untuk JsonContent.

Adam Cox
sumber
interpolasi string tampaknya tidak perlu
Igor Pashchuk
0

Tidak diragukan lagi, Anda benar, Florin. Saya sedang mengerjakan proyek ini, dan menemukan bahwa ini sepotong kode:

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

Bisa diganti dengan:

response.Content = new StringContent(string product);
Steven WH
sumber
1
Jawaban ini tampaknya tidak relevan dengan pertanyaan dan tidak menunjukkan bagaimana cara beralih dari objek (Produk) ke string
mageos