我在使用C#的ASP.NET 4中遇到了我的Web API的一个小问题。我正在尝试创建一个前端GUI,该GUI通过多个Web API发送和接收数据。拥有多个API的原因与我们的网络有关,该网络由几个安全区域组成。服务器位于不同的区域,一个简单的请求可能必须传递多达3个不同的API。
具体来说,我是从GUI向第一个API发送JSON对象。应该将JSON对象转发到下一个API和下一个API,然后从那里创建一个新的JSON对象,并沿着相同的路径返回。
路径本身工作正常。问题在于,一旦返回到GUI,就无法解析JSON对象。我收到一个用引号引起来的JSON字符串,每个API一次。
字符串可能像这样开始:Hey! I am a string, or a JSON object of sorts!
API之间的第一跳为我提供了这一点:"Hey! I am a string, or a JSON object of sorts!"
在下一跳之后,它看起来像这样:"\"Hey! I am a string, or a JSON object of sorts!\""
当我的GUI掌握了它时,我们就会得到以下内容:"\"\\\"Hey! I am a string, or a JSON object of sorts!\\\"\""
出于明显的原因,这是解析失败的地方。 JSON对象本身的格式正确,但是所有引号都导致JSON.net解析器出现问题(对象内的所有引号也被多次包装)。
到目前为止,我尝试将请求发送为应用程序/json类型和文本/纯文本类型。两者都做同样的事情。 API返回HttpResponseMessage,可使用ReadAsStringAsync()进行读取。我还尝试避免读取字符串,而只是直接从HttpRequestMessage读取到HttpResponseMessage中,并且仅在GUI中执行ReadAsStringAsync(),但问题仍然存在。 JSON字符串是使用JSON.nets Serialize()方法创建的,并使用StringContent()放入HttpContent。这似乎正确地完成了工作。我相信引号是在API和GUI收到HttpResponseMessage时生成的。
知道如何将JSON字符串作为原始字符串发送和接收吗?
我可以通过将对象解析为每个API的JToken或JObject,然后再次对其进行序列化来绕过此行为。但是,这不是一个好的解决方案-我希望API只是按照消息的获取方式转发消息,而不对消息做任何事情。我使用路由研究了转发,但是正在进行很多授权工作,这确实要求我使用API操作,而不是重定向路由。
澄清一下(TLDR):理想的解决方案是API仅传递消息而不解析或读取任何内容。只要消息的来源得到授权,请求被加密并且所请求的URL有效,消息本身就对每个“代理” API无关紧要。
最佳答案
在为每个响应(而不是在收到响应时)重新序列化JSON字符串时,将在每个“代理” API处添加引号和反斜杠。
在您的代理API中,大概您正在执行以下操作(为简洁起见,省略了错误处理):
[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);
}
这里的问题是,Web API默认情况下假定它负责序列化您提供的所有内容。对于大多数用例,这正是您想要的。但是,如果您的内容已经序列化为JSON,则Web API无法得知。它将很高兴地重新序列化字符串,并在此过程中添加额外的引号和反斜杠。
要不加修改地传递JSON字符串,您需要显式创建响应内容对象(而不是让Web API创建它),并确保将媒体类型设置为,以便下游客户端仍将其解释为JSON(而不是纯文本)。 )。这是修改后的代码:
[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;
}
我敢肯定,上述情况可以改善,但这就是要旨。试一试,看看它是否能为您解决问题。请注意,您将需要在所有代理API上应用此修复程序。
关于c# - 通过Web API发送的字符串用引号引起来,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33681978/