Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过Web API发送的字符串';s用引号括起来_C#_Json_Api_Asp.net Web Api - Fatal编程技术网

C# 通过Web API发送的字符串';s用引号括起来

C# 通过Web API发送的字符串';s用引号括起来,c#,json,api,asp.net-web-api,C#,Json,Api,Asp.net Web Api,我在ASP.NET 4中使用C#时遇到了一个小问题。我正在尝试创建一个前端GUI,它通过多个Web API发送和接收数据。拥有多个API的原因与我们的网络有关,它由几个安全区域组成。服务器位于不同的区域,一个简单的请求可能需要通过多达3个不同的API 具体来说,我将从GUI向第一个API发送一个JSON对象。JSON对象应该被转发到下一个API和下一个API,然后从那里创建一个新的JSON对象,并沿着相同的路径返回 这条路本身运行良好。问题在于,一旦JSON对象返回GUI,就无法对其进行解析。我

我在ASP.NET 4中使用C#时遇到了一个小问题。我正在尝试创建一个前端GUI,它通过多个Web API发送和接收数据。拥有多个API的原因与我们的网络有关,它由几个安全区域组成。服务器位于不同的区域,一个简单的请求可能需要通过多达3个不同的API

具体来说,我将从GUI向第一个API发送一个JSON对象。JSON对象应该被转发到下一个API和下一个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]
公共异步任务GetWidget(int id)
{
HttpClient=新的HttpClient();
字符串url=”http://nextapiserver.example.org/widgets/“+id;
string json=await client.GetStringAsync(url);
return Request.CreateResponse(HttpStatusCode.OK,json);
}
这里的问题是WebAPI默认假定它负责序列化您提供的任何内容。对于大多数用例,这正是您想要的。但是,如果您的内容已经序列化为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;
}
[HttpGet]
公共异步任务GetWidget(int id)
{
HttpClient=新的HttpClient();
字符串url=”http://nextapiserver.example.org/widgets/“+id;
string json=await client.GetStringAsync(url);
HttpResponseMessage response=Request.CreateResponse(HttpStatusCode.OK);
response.Content=newstringcontent(json,Encoding.UTF8,“application/json”);
返回响应;
}

我相信上面的内容可以改进,但这就是要点。试一试,看看它是否能帮你解决问题。请注意,您需要在所有代理API上应用此修复程序。

经过大量研究,我终于找到了这个解决方案

首先;我直接返回HttpResponseMessage;我并不是有意在API路径的每个跃点中对其进行反序列化

事实证明,问题在于我们混合使用了“本机”MVC序列化方法和JSON.net方法。任何一个本身都可以,并提供了所有API的干净传递。但是,如果我们将来自本机方法和JSON.net-methods的序列化数据组合在一起,那么API的下一级将无法识别格式,并且错误地认为应该再次序列化内容(使用本机方法)


因此,解决方案只是从序列化过程中删除所有JSON.net方法,我们最终得到了预期的结果。

您可以使用
GetAsync
而不是
GetStringAsync

public async Task<HttpResponseMessage> Get(int id)
{
    using (HttpClient httpClient = new HttpClient())
    {
        return await httpClient.GetAsync(url);
    }
}
公共异步任务Get(int-id)
{
使用(HttpClient HttpClient=new HttpClient())
{
返回wait-httpClient.GetAsync(url);
}
}
public async Task<HttpResponseMessage> Get(int id)
{
    using (HttpClient httpClient = new HttpClient())
    {
        return await httpClient.GetAsync(url);
    }
}
JSON.parse(myJSONdata["myJSONcolumn"]["sublevel1"])
JSON.parse(myJSONdata["myJSONcolumn"])["sublevel1"]
"\"my string result\""
return Ok(myStringValue);
return Ok(new { id = myStringValue });
var myStringValue = "string value";
return Ok(myStringValue);
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, "http://<Host>/<Path>");
request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
var httpResponseMessage = client.SendAsync(request).Result;
var responseString = httpResponseMessage.Content.ReadAsStringAsync().Result;
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "http://<Host>/<Path>");
request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
var httpResponseMessage = client.SendAsync(request).Result;
var responseString = httpResponseMessage.Content.ReadAsStringAsync().Result;
[HttpGet("/"), Produces("text/plain")]
public IActionResult HelloWorld() => Ok("Hello World");
var jason = JsonHelper.SerializeToJson(result);
return Ok(jason);
return new JsonResult<MyDataType>(result, JsonHelper.Settings, Encoding.UTF8, this);