¿Cómo devolver una cadena sin procesar con ApiController?

125

Tengo un ApiController que sirve XML / JSON, pero me gustaría que una de mis acciones devuelva HTML puro. Intenté lo siguiente pero aún devuelve XML / JSON.

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

Esto es lo que devuelve lo anterior:

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

¿Hay alguna manera de devolver solo el texto puro y sin escape sin siquiera las etiquetas XML circundantes (tal vez un tipo de atributo de acción de retorno diferente)?

TruMan1
fuente

Respuestas:

223

Puede hacer que su acción de API web devuelva una HttpResponseMessagepara la cual tiene control total sobre el Contenido. En su caso, puede usar un StringContent y especificar el tipo de contenido correcto:

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

o

public IHttpActionResult Get()
{
    return base.ResponseMessage(new HttpResponseMessage()
    {
        Content = new StringContent(
            "<strong>test</strong>", 
            Encoding.UTF8, 
            "text/html"
        )
    });
}
Darin Dimitrov
fuente
Todavía no lo he intentado, pero me pregunto si funcionaría el tipo de datos en html.
adt
55
No, no funcionará. La API web solo tiene formateadores XML y JSON integrados. Para todo lo demás, tendrá que construir su propio formateador o devolver mensajes HttpResponseMessage sin procesar de sus métodos, como se muestra en mi respuesta.
Darin Dimitrov
HttpResponseMessage se encuentra en el espacio de nombres System.Net.Http.
James Lawruk
8

Otra posible solución. En Web API 2 utilicé el método base.Content () de APIController:

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

Necesitaba hacer esto para evitar un error de IE9 en el que seguía intentando descargar contenido JSON. Esto también debería funcionar para datos de tipo XML utilizando el XmlMediaTypeFormatterformateador de medios.

Espero que ayude a alguien.

Garryp
fuente
el OP estaba pidiendo devolver una cadena html ... ¿dónde está esa cadena? y ¿cómo puede JsonMediaTypeFormatter devolver html?
joedotnot
4

Simplemente return Ok(value)no funcionará, será tratado como IEnumerable<char>.

En su lugar, use return Ok(new { Value = value })o simillar.

abatishchev
fuente
0

Llamo al siguiente método de controlador webapi2 desde un método de controlador 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

Lo llamo desde esta rutina en el servidor 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
fuente
0

Si está utilizando MVC en lugar de WebAPI, puede utilizar la base. Método de contenido:

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

Debemos esforzarnos por no devolver html sino datos puros de nuestras API y formatear los datos en consecuencia en la interfaz de usuario, pero tal vez pueda usar:

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

esto funciona para mi

usuario1075679
fuente
66
Envolver algo en un objeto ficticio no lo hace más puro. Si el HTML es su información, no tiene sentido ocultarlo.
Jouni Heikniemi
La idea de la API web es devolver datos y dejar la interfaz de usuario para agregar el HTML requerido, tal vez podamos tener algunos casos en los que los datos sean HTML, pero creo que esa no es la norma.
user1075679