Inhalt in HttpResponseMessage-Objekt einfügen?

180

Vor einigen Monaten hat Microsoft beschlossen, die HttpResponseMessage-Klasse zu ändern. Zuvor konnten Sie einfach einen Datentyp an den Konstruktor übergeben und dann die Nachricht mit diesen Daten zurückgeben, jedoch nicht mehr.

Jetzt müssen Sie die Content-Eigenschaft verwenden, um den Inhalt der Nachricht festzulegen. Das Problem ist, dass es vom Typ HttpContent ist und ich anscheinend keine Möglichkeit finde, eine Zeichenfolge beispielsweise in HttpContent zu konvertieren.

Weiß jemand, wie man mit diesem Problem umgeht? Vielen Dank.

Prätor
quelle

Antworten:

216

Für einen String ist es am schnellsten, den StringContent- Konstruktor zu verwenden

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

Für andere gängige Szenarien gibt es eine Reihe zusätzlicher Nachkommen der HttpContent-Klasse .

Jim O'Neil
quelle
In meinem Beitrag unten finden Sie Informationen zum Erstellen eigener abgeleiteter StringContent-Typen (z. B. JSON, XML usw.).
Bytedev
133

Sie sollten die Antwort mit Request.CreateResponse erstellen :

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

Sie können Objekte nicht nur Zeichenfolgen an CreateResponse übergeben und diese basierend auf dem Accept-Header der Anforderung serialisieren. Dies erspart Ihnen die manuelle Auswahl eines Formatierers.

Florin Dumitrescu
quelle
Es funktioniert automatisch mit den Inhaltstypen, so dass Sie xml / json ohne zusätzlichen Code
Ich denke, es wäre richtiger anzurufen, CreateErrorResponse()wenn die Antwort ein Fehler ist, wie im Beispiel dieser Antwort. In meinem Try-Catch verwende ich: this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "message", exception); Und dies ist die richtige Antwort, wenn Sie überhaupt Bedenken haben, den Accept-Header des Anrufers ohne zusätzliche Spielereien zu respektieren (und Sie verwenden WebAPI)
JMD
2
@FlorinDumitrescu Sein Punkt war, dass dies NUR funktioniert, wenn Sie erben ApiController. Wenn Sie Controllerstattdessen nur erben , funktioniert es nicht und Sie müssen es selbst erstellen: HttpResponseMessage msg = new HttpResponseMessage(); msg.Content = new StringContent("hi"); msg.StatusCode = HttpStatusCode.OK;
vapcguy
64

Anscheinend ist der neue Weg dazu hier detailliert beschrieben:

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

Um Henrik zu zitieren:

HttpResponseMessage response = new HttpResponseMessage();

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

Grundsätzlich muss also ein ObjectContent-Typ erstellt werden, der anscheinend als HttpContent-Objekt zurückgegeben werden kann.

Prätor
quelle
30
Was ist myFormatter
Greg Z.
1
@ user1760329 es wäre ein new JsonMediaTypeFormatter();oder ähnliches abhängig von Ihrem Format
John
1
ObjectContentwird nicht gefunden, mit WCF
Medet Tleukabiluly
2
Ich würde dies nicht als "neue Methode" bezeichnen - dieser Artikel, auf den Sie verweisen, listet ihn als Alternative für den Fall auf, dass Sie "die vollständige Kontrolle über den [Medientyp] -Formatierer haben möchten, den Sie verwenden möchten"
Bern
Danke @praetor. Dies war wirklich hilfreich für mich
SO Benutzer
52

Die einfachste einzeilige Lösung ist die Verwendung

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

Für serialisierten JSON-Inhalt:

return new HttpResponseMessage( HttpStatusCode.OK ) {Content =  new StringContent( SerializedString, System.Text.Encoding.UTF8, "application/json" ) };
Simon Mattes
quelle
Dies hat bei mir nicht funktioniert, da für IHttpActionResult der Rückgabetyp ResponseMessageResult erforderlich ist. Siehe meine Antwort unten für das, was ich am Ende hatte. Beachten Sie auch, dass ich den JsonContent von nashawn (abgeleitet von der StringContent-Basisklasse) berücksichtigt habe.
Adam Cox
1
Wickeln Sie einfach die HttpResponseMessage ein und geben Sie dann Folgendes zurück: return new ResponseMessageResult (return new HttpResponseMessage (HttpStatusCode.OK) {new StringContent ("Ihre Nachricht hier")}); :)
Simon Mattes
41

Für jedes T-Objekt können Sie Folgendes tun:

return Request.CreateResponse<T>(HttpStatusCode.OK, Tobject);
ScubaSteve
quelle
5
Except Requestist nur mit einer CreateResponseMethode verfügbar , wenn Sie erben ApiController. Es wird nicht funktionieren, wenn mit Controller.
Vapcguy
15

Sie können Ihre eigenen speziellen Inhaltstypen erstellen. Zum Beispiel eine für Json-Inhalte und eine für XML-Inhalte (weisen Sie sie dann einfach dem HttpResponseMessage.Content zu):

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
quelle
sehr ordentliche und saubere Umsetzung.
Sam
3

Inspiriert von der Antwort von Simon Mattes musste ich den von IHttpActionResult geforderten Rückgabetyp ResponseMessageResult erfüllen. Ich habe auch den JsonContent von nashawn verwendet und ...

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

Siehe Nashawns Antwort für JsonContent.

Adam Cox
quelle
String-Interpolation scheint unnötig
Igor Pashchuk
0

Kein Zweifel, dass Sie richtig Florin sind. Ich habe an diesem Projekt gearbeitet und festgestellt, dass dieser Code:

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

Könnte ersetzt werden durch:

response.Content = new StringContent(string product);
Steven WH
quelle
1
Diese Antwort scheint für die Frage nicht relevant zu sein und zeigt nicht, wie man von einem Objekt (Produkt) zu einem String wechselt
Magier