背景
我正在将JSON在我的身体中发送到我的API控制器,但不断收到以下错误。
{":["分析值时遇到意外字符:{.Path'',第1行,位置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.
}
体内的Json
{"APIKey":"1283fff8…"}
问题
我更喜欢使用.Net Core[From Body]
功能,而不是手动获取内容。
我希望JSON字符串在字符串Value
参数中可用。
我错过了什么?
ASP.NET Core试图将{"APIKey":"1283f0f8..."}
从JSON反序列化为string
值,但失败了,因为它希望输入是有效的JSON字符串。
换句话说,如果您的主体是"{"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]
调用序列化程序来反序列化请求体。然后,modelbinder尝试将其绑定到参数。在这里,它不能做到这一点,因为您绑定到一个字符串,而请求主体是一个字典。本质上,幕后发生的事情(伪代码(是:
value = JsonConvert.DeserializeObject<string>(dictionaryAsJson);
您从JSON.NET收到反序列化错误,因为它无法将JSON解析为字符串。
如果您想将值作为字符串,那么您应该将其发布为类似text/plain
的内容,而不是application/json
。否则,您将需要绑定到一个实际表示传入的JSON对象的类型,在这里它将是Dictionary<string, string>
。
我在使用ASP.NET Core 3.1时遇到了同样的问题。我在API控制器上发布了一个JSON,看起来像:
public JsonResult Save([FromBody]MainDetails obj){ ... }
在我的案例中,问题是我的MainDetails
对象的属性ChildDetails.StartDate
的类型是DateTime
,并且我正在用JSON发送一个null
值。这导致控制器上的反序列化失败。我将属性类型从DateTime
更改为DateTime?
以使其工作。
基本上,需要检查并确保您POST的JSON对要反序列化的目标对象有效。如果您有不可为null的属性,在JSON中发送的值为null
,则反序列化将失败(不告诉您原因(。希望这能有所帮助。