asp.net – How to return raw string with ApiController?

The Question :

128 people think this question is useful

I have an ApiController that serves XML/JSON, but I would like one of my actions to return pure HTML. I tried the below but it still return XML/JSON.

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

This is what the above returns:

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

Is there a way to return just the pure, unescaped text without even the surrounding XML tags (maybe a different return type of action attribute)?

The Question Comments :

The Answer 1

227 people think this answer is useful

You could have your Web Api action return an HttpResponseMessage for which you have full control over the Content. In your case you might use a StringContent and specify the correct content type:

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

or

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

The Answer 2

8 people think this answer is useful

Another possible solution. In Web API 2 I used the base.Content() method of APIController:

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

I needed to do this to get around an IE9 bug where it kept trying to download JSON content. This should also work for XML-type data by using the XmlMediaTypeFormatter media formatter.

Hope that helps someone.

The Answer 3

4 people think this answer is useful

Just return Ok(value) won’t work, it will be treated as IEnumerable<char>.

Instead use return Ok(new { Value = value }) or simillar.

The Answer 4

1 people think this answer is useful

If you are using MVC rather than WebAPI you can use the base.Content method:

return base.Content(result, "text/html", Encoding.UTF8);

The Answer 5

0 people think this answer is useful

I call the following webapi2 controller method from an mvc controller method:

<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

I call it from this routine on the asp.net server:

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

The Answer 6

-2 people think this answer is useful

We must strive not to return html but pure data from our API’s and format data accordingly in the UI, but maybe you can use:

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

it works for me

Add a Comment