【问题标题】:HttpClient.SendAsync() is not sending JSON as stringHttpClient.SendAsync() 未将 JSON 作为字符串发送
【发布时间】: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("{0}{1}", _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 方提供商。不过它的很多客户都在使用它。

标签: .net-core httpclient dotnet-httpclient


【解决方案1】:

直接回答问题...

您没有转义 JSON 字符串中的引号。试试这个:

var jsonRequest = string.Format("\"{0}\"", jsonData.Replace("\"", "\\\""));

但是...

我质疑您是如何解决这个问题的。您在 cmets 中提到,如果您不在客户端对 JSON 进行字符串化,则会在服务器端(在您的 MVC 代码中)出现错误。但是,要求客户这样做是非常尴尬和不标准的。我会:

  1. 将内容类型从 text/json 更改为 application/json。这不能解决问题,但这是标准。

  2. 去掉上面那行,直接发送jsonData。即不要将 JSON 字符串化。

  3. 提出一个关于如何解决您遇到的服务器端错误的新问题,并发布相关的 MVC 代码。

【讨论】:

  • Replace() 对象中怎么会有双斜线?它有什么作用?
  • 转义转义字符。 C# 中的"\\" 将按字面意思呈现为 \,这就是您想要在这里结束的内容。你实际上是双重转义,这就是它看起来很奇怪的原因。
  • 实际上,我刚刚更新了它 - 你需要 3 个反斜杠。第一个转义第二个,第三个转义引用。够迷惑吗? :)
  • 感谢您的编辑。第 3 方提供者需要 text/json。 :-/ 所以,我正在构建客户端以发出 3rd 方提供程序,作为 xUnit 测试的一部分,因此我们在未来升级时不会破坏任何东西。 :-/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-05
  • 2022-11-29
  • 2011-04-30
  • 1970-01-01
  • 2016-03-28
  • 2016-02-17
  • 1970-01-01
相关资源
最近更新 更多