HttpClient.SendAsync() 未将 JSON 作为字符串发送
Posted
技术标签:
【中文标题】HttpClient.SendAsync() 未将 JSON 作为字符串发送【英文标题】:HttpClient.SendAsync() is not sending JSON as string 【发布时间】:2017-09-29 18:29:46 【问题描述】:我无法弄清楚 HttpClient 脚本出了什么问题。
当我使用 Fiddler 时,它可以工作,而且 AspNetCore MVC 不会抛出错误。
http://localhost:6004/api/XUnitExamplesTest/JsonStringMethod
Http-Get
User-Agent: Fiddler
Accept: text/json
Content-Type: text/json
Host: localhost:6004
Content-Length: 24
"\"Color\": \"Green\""
但 HttpClient 脚本会导致 AspNetCore MVC 问题。
var sampleData = new XUnitSampleData() Color = "Red" ;
var contentType = "text/json";
var httpMethod = HttpMethod.Get;
var uriPath = "JsonStringMethod";
var jsonData = JsonConvert.SerializeObject(_sampleData, Formatting.None).ToString(); // JSON String. --> " \"Vin\" : \"foo\", \"Color\" : \"foo\" "
var jsonRequest = string.Format("\"0\"", jsonData);
var result = await XUnitWebClient.GetAsync3(contentType, httpMethod, uriPath, jsonRequest, CancellationToken.None);
public static async Task<string> GetAsync3(string contentType, HttpMethod httpMethod, string uriPath, string request, CancellationToken cancellationToken)
using (var httpClient = new HttpClient())
using (var httpRequestMessage = new HttpRequestMessage(httpMethod, string.Format("01", _uri, uriPath)))
httpClient.BaseAddress = new Uri(string.Format("0", _baseAddress));
//httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType)); // "Accept" Header.
//httpClient.DefaultRequestHeaders.Remove("Content-Type");
//httpClient.DefaultRequestHeaders.Add("Content-Type", contentType);
httpRequestMessage.Content = new StringContent(request, Encoding.UTF8, contentType); // "Content-Type" Header.
var response = await httpClient.SendAsync(httpRequestMessage);
return await response.Content.ReadAsStringAsync();
AspNetCore MVC 得到的 JSON 值为""
。
由于我使用的是 text/json,所以我如何告诉 HttpClient 发送带有开头引号和结尾引号的 json 字符串,而不是去掉它?
或者我在这里对 JsonConvert.SerializeObject() 做错了什么?
【问题讨论】:
客户端还是服务器端? JSON 字符串两端的双引号,当我通过 freeformatter.com/json-validator.html 运行它时,它表示它是有效的 JSON 字符串。因此,当发送到服务器端(AspNetCore MVC)时,它应该在客户端(HttpClient)上工作。如果 text/json 两端没有双引号,AspNetCore MVC 将不会接受它 回答您关于 Fiddler 示例的问题。如果两端没有双引号,则会导致 AspNetCore MVC 异常,其中 Newtonsoft.Json.JsonInputFormatter & Newtonsoft.Json.JsonReaderException 遇到错误。但是在两端加上双引号就可以了。 我的立场是正确的 - 从技术上讲,JSON string 本身就是有效的 JSON。尽管如此,要求客户端对 JSON 进行刺痛,而不是直接发送它是非常尴尬的。我会尝试回答。 另一个观察结果 - 在 GET 请求中发送 JSON 正文(或任何正文)并不常见。color: green
是列表过滤器还是类似的东西?将其作为查询字符串参数传递更为常见。
我的手被绑了。必须遵守陷入自身集成混乱的第 3 方提供商。不过它的很多客户都在使用它。
【参考方案1】:
直接回答问题...
您没有转义 JSON 字符串中的引号。试试这个:
var jsonRequest = string.Format("\"0\"", jsonData.Replace("\"", "\\\""));
但是...
我质疑您是如何解决这个问题的。您在 cmets 中提到,如果您不在客户端对 JSON 进行字符串化,则会在服务器端(在您的 MVC 代码中)出现错误。但是,要求客户这样做是非常尴尬和不标准的。我会:
将内容类型从 text/json
更改为 application/json
。这不能解决问题,但这是标准。
去掉上面那行,直接发送jsonData
。即不要将 JSON 字符串化。
提出一个关于如何解决您遇到的服务器端错误的新问题,并发布相关的 MVC 代码。
【讨论】:
Replace()
对象中怎么会有双斜线?它有什么作用?
转义转义字符。 C# 中的"\\"
将按字面意思呈现为 \,这就是您想要在这里结束的内容。你实际上是双重转义,这就是它看起来很奇怪的原因。
实际上,我刚刚更新了它 - 你需要 3 个反斜杠。第一个转义第二个,第三个转义引用。够迷惑吗? :)
感谢您的编辑。第 3 方提供者需要 text/json。 :-/ 所以,我正在构建客户端以发出 3rd 方提供程序,作为 xUnit 测试的一部分,因此我们在未来升级时不会破坏任何东西。 :-/以上是关于HttpClient.SendAsync() 未将 JSON 作为字符串发送的主要内容,如果未能解决你的问题,请参考以下文章
HttpClient.SendAsync 方法退出而不抛出异常
模拟 HttpClient.SendAsync 以返回内容不为空的响应