149

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/">&lt;strong&gt;test&lt;/strong&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)?

6 Answers 6

248

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"
        )
    });
}
Sign up to request clarification or add additional context in comments.

3 Comments

I havent tried yet but I wonder if I'd set data type to html would work ?
No it won't work. The Web API has XML and JSON formatters built-in only. For everything else you will have to build your own formatter or return raw HttpResponseMessages from your methods as shown in my answer.
HttpResponseMessage is located in the System.Net.Http namespace.
12

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.

2 Comments

the OP was asking for returning a html string .. where is such a string ? and how can JsonMediaTypeFormatter return html ?
thanks, I found your answer one step before wrinting my own MediaTypeFormatter for returning opaque plain strings, I wouldn't guess that JsonMediaTypeFormatter also handles text/plain
6

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

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

3 Comments

return Ok(stringValue) worked fine for me. [c# webapi net5.0]
@theSushil: that might've been changed in .NET Core or .NET 5. The response is from 2016, the pre-.NET Core times where this was an issue.
For me, it almost worked - for JSON it escaped everything, rendering the json invalid.
4

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

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

Comments

0

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

Comments

-3

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

3 Comments

Wrapping something in a dummy object does not make it any more pure. If the HTML is your data, there's no sense in hiding it.
The idea of web api's is to return data, and leave the UI to add the required HTML, maybe we can have some cases where the data is HTML, but I think that is not the norm.
I agree that we should strive to return structured data instead of HTML. however, the code you provided did not return raw string solely as requested

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.