Inserisci contenuto nell'oggetto HttpResponseMessage?


180

Diversi mesi fa, Microsoft ha deciso di modificare la classe HttpResponseMessage. Prima, potevi semplicemente passare un tipo di dati nel costruttore e quindi restituire il messaggio con quei dati, ma non più.

Ora, è necessario utilizzare la proprietà Content per impostare il contenuto del messaggio. Il problema è che è di tipo HttpContent e non riesco a trovare un modo per convertire una stringa, ad esempio in HttpContent.

Qualcuno sa come affrontare questo problema? Molte grazie.

Risposte:


216

Per una stringa in particolare, il modo più veloce è usare il costruttore StringContent

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

Esistono numerosi discendenti di classe HttpContent aggiuntivi per altri scenari comuni.


Vedi il mio post qui sotto per creare i tuoi tipi derivati ​​di StringContent (ad es. JSON, XML ecc.).
bytedev,

135

È necessario creare la risposta utilizzando Request.CreateResponse :

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

È possibile passare oggetti non solo stringhe a CreateResponse e li serializzerà in base all'intestazione Accept della richiesta. Questo ti evita di scegliere manualmente un formattatore.


Funziona automaticamente con i tipi di contenuto in modo da poter fare xml / json senza codice aggiuntivo

Penso che sarebbe più corretto chiamare CreateErrorResponse()se la risposta è un errore, come è nell'esempio di questa risposta. All'interno del mio try-catch sto usando: this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "message", exception); E, questa è la risposta corretta se sei affatto preoccupato di rispettare l'intestazione Accept del chiamante, senza shenanigans extra. (E stai usando WebAPI)
JMD

2
@FlorinDumitrescu Il suo punto era che questo funziona SOLO per quando erediti ApiController. Se invece stai solo ereditando Controller, non funziona e devi crearlo tu stesso: HttpResponseMessage msg = new HttpResponseMessage(); msg.Content = new StringContent("hi"); msg.StatusCode = HttpStatusCode.OK;
vapcguy,

64

Apparentemente il nuovo modo di farlo è dettagliato qui:

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

Per citare Henrik,

HttpResponseMessage response = new HttpResponseMessage();

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

Quindi, in sostanza, si deve creare un tipo ObjectContent, che apparentemente può essere restituito come oggetto HttpContent.


31
cos'è myFormatter
Greg Z.

1
@ user1760329 sarebbe un new JsonMediaTypeFormatter();o simile a seconda del formato
John

1
ObjectContentnon viene trovato, utilizzando WCF
Medet Tleukabiluly il

2
Non lo definirei il "nuovo modo di farlo" - quell'articolo a cui fai riferimento lo elenca come un'alternativa nel caso in cui tu voglia avere "il controllo completo del formatter [tipo di media] che vuoi usare"
Berna

Grazie @praetor. Questo è stato davvero utile per me
SO User, il

53

La soluzione a linea singola più semplice è quella di utilizzare

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

Per contenuti JSON serializzati:

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

questo non ha funzionato per me perché IHttpActionResult richiede il tipo restituito di ResponseMessageResult. Vedi la mia risposta qui sotto per quello che ho finito. Inoltre, ho tenuto conto del JsonContent di nashawn (derivato dalla classe base StringContent).
Adam Cox,

1
Basta avvolgere HttpResponseMessage quindi: return new ResponseMessageResult (return new HttpResponseMessage (HttpStatusCode.OK) {new StringContent ("Your message here")}); :)
Simon Mattes,

41

Per qualsiasi oggetto T puoi fare:

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

5
Tranne Requestè disponibile solo con un CreateResponsemetodo se si sta ereditando ApiController. Non funzionerà se si utilizza Controller.
vapcguy,

15

Puoi creare i tuoi tipi di contenuti specializzati. Ad esempio uno per il contenuto Json e uno per il contenuto Xml (quindi assegnarli a 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")
    {
    }
}

implementazione molto ordinata e pulita.
Sam,

3

Ispirato dalla risposta di Simon Mattes, dovevo soddisfare IHttpActionResult che richiedeva il tipo di restituzione di ResponseMessageResult. Usando anche JsonContent di nashawn, ho finito con ...

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

Vedi la risposta di nashawn per JsonContent.


l'interpolazione delle stringhe sembra superflua
Igor Pashchuk,

0

Non c'è dubbio che hai ragione Fiorino. Stavo lavorando a questo progetto e ho scoperto che questo pezzo di codice:

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

Potrebbe essere sostituito con:

response.Content = new StringContent(string product);

1
Questa risposta non sembra rilevante per la domanda e non mostra come passare da un oggetto (prodotto) a una stringa
mageos
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.