Strings sent through Web API's gets wrapped in quotes
The quotes and backslashes are being added at each "proxy" API as the JSON string is re-serialized for each response, not when the response is received.
In your proxy API, presumably you are doing something like this (error handling omitted for brevity):
[HttpGet]
public async Task<HttpResponseMessage> GetWidget(int id)
{
HttpClient client = new HttpClient();
string url = "http://nextapiserver.example.org/widgets/" + id;
string json = await client.GetStringAsync(url);
return Request.CreateResponse(HttpStatusCode.OK, json);
}
The problem here is that Web API assumes by default that it is responsible for serializing anything you give it. For most use cases, this is exactly what you would want. But if your content is already serialized to JSON, Web API has no way of knowing that; it will happily re-serialize the string, adding extra quotes and backslashes in the process.
To pass through a JSON string untouched, you need to explicitly create the response content object (rather than letting Web API create it), making sure to set the media type to so that downstream clients will still interpret it as JSON (rather than plain text). Here is the revised code:
[HttpGet]
public async Task<HttpResponseMessage> GetWidget(int id)
{
HttpClient client = new HttpClient();
string url = "http://nextapiserver.example.org/widgets/" + id;
string json = await client.GetStringAsync(url);
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;
}
I'm sure the above can improved, but that is the gist of it. Give it a shot and see if it solves the issue for you. Note that you will need to apply this fix on all the proxy APIs.
For ASP.NET Core, decorate the action with [Produces("text/plain")]
.
Eg.
[HttpGet("/"), Produces("text/plain")]
public IActionResult HelloWorld() => Ok("Hello World");
After MUCH research, I finally figured this one out.
First off; I was returning the HttpResponseMessage directly; I was not intentionally deserializing it inside each hop along the API-path.
The problem, as it turns out, was actually that we were using a mix of the "native" MVC serialization methods and JSON.net's methods. Either one by itself is fine, and provides a clean passthrough of all API's. If, however, we would combine serialized data from both native methods and JSON.net-methods, the API's further down the chain would not be able to recognize the formatting and incorrectly assume that the content should be serialized again (using native methods).
So the solution was simply to remove all JSON.net-methods from the serialization process, and we ended up with the expected results.