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.