Wie kann ich mit ApiController einen rohen String zurückgeben?

125

Ich habe einen ApiController, der XML / JSON bereitstellt, möchte jedoch, dass eine meiner Aktionen reines HTML zurückgibt. Ich habe das Folgende versucht, aber es gibt immer noch XML / JSON zurück.

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

Dies ist, was das Obige zurückgibt:

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

Gibt es eine Möglichkeit, nur den reinen, nicht entkappten Text ohne die umgebenden XML-Tags zurückzugeben (möglicherweise ein anderes Rückgabetyp-Aktionsattribut)?

TruMan1
quelle

Antworten:

223

Sie können Ihre Web-API-Aktion zurückgeben lassen, HttpResponseMessagefür die Sie die volle Kontrolle über den Inhalt haben. In Ihrem Fall können Sie einen StringContent verwenden und den richtigen Inhaltstyp angeben:

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

oder

public IHttpActionResult Get()
{
    return base.ResponseMessage(new HttpResponseMessage()
    {
        Content = new StringContent(
            "<strong>test</strong>", 
            Encoding.UTF8, 
            "text/html"
        )
    });
}
Darin Dimitrov
quelle
Ich habe es noch nicht versucht, aber ich frage mich, ob ich den Datentyp auf HTML setzen würde.
adt
5
Nein, es wird nicht funktionieren. In der Web-API sind nur XML- und JSON-Formatierer integriert. Für alles andere müssen Sie Ihren eigenen Formatierer erstellen oder rohe HttpResponseMessages von Ihren Methoden zurückgeben, wie in meiner Antwort gezeigt.
Darin Dimitrov
HttpResponseMessage befindet sich im System.Net.Http-Namespace.
James Lawruk
8

Eine andere mögliche Lösung. In der Web-API 2 habe ich die base.Content () -Methode verwendet von APIController:

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

Ich musste dies tun, um einen IE9-Fehler zu umgehen, bei dem immer wieder versucht wurde, JSON-Inhalte herunterzuladen. Dies sollte auch für XML-Daten mithilfe des XmlMediaTypeFormatterMedienformatierers funktionieren.

Hoffe das hilft jemandem.

garryp
quelle
Das OP bat um die Rückgabe einer HTML-Zeichenfolge. Wo ist eine solche Zeichenfolge? und wie kann JsonMediaTypeFormatter HTML zurückgeben?
Joedotnot
4

Funktioniert einfach return Ok(value)nicht, es wird behandelt als IEnumerable<char>.

Verwenden return Ok(new { Value = value })Sie stattdessen oder ähnlich.

abatishchev
quelle
0

Ich rufe die folgende webapi2-Controller-Methode von einer mvc-Controller-Methode auf:

<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

Ich rufe es von dieser Routine auf dem asp.net-Server auf:

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
quelle
0

Wenn Sie MVC anstelle von WebAPI verwenden, können Sie die base.Content-Methode verwenden:

return base.Content(result, "text/html", Encoding.UTF8);
Cossens
quelle
-2

Wir müssen uns bemühen, nicht HTML, sondern reine Daten von unseren APIs zurückzugeben und Daten in der Benutzeroberfläche entsprechend zu formatieren, aber vielleicht können Sie Folgendes verwenden:

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

Für mich geht das

user1075679
quelle
6
Das Einwickeln von etwas in ein Dummy-Objekt macht es nicht reiner. Wenn die HTML ist Ihre Daten, gibt es keinen Sinn , es zu verbergen.
Jouni Heikniemi
Die Idee von Web-APIs ist es, Daten zurückzugeben und die Benutzeroberfläche zu verlassen, um das erforderliche HTML hinzuzufügen. Vielleicht können wir einige Fälle haben, in denen die Daten HTML sind, aber ich denke, das ist nicht die Norm.
user1075679