Como retornar uma string não processada com o ApiController?

125

Eu tenho um ApiController que serve XML / JSON, mas gostaria que uma de minhas ações retornasse HTML puro. Eu tentei o abaixo, mas ele ainda retorna XML / JSON.

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

É isso que o retorno acima:

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

Existe uma maneira de retornar apenas o texto puro e sem escape, mesmo sem as tags XML ao redor (talvez um tipo de retorno diferente do atributo de ação)?

TruMan1
fonte

Respostas:

223

Você pode fazer com que sua ação da API da Web retorne uma HttpResponseMessagepara a qual você tem controle total sobre o Conteúdo. No seu caso, você pode usar um StringContent e especificar o tipo de conteúdo correto:

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

ou

public IHttpActionResult Get()
{
    return base.ResponseMessage(new HttpResponseMessage()
    {
        Content = new StringContent(
            "<strong>test</strong>", 
            Encoding.UTF8, 
            "text/html"
        )
    });
}
Darin Dimitrov
fonte
Eu ainda não tentei, mas gostaria de saber se eu definiria o tipo de dados para html funcionaria?
ADT
5
Não, não vai funcionar. A API da Web possui apenas formatadores XML e JSON internos. Para todo o resto, você precisará criar seu próprio formatador ou retornar HttpResponseMessages a partir de seus métodos, conforme mostrado na minha resposta.
precisa
HttpResponseMessage está localizado no espaço para nome System.Net.Http.
precisa saber é o seguinte
8

Outra solução possível. Na API da Web 2, usei o método base.Content () de APIController:

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

Eu precisava fazer isso para solucionar um bug do IE9, onde ele continuava tentando baixar o conteúdo JSON. Isso também deve funcionar para dados do tipo XML usando o XmlMediaTypeFormatterformatador de mídia.

Espero que ajude alguém.

garryp
fonte
o OP estava pedindo o retorno de uma string html .. onde está essa string? e como JsonMediaTypeFormatter pode retornar html?
joedotnot
4

return Ok(value)não vai funcionar, será tratado como IEnumerable<char>.

Em vez disso, use return Ok(new { Value = value })ou similar.

abatishchev
fonte
0

Eu chamo o seguinte método do controlador webapi2 a partir de um método do 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

Eu chamo isso dessa rotina no 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
fonte
0

Se você estiver usando MVC em vez de WebAPI, poderá usar o método base.Content:

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

Devemos nos esforçar para não retornar html, mas dados puros das nossas APIs e formatar os dados adequadamente na interface do usuário, mas talvez você possa usar:

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

funciona para mim

user1075679
fonte
6
Enrolar algo em um objeto fictício não o torna mais puro. Se o HTML são seus dados, não faz sentido ocultá-los.
Jouni Heikniemi 18/03/2014
A idéia das APIs da web é retornar dados e deixar a interface do usuário para adicionar o HTML necessário, talvez possamos ter alguns casos em que os dados são HTML, mas acho que essa não é a norma.
usar o seguinte comando