API 控制器无法从 POST body 读取 Json
API Controller unable to read Json from POST body
背景
我在 body 中将 JSON 发送到我的 API 控制器,但不断收到以下错误。
{"":["Unexpected character encountered while parsing value: {. Path
'', line 1, position 1."]}
我的 HTTP 请求
HttpClient client = new HttpClient();
HttpRequest httpRequest;
HttpResponseMessage httpResponse = null;
httpRequest = new HttpRequest("", HostnameTb.Text, null);
var values = new Dictionary<string, string>
{
{ "APIKey", APIKeyTb.Text }
};
string json = JsonConvert.SerializeObject(values);
StringContent content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
httpResponse = client.PostAsync(HostnameTb.Text, content).Result;
var responseString = await httpResponse.Content.ReadAsStringAsync();
我的控制器是这样的。
[HttpPost]
public void Post([FromBody] string value)
{
//Never gets here.
}
中的Jsonbody.
{"APIKey":"1283f0f8..."}
问题
我更愿意使用 .Net Core [From Body]
功能,而不是手动获取内容。
我希望 JSON 字符串在字符串 Value
参数中可用。
我错过了什么?
ASP.NET Core 尝试将 {"APIKey":"1283f0f8..."}
从 JSON 反序列化为 string
值,但失败了,因为它期望输入是有效的 JSON 字符串。
换句话说,如果您的 body 是 "{\"APIKey\":\"1283f0f8...\"}"
,您将在输入变量中获得预期的 JSON 字符串。
为了在不更改 HTTP 请求的情况下获取 APIKey
值,创建一个输入类型:
public class Input
{
public string ApiKey { get; set; }
}
并将其用作控制器操作的输入:
[HttpPost]
public void Post([FromBody] Input input)
{
var apiKey = input.ApiKey;
// etc
}
或者,更改您的 HTTP 请求以发送 string
:
// ...
var content = new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json");
// ...
注意使用JsonConvert.SerializeObject()
而不是ToString()
; "foo".ToString()
仍然只是 "foo"
,而你想要 "\"foo\""
。
这不是它的工作原理。 [FromBody]
调用序列化程序来反序列化请求正文。然后,模型绑定器尝试将其绑定到参数。在这里,它不能这样做,因为您要绑定到一个字符串,而请求正文是一个字典。本质上,幕后发生的事情(伪代码)是:
value = JsonConvert.DeserializeObject<string>(dictionaryAsJson);
您收到来自 JSON.NET 的反序列化错误,因为它无法将 JSON 解析为字符串。
如果您希望将值作为字符串,那么您应该 post 类似于 text/plain
而不是 application/json
。否则,您需要绑定到一个实际代表 JSON 对象的类型,这里是 Dictionary<string, string>
。
我在使用 ASP.NET Core 3.1 时遇到了同样的问题。我正在 POST 将 JSON 连接到我的 API 控制器,看起来像:
public JsonResult Save([FromBody]MainDetails obj){ ... }
我的问题是 MainDetails
对象的 属性 ChildDetails.StartDate
是 DateTime
类型,而我发送的是 null
JSON 中的值。这导致反序列化在控制器上失败。我将 属性 类型从 DateTime
更改为 DateTime?
以使其工作。
基本上,需要检查并确保您 POST 的 JSON 对于您反序列化的目标对象有效。如果您有不可为 null 的属性,并且在 JSON 中发送的值为 null
,那么您的反序列化将失败(不告诉您原因)。
希望这有帮助。
背景
我在 body 中将 JSON 发送到我的 API 控制器,但不断收到以下错误。
{"":["Unexpected character encountered while parsing value: {. Path '', line 1, position 1."]}
我的 HTTP 请求
HttpClient client = new HttpClient();
HttpRequest httpRequest;
HttpResponseMessage httpResponse = null;
httpRequest = new HttpRequest("", HostnameTb.Text, null);
var values = new Dictionary<string, string>
{
{ "APIKey", APIKeyTb.Text }
};
string json = JsonConvert.SerializeObject(values);
StringContent content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");
httpResponse = client.PostAsync(HostnameTb.Text, content).Result;
var responseString = await httpResponse.Content.ReadAsStringAsync();
我的控制器是这样的。
[HttpPost]
public void Post([FromBody] string value)
{
//Never gets here.
}
中的Jsonbody.
{"APIKey":"1283f0f8..."}
问题
我更愿意使用 .Net Core [From Body]
功能,而不是手动获取内容。
我希望 JSON 字符串在字符串 Value
参数中可用。
我错过了什么?
ASP.NET Core 尝试将 {"APIKey":"1283f0f8..."}
从 JSON 反序列化为 string
值,但失败了,因为它期望输入是有效的 JSON 字符串。
换句话说,如果您的 body 是 "{\"APIKey\":\"1283f0f8...\"}"
,您将在输入变量中获得预期的 JSON 字符串。
为了在不更改 HTTP 请求的情况下获取 APIKey
值,创建一个输入类型:
public class Input
{
public string ApiKey { get; set; }
}
并将其用作控制器操作的输入:
[HttpPost]
public void Post([FromBody] Input input)
{
var apiKey = input.ApiKey;
// etc
}
或者,更改您的 HTTP 请求以发送 string
:
// ...
var content = new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json");
// ...
注意使用JsonConvert.SerializeObject()
而不是ToString()
; "foo".ToString()
仍然只是 "foo"
,而你想要 "\"foo\""
。
这不是它的工作原理。 [FromBody]
调用序列化程序来反序列化请求正文。然后,模型绑定器尝试将其绑定到参数。在这里,它不能这样做,因为您要绑定到一个字符串,而请求正文是一个字典。本质上,幕后发生的事情(伪代码)是:
value = JsonConvert.DeserializeObject<string>(dictionaryAsJson);
您收到来自 JSON.NET 的反序列化错误,因为它无法将 JSON 解析为字符串。
如果您希望将值作为字符串,那么您应该 post 类似于 text/plain
而不是 application/json
。否则,您需要绑定到一个实际代表 JSON 对象的类型,这里是 Dictionary<string, string>
。
我在使用 ASP.NET Core 3.1 时遇到了同样的问题。我正在 POST 将 JSON 连接到我的 API 控制器,看起来像:
public JsonResult Save([FromBody]MainDetails obj){ ... }
我的问题是 MainDetails
对象的 属性 ChildDetails.StartDate
是 DateTime
类型,而我发送的是 null
JSON 中的值。这导致反序列化在控制器上失败。我将 属性 类型从 DateTime
更改为 DateTime?
以使其工作。
基本上,需要检查并确保您 POST 的 JSON 对于您反序列化的目标对象有效。如果您有不可为 null 的属性,并且在 JSON 中发送的值为 null
,那么您的反序列化将失败(不告诉您原因)。
希望这有帮助。