2

I want to directly capture JSON from an external API in a service layer, return that to a MVC 4 ApiController, and then output the JSON through that ApiController. I'm basically writing a wrapper around another API service because some other actions have to happen at the same time (authentication, etc). The problem is that the JSON gets converted to a string and is passed around as a string in my C# code. This just adds escape characters to the JSON. Is there anyway I can just pass the JSON object around in my C# code? Details of my implementation are below.

In a service layer, I'm consuming an API that provides JSON via the method below.

return new WebClient().DownloadString(url);

Unfortunately this returns a string. As this API is already returning JSON to me this is problematic because lots of escape characters get added to the string.

The JSON should look something like this

[{"Citation":{"Attachments":[{"AttachedPersonIds":null,..."Type":"Record"}]

But instead it now looks like this

"[{\"Citation\":{\"Attachments\":[{\"AttachedPersonIds\":null,...\"Type\":\"Record\"}]"

After I get this string I return it through a couple of methods to an ApiController (which is setup to return JSON) like this.

public class HintsController : ApiController
{
    public string Get(string treeId, string personId)
    {
        return _hintService.GetHints(treeId, personId);
    }
}

I've tried to convert the string to a Literal string and tried serializing the string again. Doing this just adds more escape characters and doesn't solve the problem. I think the problem is with how I'm consuming the initial call because it's casting it from JSON to a string. But I don't know how to avoid this.

Thanks in advance for any ideas.

Pinski
  • 2,607
  • 2
  • 24
  • 25
  • Where are you looking at this string? It's probably just the debugger version – scottm May 11 '12 at 22:18
  • When the string is output through the ApiController it has the escape characters in it. I don't think the debugger would add escape characters that aren't there. – Pinski May 11 '12 at 22:31
  • Think you need to return it as HttpResponseMessage with Content set to a StringContent object. Otherwise you'll get an escaped literal string. – dezfowler May 11 '12 at 22:44
  • Could you show your js code? I've add new Get method, and it is called but result newer come back to js. – RredCat Apr 02 '13 at 05:30
  • With next error. Invalid character\n at parseJSON .. at ajaxConvert .. at done .. at callback – RredCat Apr 02 '13 at 05:44

2 Answers2

4

Because the controller returns a string, the JSON formatter is serializing the entire string to a JSON string and escaping the embedded quote characters.

You can do something like this:

public HttpResponseMessage Get()
{
    var resp = new HttpResponseMessage()
    {
        Content = new StringContent("{json here...}")
    };
    resp.Content.Headers.ContentType = 
                  new MediaTypeHeaderValue("application/json");
    return resp;
}

This assumes that you always want to return JSON.

gideon
  • 19,329
  • 11
  • 72
  • 113
Mike Wasson
  • 6,572
  • 2
  • 24
  • 20
0

You can turn it into a dynamic object and pass that around, if you really want to pass the objects.

I can't tell where the literal escape characters are coming from, can you be a little more clear on that. Is the API generating them, or is there some other point in our code? I've seen them in the debug window before, when the string didn't actually contain them, and printing/etc worked normally.

You can use Json.net (standard), the built in serializer, https://github.com/jsonfx/jsonfx and others .

From the jsonfx site:

var reader = new JsonReader(); var writer = new JsonWriter();
string input = @"{ ""foo"": true, ""array"": [ 42, false, ""Hello!"", null ] }";

dynamic output = reader.Read(input);
Console.WriteLine(output.array[0]); // 42
string json = writer.Write(output);
Console.WriteLine(json); // {"foo":true,"array":[42,false,"Hello!",null]}

There are a few other ways ways, see these threads:

Community
  • 1
  • 1
Andrew
  • 8,322
  • 2
  • 47
  • 70