Umieścić zawartość w obiekcie HttpResponseMessage?


180

Kilka miesięcy temu Microsoft zdecydował się zmienić klasę HttpResponseMessage. Wcześniej można było po prostu przekazać typ danych do konstruktora, a następnie zwrócić komunikat z tymi danymi, ale już nie.

Teraz musisz użyć właściwości Content, aby ustawić treść wiadomości. Problem polega na tym, że jest to typ HttpContent i nie mogę znaleźć sposobu na przekonwertowanie ciągu, na przykład, na HttpContent.

Czy ktoś wie, jak sobie z tym poradzić? Wielkie dzięki.

Odpowiedzi:


216

W szczególności w przypadku ciągu znaków najszybszym sposobem jest użycie konstruktora StringContent

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

Istnieje wiele dodatkowych potomków klasy HttpContent dla innych typowych scenariuszy.


Zobacz mój post poniżej, aby utworzyć własne pochodne typy StringContent (np. JSON, XML itp.).
bytedev

135

Powinieneś utworzyć odpowiedź za pomocą Request.CreateResponse :

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

Możesz przekazywać obiekty, a nie tylko ciągi znaków, do CreateResponse i serializuje je na podstawie nagłówka Accept żądania. Dzięki temu nie musisz ręcznie wybierać programu formatującego.


Automatycznie działa z typami zawartości, więc możesz zrobić xml / json bez dodatkowego kodu

Myślę, że bardziej poprawne byłoby wywołanie, CreateErrorResponse()jeśli odpowiedź jest błędem, tak jak w przykładzie tej odpowiedzi. Wewnątrz mojego haczyka, którego używam: this.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "message", exception); I to jest poprawna odpowiedź, jeśli w ogóle martwisz się o uszanowanie nagłówka Accept dzwoniącego, bez dodatkowych szyderstw. (I używasz WebAPI)
JMD

2
@FlorinDumitrescu Chodziło mu o to, że działa to TYLKO w przypadku dziedziczenia ApiController. Jeśli Controllerzamiast tego dziedziczysz tylko dziedziczenie , to nie działa i musisz to stworzyć samodzielnie: HttpResponseMessage msg = new HttpResponseMessage(); msg.Content = new StringContent("hi"); msg.StatusCode = HttpStatusCode.OK;
vapcguy

64

Najwyraźniej nowy sposób, aby to zrobić, jest szczegółowo opisany tutaj:

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

Cytując Henrika,

HttpResponseMessage response = new HttpResponseMessage();

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

Zasadniczo należy więc utworzyć typ ObjectContent, który najwyraźniej może zostać zwrócony jako obiekt HttpContent.


31
co to jest myFormatter
Greg Z.

1
@ user1760329 będzie to new JsonMediaTypeFormatter();lub podobne, w zależności od formatu
Jan

1
ObjectContentnie został znaleziony, używając WCF
Medet Tleukabiluly

2
Nie zakwalifikowałbym tego jako „nowego sposobu na zrobienie tego” - ten artykuł, do którego się odnosisz, wymienia go jako alternatywę w przypadku, gdy chcesz mieć „pełną kontrolę nad formatowaniem [typu nośnika], którego chcesz używać”
Bern

Dzięki @praetor. To było dla mnie bardzo pomocne
SO User

53

Najłatwiejszym w użyciu rozwiązaniem jednokreskowym

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

W przypadku serializowanej zawartości JSON:

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

to nie zadziałało, ponieważ IHttpActionResult wymaga zwracanego typu ResponseMessageResult. Zobacz moją odpowiedź poniżej, na co skończyłem. Zwróć także uwagę, że uwzględniłem JsonContent nashawn (jako wyprowadzony z klasy bazowej StringContent).
Adam Cox

1
Po prostu zawiń HttpResponseMessage, a następnie: return new ResponseMessageResult (return new HttpResponseMessage (HttpStatusCode.OK) {new StringContent ("Twoja wiadomość tutaj")}); :)
Simon Mattes

41

Dla dowolnego obiektu T możesz:

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

5
Z wyjątkiem Requestjest dostępna tylko w przypadku CreateResponsemetody, jeśli dziedziczenie ApiController. Nie będzie działać, jeśli używasz Controller.
vapcguy

15

Możesz tworzyć własne wyspecjalizowane typy treści. Na przykład jeden dla zawartości Json i jeden dla zawartości XML (a następnie przypisz je do 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")
    {
    }
}

bardzo zadbane i czyste wykonanie.
Sam

3

Zainspirowany odpowiedzią Simona Mattesa, musiałem spełnić wymagany przez IHttpActionResult typ zwrotu ResponseMessageResult. Używając również JsonContent nashawn, skończyło się na ...

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

Zobacz odpowiedź nashawn na JsonContent.


interpolacja strun wydaje się niepotrzebna
Igor Pashchuk

0

Nie ma wątpliwości, że masz rację Florin. Pracowałem nad tym projektem i stwierdziłem, że ten fragment kodu:

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

Można zastąpić:

response.Content = new StringContent(string product);

1
Ta odpowiedź nie wydaje się być odpowiednia dla pytania i nie pokazuje, jak przejść od przedmiotu (produktu) do sznurka
mageos
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.