Comment retourner une chaîne brute avec ApiController?

125

J'ai un ApiController qui sert XML / JSON, mais j'aimerais que l'une de mes actions renvoie du HTML pur. J'ai essayé ce qui suit mais il renvoie toujours XML / JSON.

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

Voici ce que renvoie ce qui précède:

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

Existe-t-il un moyen de renvoyer uniquement le texte pur et sans échappement sans même les balises XML environnantes (peut-être un type d'attribut d'action de retour différent)?

TruMan1
la source

Réponses:

223

Votre action Web Api peut renvoyer une action HttpResponseMessagepour laquelle vous avez un contrôle total sur le contenu. Dans votre cas, vous pouvez utiliser un StringContent et spécifier le type de contenu correct:

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
la source
Je n'ai pas encore essayé, mais je me demande si je définirais le type de données en HTML fonctionnerait?
Annonce du
5
Non, cela ne fonctionnera pas. L'API Web a uniquement des formateurs XML et JSON intégrés. Pour tout le reste, vous devrez créer votre propre formateur ou renvoyer des HttpResponseMessages bruts à partir de vos méthodes, comme indiqué dans ma réponse.
Darin Dimitrov du
HttpResponseMessage se trouve dans l'espace de noms System.Net.Http.
James Lawruk
8

Une autre solution possible. Dans Web API 2, j'ai utilisé la méthode base.Content () de APIController:

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

J'avais besoin de faire cela pour contourner un bogue IE9 où il essayait de télécharger du contenu JSON. Cela devrait également fonctionner pour les données de type XML à l'aide du XmlMediaTypeFormatterformateur multimédia.

J'espère que cela aide quelqu'un.

Garryp
la source
l'OP demandait de retourner une chaîne html .. où est une telle chaîne? et comment JsonMediaTypeFormatter peut-il renvoyer du HTML?
joedotnot le
4

Juste return Ok(value)ne fonctionnera pas, il sera traité comme IEnumerable<char>.

Utilisez plutôt return Ok(new { Value = value })ou simillar.

abatishchev
la source
0

J'appelle la méthode de contrôleur webapi2 suivante à partir d'une méthode de contrôleur 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

Je l'appelle à partir de cette routine sur le serveur 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
la source
0

Si vous utilisez MVC plutôt que WebAPI, vous pouvez utiliser la méthode base.Content:

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

Nous devons nous efforcer de ne pas renvoyer du html mais des données pures de nos API et de formater les données en conséquence dans l'interface utilisateur, mais vous pouvez peut-être utiliser:

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

ça marche pour moi

user1075679
la source
6
Emballer quelque chose dans un objet factice ne le rend pas plus pur. Si le HTML est vos données, il n'y a aucun sens à le cacher.
Jouni Heikniemi
L'idée des API Web est de renvoyer des données et de quitter l'interface utilisateur pour ajouter le HTML requis, peut-être pouvons-nous avoir des cas où les données sont du HTML, mais je pense que ce n'est pas la norme.
user1075679