Dave
Dave

Reputation: 3882

Returning a string containing valid Json with Nancy

I receive a string that contains valid JSON from another service. I would like to just forward this string with Nancy but also set the content-type to "application/json" which will allow me to remove the need for using $.parseJSON(data) on the client side.

If I use Response.AsJson it seems to mangle the JSON in the string and adds escape characters. I could create a Stream with the string and set the response type something like:

Response test = new Response();
test.ContentType = "application/json";
test.Contents = new MemoryStream(Encoding.UTF8.GetBytes(myJsonString)); 

but would like to know if there is a simpler way?

Upvotes: 50

Views: 29731

Answers (5)

Peter Kofler
Peter Kofler

Reputation: 9440

If all routes of your module return a JSON string, then you can set the content type in the After hook for all routes at once:

Get["/"] = _ =>
{
    // ... 
    return myJsonString;
};

After += ctx =>
{
    ctx.Response.ContentType = "application/json";
};

Upvotes: 1

djoyce
djoyce

Reputation: 315

This also works:

Response.AsText(myJsonString, "application/json");

Upvotes: 19

Darius
Darius

Reputation: 1149

Looks like Nancy has got a nice Response.AsJson extension method:

Get["/providers"] = _ =>
            {
                var providers = this.interactiveDiagnostics
                                    .AvailableDiagnostics
                                    .Select(p => new { p.Name, p.Description, Type = p.GetType().Name, p.GetType().Namespace, Assembly = p.GetType().Assembly.GetName().Name })
                                    .ToArray();

                return Response.AsJson(providers);
            };

Upvotes: 76

Steven Robbins
Steven Robbins

Reputation: 26599

I like that you think there should be a better way because you're having to use 3 lines of code, I think that says something about Nancy :-)

I can't think of a "better" way to do it, you can either do it the GetBytes way:

Get["/"] = _ =>
    {
        var jsonBytes = Encoding.UTF8.GetBytes(myJsonString);
        return new Response
            {
                ContentType = "application/json",
                Contents = s => s.Write(jsonBytes, 0, jsonBytes.Length)
            };
    };

Or the "cast a string" way:

Get["/"] = _ =>
    {
        var response = (Response)myJsonString;

        response.ContentType = "application/json";

        return response;
    };

Both do the same thing - the latter is less code, the former more descriptive (imo).

Upvotes: 59

TheCodeJunkie
TheCodeJunkie

Reputation: 9616

Pretty much the way you do it. You could do

var response = (Response)myJsonString;
response.ContentType = "application/json";

You could just create an extension method on IResponseFormatter and provide your own AsXXXX helper. With the 0.8 release there will be some extensions on the response it self so you can do stuff like WithHeader(..), WithStatusCode() etc-

Upvotes: 7

Related Questions