我在 ASP.NET 4 中使用 C# 的 Web API 遇到了一个小问题。我正在尝试创建一个前端 GUI,它通过多个 Web API 发送和接收数据。拥有多个 API 的原因与我们的网络有关,该网络由多个安全区域组成。服务器位于不同的区域,一个简单的请求可能需要通过多达 3 个不同的 API。
具体来说,我将一个 JSON 对象从 GUI 发送到第一个 API。 JSON 对象应该被转发到下一个 API 和下一个 - 并且从那里创建一个新的 JSON 对象并沿相同的路径返回。
路径本身运行良好。问题是 JSON 对象一旦返回 GUI 就无法解析。我收到一个用引号括起来的 JSON 字符串,每个 API 一次。
字符串的开头可能是这样的:
嘿!我是一个字符串,或者是一个 JSON 对象!
API 之间的第一跳给了我这个:
“嘿!我是一个字符串,或者某种 JSON 对象!”
下一跳之后是这样的:
"\"嘿!我是一个字符串,或者是一个 JSON 对象!\""
当我的 GUI 掌握它时,我们已经有了这样的东西:
"\"\\\"嘿!我是一个字符串,或者是一个JSON对象!\\\"\""
这是解析失败的地方,原因很明显。 JSON 对象本身格式正确,但所有引号都导致 JSON.net 解析器出现问题(对象内的所有引号也被多次包装)。
到目前为止,我尝试将请求作为 application/json 类型和 text/plain 类型发送。两者都做了同样的事情。 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 并不重要。
最佳答案
在每个“代理”API 中添加引号和反斜杠,因为 JSON 字符串会针对每个响应进行重新序列化,而不是在收到响应时。
在您的代理 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/