Jak zwrócić surowy ciąg z ApiController?

125

Mam ApiController, który obsługuje XML / JSON, ale chciałbym, aby jedna z moich akcji zwróciła czysty HTML. Wypróbowałem poniższe, ale nadal zwraca XML / JSON.

public string Get()
{
    return "<strong>test</strong>";
}

Oto, co zwraca powyższe:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">&lt;strong&gt;test&lt;/strong&gt;</string>

Czy istnieje sposób na zwrócenie samego czystego tekstu bez zmiany znaczenia, nawet bez otaczających tagów XML (może być inny zwracany typ atrybutu akcji)?

TruMan1
źródło

Odpowiedzi:

223

Możesz sprawić, by akcja interfejsu API sieci Web zwracała wartość, w HttpResponseMessageprzypadku której masz pełną kontrolę nad zawartością. W twoim przypadku możesz użyć StringContent i określić poprawny typ zawartości:

public HttpResponseMessage Get()
{
    return new HttpResponseMessage()
    {
        Content = new StringContent(
            "<strong>test</strong>", 
            Encoding.UTF8, 
            "text/html"
        )
    };
}

lub

public IHttpActionResult Get()
{
    return base.ResponseMessage(new HttpResponseMessage()
    {
        Content = new StringContent(
            "<strong>test</strong>", 
            Encoding.UTF8, 
            "text/html"
        )
    });
}
Darin Dimitrov
źródło
Nie próbowałem jeszcze, ale zastanawiam się, czy ustawienie typu danych na html zadziała?
adt
5
Nie, to nie zadziała. Interfejs API sieci Web ma tylko wbudowane elementy formatujące XML i JSON. W przypadku wszystkiego innego będziesz musiał zbudować własny program formatujący lub zwrócić nieprzetworzone HttpResponseMessages ze swoich metod, jak pokazano w mojej odpowiedzi.
Darin Dimitrov
HttpResponseMessage znajduje się w przestrzeni nazw System.Net.Http.
James Lawruk
8

Inne możliwe rozwiązanie. W Web API 2 wykorzystałem metodę base.Content () APIController:

    public IHttpActionResult Post()
    {
        return base.Content(HttpStatusCode.OK, new {} , new JsonMediaTypeFormatter(), "text/plain");
    }

Musiałem to zrobić, aby ominąć błąd IE9, w którym ciągle próbowałem pobrać zawartość JSON. Powinno to również działać w przypadku danych typu XML przy użyciu programu XmlMediaTypeFormatterformatującego multimedia.

Mam nadzieję, że to komuś pomoże.

garryp
źródło
OP prosił o zwrócenie ciągu html .. gdzie jest taki ciąg? i w jaki sposób JsonMediaTypeFormatter może zwrócić html?
joedotnot
4

Po prostu return Ok(value)nie zadziała, będzie traktowane jako IEnumerable<char>.

Zamiast tego użyj return Ok(new { Value = value })lub simillar.

abatishchev
źródło
0

Wywołuję następującą metodę kontrolera webapi2 z metody kontrolera mvc:

<HttpPost>
Public Function TestApiCall(<FromBody> screenerRequest As JsonBaseContainer) As IHttpActionResult
    Dim response = Me.Request.CreateResponse(HttpStatusCode.OK)
    response.Content = New StringContent("{""foo"":""bar""}", Encoding.UTF8, "text/plain")
    Return ResponseMessage(response)
End Function

Wywołuję to z tej procedury na serwerze asp.net:

Public Async Function PostJsonContent(baseUri As String, requestUri As String, content As String, Optional timeout As Integer = 15, Optional failedResponse As String = "", Optional ignoreSslCertErrors As Boolean = False) As Task(Of String)
    Return Await PostJsonContent(baseUri, requestUri, New StringContent(content, Encoding.UTF8, "application/json"), timeout, failedResponse, ignoreSslCertErrors)
End Function

Public Async Function PostJsonContent(baseUri As String, requestUri As String, content As HttpContent, Optional timeout As Integer = 15, Optional failedResponse As String = "", Optional ignoreSslCertErrors As Boolean = False) As Task(Of String)
    Dim httpResponse As HttpResponseMessage

    Using handler = New WebRequestHandler
        If ignoreSslCertErrors Then
            handler.ServerCertificateValidationCallback = New Security.RemoteCertificateValidationCallback(Function(sender, cert, chain, policyErrors) True)
        End If

        Using client = New HttpClient(handler)
            If Not String.IsNullOrWhiteSpace(baseUri) Then
                client.BaseAddress = New Uri(baseUri)
            End If

            client.DefaultRequestHeaders.Accept.Clear()
            client.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
            client.Timeout = New TimeSpan(TimeSpan.FromSeconds(timeout).Ticks)

            httpResponse = Await client.PostAsync(requestUri, content)

            If httpResponse.IsSuccessStatusCode Then
                Dim response = Await httpResponse.Content.ReadAsStringAsync
                If Not String.IsNullOrWhiteSpace(response) Then
                    Return response
                End If
            End If
        End Using
    End Using

    Return failedResponse
End Function
Liam
źródło
0

Jeśli używasz MVC zamiast WebAPI, możesz użyć metody base.Content:

return base.Content(result, "text/html", Encoding.UTF8);
Kozacy
źródło
-2

Musimy starać się nie zwracać html, ale czyste dane z naszego API i odpowiednio sformatować dane w interfejsie użytkownika, ale może możesz użyć:

return this.Request.CreateResponse(HttpStatusCode.OK, 
     new{content=YourStringContent})

mi to pasuje

user1075679
źródło
6
Owinięcie czegoś w obiekt atrapy nie czyni go bardziej czystym. Jeśli HTML to Twoje dane, nie ma sensu go ukrywać.
Jouni Heikniemi
Ideą interfejsów API sieci Web jest zwrócenie danych i pozostawienie interfejsu użytkownika w celu dodania wymaganego kodu HTML, być może możemy mieć przypadki, w których dane są w formacie HTML, ale myślę, że nie jest to normą.
user1075679