Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET WebAPI: How to control string content returned to client?

In WebAPI, say I return a string wrapped in an HTTP response:

return Request.CreateResponse(HttpStatusCode.BadRequest, "Line1 \r\n Line2");

When invoking this action from jQuery, the response text is treated before it is returned. So in the xhr, I get something like this:

function success(xhr) {
    alert(xhr.responseText); // alerts ""Line1 \\r\\n Line2""
}

In other words, the string gets wrapped in double quotes, and special characters get escaped so that they appear in the output (actual alert is "Line1 \r\n Line2", so the newlines are not preserved, but rather encoded and shown in the response text).

I can get around this by removing the quotes and replacing the newlines on the client like so:

var responseText = xhr.responseText.substr(1, xhr.responseText - 2)
    .replace('\\r', '\r').replace('\\n', '\n');

But is there a way to tell WebAPI how to format string responses? For example, not to wrap them in double quotes and convert escaped characters?

like image 434
danludwig Avatar asked Oct 29 '12 19:10

danludwig


People also ask

Can you return an action from Web API?

The Web API action method can have following return types. It's not necessary that all action methods must return something. It can have void return type.


2 Answers

This happens because your controller is returning JSON in which string values are quoted.

A simple solution is to parse the responseText as JSON and then you can use the value as intended:

$.ajax("/api/values/10", {
    error: function (xhr) {
        var error = JSON.parse(xhr.responseText);
        $("textarea").val(error);
    }
});

This correctly interprets the line breaks/carriage returns.

Alternatively you can specify the text/plain media type in your controller:

return Request.CreateResponse(
    HttpStatusCode.BadRequest, 
    "Line1 \r\n Line2", "text/plain");

Web API will then try and load an appropriate media type formatter for text/plain which unfortunately does not exist OOTB. You'll find one in WebApiContrib.

like image 160
Ben Foster Avatar answered Oct 21 '22 13:10

Ben Foster


What you are after is a custom MediaTypeFormatter. It sounds like you wish to implement your own custom one to replace and existing or you're creating a new custom one all together depending what what Accept header you're expecting. Good news is you can swap out existing ones or come up with a new MediaType of you like. A couple places that will help get you started can be found here:

http://byterot.blogspot.com/2012/04/aspnet-web-api-series-part-5.html

http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

Yes, I've actually done this in small part as I've swapped out some of the default formatter e.g. JSON with a faster one i.e. ServiceStack and it works great.

like image 42
Daron Cox Avatar answered Oct 21 '22 12:10

Daron Cox