WCF 使用 HTTP 400 响应来自 Razor Pages 应用的序列化 JSON 字符串

WCF responds with HTTP 400 to serialized JSON string from Razor Pages app

我正在尝试 POST 包含 JSON 从 Razor Pages 应用程序到 WCF 服务端点的请求,需要 Json WebMessageFormat 和 Bare BodyStyle.The JSON 通过 Postman 传递得很好,但当我通过 http-client 发送它时却没有。 Wireshark 还在 http 客户端生成的数据包中的 JSON 周围显示了一些额外的字节,这些字节在 Postman 数据包中不存在。对于 Postman 数据包,Wireshark 还将此报告为 line-based text data: application/json。 .Net 数据包是 JavaScript Object Notation: application/json.

这是我的 C# 代码,用于将 JSON 发送到 WCF 端点:

var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:8000");

dynamic foo = new ExpandoObject();
foo.position = 1;

var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(foo), System.Text.Encoding.UTF8, "application/json");

var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:8000/WCFService/ControllerV1/PostJSON");
request.Headers.Add("cache-control", "no-cache");
request.Headers.Add("Accept", "*/*");
request.Headers.Add("Connection", "keep-alive");
request.Content = content;


try
{
    var response = await client.SendAsync(request);
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
}
    catch (HttpRequestException e)
{
    Console.WriteLine(e.Message);
}

这是我的 WCF 端点声明:

[OperationContract, WebInvoke(Method="POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
void PostJSON(string jsonString);

我希望这些数据包从服务器产生相同的响应,但是,当邮递员构建数据包时,似乎相同的字符串会产生响应 200,而当由 .Net 构建时,会产生响应 400。我显然在这里遗漏了一些微妙的东西,但我似乎无法梳理它。

请求和响应有 2 种可能的 BodyStylewrappedbare。当您指定 wrapped 主体样式时,WCF 服务期望传递有效的 json,在您的情况下为

//note that property name is case sensitive and must match service parameter name
{
    "jsonString": "some value"
}

并且当您指定 bare 格式时,服务只需要纯字符串值(如果您使用原始类型)作为这样的请求

"some value"

当你像这样序列化你的对象时

dynamic foo = new ExpandoObject();
foo.position = 1;

string result = JsonConvert.SerializeObject(foo);

result包含以下json

{
    "position":1
}

对应于 wrapped 格式和服务 returns 400: Bad Request。您需要做的就是将此 json 转换为有效的 json string 值,例如

"{\"position\":1}"

重复JsonConvert.SerializeObject调用即可完成

dynamic foo = new ExpandoObject();
foo.position = 1;

string wrapped = JsonConvert.SerializeObject(foo);
string bare = JsonConvert.SerializeObject(wrapped);
var content = new StringContent(bare, System.Text.Encoding.UTF8, "application/json");