นำเนื้อหาในวัตถุ HttpResponseMessage หรือไม่


180

เมื่อหลายเดือนก่อน Microsoft ตัดสินใจเปลี่ยนคลาส HttpResponseMessage ก่อนหน้านี้คุณสามารถส่งประเภทข้อมูลไปยังตัวสร้างจากนั้นส่งคืนข้อความด้วยข้อมูลนั้น แต่ไม่ใช่อีกต่อไป

ตอนนี้คุณต้องใช้คุณสมบัติเนื้อหาเพื่อตั้งค่าเนื้อหาของข้อความ ปัญหาคือมันเป็นประเภท HttpContent และฉันไม่สามารถหาวิธีแปลงสตริงได้เป็น HttpContent

ไม่มีใครรู้วิธีจัดการกับปัญหานี้หรือไม่? ขอบคุณมาก.

คำตอบ:


216

สำหรับสตริงโดยเฉพาะวิธีที่เร็วที่สุดคือการใช้ตัวสร้างStringContent

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

มีจำนวนของการสืบทอดคลาส HttpContentเพิ่มเติมสำหรับสถานการณ์ทั่วไปอื่น ๆ


ดูโพสต์ของฉันด้านล่างเพื่อสร้าง StringContent ประเภทของคุณเอง (เช่น JSON, XML เป็นต้น)
bytedev

135

คุณควรสร้างการตอบสนองโดยใช้Request.CreateResponse :

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

คุณสามารถส่งผ่านวัตถุไม่เพียง แต่สตริงไปยัง CreateResponse และมันจะทำให้เป็นอนุกรมโดยยึดตามส่วนหัว Accept ของคำขอ วิธีนี้ช่วยให้คุณไม่ต้องเลือกฟอร์แมตเตอร์ด้วยตนเอง


มันทำงานโดยอัตโนมัติกับประเภทเนื้อหาเพื่อให้คุณสามารถทำ xml / json โดยไม่ต้องมีรหัสเพิ่มเติม

ฉันคิดว่ามันจะถูกต้องมากขึ้นที่จะเรียกCreateErrorResponse()ถ้าการตอบสนองเป็นข้อผิดพลาดตามที่อยู่ในตัวอย่างของคำตอบนี้ ภายในลองของฉันฉันกำลังใช้: this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "message", exception); และนี่คือคำตอบที่ถูกต้องถ้าคุณกังวลเกี่ยวกับการยอมรับส่วนหัวยอมรับของผู้โทรโดยไม่ต้องมี shenanigans เพิ่มเติม (และคุณใช้ WebAPI)
JMD

2
@FlorinDumitrescu ประเด็นของเขาคือสิ่งนี้ใช้ได้เฉพาะเมื่อคุณรับช่วงApiControllerต่อ หากคุณเป็นเพียงการสืบทอดControllerแทนก็ไม่ได้ทำงานและคุณต้องสร้างมันด้วยตัวเอง: HttpResponseMessage msg = new HttpResponseMessage(); msg.Content = new StringContent("hi"); msg.StatusCode = HttpStatusCode.OK;
vapcguy

64

เห็นได้ชัดว่าวิธีใหม่ในการทำมีรายละเอียดอยู่ที่นี่:

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

หากต้องการอ้างอิง Henrik

HttpResponseMessage response = new HttpResponseMessage();

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

ดังนั้นโดยทั่วไปเราจะต้องสร้างประเภท ObjectContent ซึ่งเห็นได้ชัดว่าสามารถส่งคืนเป็นวัตถุ HttpContent


31
myFormatter คืออะไร
Greg Z.

1
@ user1760329 มันจะเป็นnew JsonMediaTypeFormatter();หรือคล้ายกันขึ้นอยู่กับรูปแบบของคุณ
John

1
ObjectContentไม่พบใช้ WCF
Medet Tleukabiluly

2
ฉันจะไม่ถือว่าคุณสมบัตินี้เป็น "วิธีการใหม่ในการทำ" - บทความที่คุณอ้างอิงระบุว่าเป็นทางเลือกในกรณีที่คุณต้องการ "ควบคุมฟอร์แมต [สื่อประเภท] ที่คุณต้องการใช้"
เบิร์น

ขอบคุณ @praetor สิ่งนี้มีประโยชน์กับฉันจริงๆ
ผู้ใช้ SO

53

วิธีแก้ปัญหาแบบบรรทัดเดียวที่ง่ายที่สุดคือการใช้

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

สำหรับเนื้อหา JSON ต่อเนื่อง:

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

สิ่งนี้ไม่ได้ผลสำหรับฉันเพราะ IHttpActionResult ต้องการประเภทการคืนของ ResponseMessageResult ดูคำตอบของฉันด้านล่างสำหรับสิ่งที่ฉันลงเอยด้วย โปรดทราบว่าฉันได้คำนึงถึง JsonContent ของ nashawn (ซึ่งได้มาจากคลาสฐานของ StringContent)
Adam Cox

1
เพียงแค่ใส่ HttpResponseMessage จากนั้นส่งคืน ResponseMessageResult ใหม่ (คืน HttpResponseMessage ใหม่ (HttpStatusCode.OK) {StringContent ใหม่ ("ข้อความของคุณที่นี่")}); :)
Simon Mattes

41

สำหรับวัตถุ T ใด ๆ ที่คุณสามารถทำได้:

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

5
ยกเว้นRequestจะใช้ได้เฉพาะกับวิธีการถ้าคุณกำลังสืบทอดCreateResponse มันจะไม่ทำงานถ้าใช้ApiController Controller
vapcguy

15

คุณสามารถสร้างประเภทเนื้อหาพิเศษของคุณเอง ตัวอย่างหนึ่งสำหรับเนื้อหา Json และอีกหนึ่งสำหรับเนื้อหา Xml (จากนั้นกำหนดให้ 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")
    {
    }
}

การดำเนินการที่เป็นระเบียบและสะอาดมาก
Sam

3

แรงบันดาลใจจากคำตอบของ Simon Mattes ฉันต้องการตอบสนอง IHttpActionResult ที่ต้องการประเภท Return ของ ResponseMessageResult นอกจากนี้ยังใช้ JsonContent ของ nashawn ฉันลงเอยด้วย ...

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

ดูคำตอบของ nashawn สำหรับ JsonContent


สตริงแก้ไขดูเหมือนไม่จำเป็น
อิกอร์ Pashchuk

0

ไม่ต้องสงสัยเลยว่าคุณถูก Florin ฉันกำลังทำงานในโครงการนี้และพบว่ารหัสนี้:

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

สามารถแทนที่ด้วย:

response.Content = new StringContent(string product);

1
คำตอบนี้ดูเหมือนจะไม่เกี่ยวข้องกับคำถามและไม่แสดงว่าจะไปจากวัตถุ (ผลิตภัณฑ์) ไปยังสตริงได้อย่างไร
mageos
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.