ASP.NET Core 3.0 [FromBody] 字符串内容返回“无法将 JSON 值转换为 System.String。”
Posted
技术标签:
【中文标题】ASP.NET Core 3.0 [FromBody] 字符串内容返回“无法将 JSON 值转换为 System.String。”【英文标题】:ASP.NET Core 3.0 [FromBody] string content returns "The JSON value could not be converted to System.String." 【发布时间】:2020-01-28 17:32:13 【问题描述】:在 ASP.NET Core 3.0 中对 ApiController
使用 [FromBody]
字符串内容会返回验证错误:
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title":"One or more validation errors occurred.",
"status":400,
"traceId":"|9dd96d96-4e64bafba4ba0245.",
"errors":"$":["The JSON value could not be converted to System.String. Path: $ | LineNumber: 0 | BytePositionInLine: 1."]
当客户端使用 content-type 发布数据时:application/json
如何在 .NET Core 3.0 的 api 控制器中将原始 json 数据作为字符串获取?无需客户端更新其内容类型?
【问题讨论】:
这在 .net core 2.1 中有效吗?发布您的 json 示例。 我决定只使用 StreamReader 并自己阅读 Request.Body。它是一个新项目,在 2.1 上还没有 testet,但过去可能将正文绑定到 JToken 而不是字符串。 【参考方案1】:不确定这是否有帮助,但我认为他们对 .net core 3.0 Newtonsoft.JSON 包进行了一些更改,因此您可以尝试一下
安装Microsoft.AspNetCore.Mvc.NewtonsoftJson
包。
在你的 startup.cs 添加
services.AddControllers().AddNewtonsoftJson();
【讨论】:
我的 [FromBody] JSON 参数在 3.0 升级后返回 null。这解决了它。谢谢! 这完全有效,经过数小时的调试,没有错误只是安装它,我们是绿色的! 尝试使用 asp .net core 3.1。面对错误 Package Microsoft.AspNetCore.Mvc.NewtonsoftJson 5.0.0 is not compatible with netcoreapp3.1 @Vikram,那是因为您正在安装 NuGet 包的 5.0.0 版。安装前,选择版本为3.1。【参考方案2】:如果您使用的是 asp.net core 3.0,那么它具有内置的 JSON 支持。我使用了以下内容,并且无需设置自定义输入处理程序即可工作。
[HttpPost]
public async Task<IActionResult> Index([FromBody] JsonElement body)
string json = System.Text.Json.JsonSerializer.Serialize(body);
return Ok();
【讨论】:
别忘了导入/使用 System.Text.Json;所以 JsonElement 被识别【参考方案3】:将[FromBody] string content
更改为[FromBody] object content
,然后如果您想/需要读取为字符串,请使用content.ToString()
【讨论】:
谢谢,我把输入参数类型改成object,然后就成功了 谢谢,我在挣扎【参考方案4】:如果您将参数 [FromBody] String value
更改为 [FromBody] YourType value
,它会自动为您反序列化。
发件人:
// POST api/<SelectiveCallRulesController>
[HttpPost]
public async Task Post([FromBody] String rule)
...
收件人:
// POST api/<SelectiveCallRulesController>
[HttpPost]
public async Task Post([FromBody] SelectiveCallRule rule)
...
直到我意识到关于反序列化的错误消息是正确的!
【讨论】:
问题是有时你不能反序列化值,因为你不知道你会得到什么类型的对象。【参考方案5】:您可以创建另一个包含您的 json 字段的类。
【讨论】:
您能举个例子吗?这是如何在请求正文中发布的。【参考方案6】:您需要将 Json 对象转换为字符串,然后将其发送到服务器。像 JSON.stringify(jsonObj)。
【讨论】:
我无法更换客户。【参考方案7】:我必须编写一个自定义 IInputFormatter
以确保我的正文内容始终被解释为字符串。
我也遇到过无法更新所有 API 客户端的情况。
以下内容将确保任何[FromBody]
参数都将被解释为字符串,即使它们没有被调用者用引号括起来。
public class JsonStringInputFormatter : TextInputFormatter
public JsonStringInputFormatter() : base()
SupportedEncodings.Add(UTF8EncodingWithoutBOM);
SupportedEncodings.Add(UTF16EncodingLittleEndian);
SupportedMediaTypes.Add(MediaTypeNames.Application.Json);
public override bool CanRead(InputFormatterContext context)
if (context == null)
throw new ArgumentNullException(nameof(context));
return context.ModelType == typeof(string);
public override async Task<InputFormatterResult> ReadRequestBodyAsync(
InputFormatterContext context, Encoding encoding)
if (context == null)
throw new ArgumentNullException(nameof(context));
using (var streamReader = new StreamReader(
context.HttpContext.Request.Body,
encoding))
return await InputFormatterResult.SuccessAsync(
(await streamReader.ReadToEndAsync()).Trim('"'));
从正文中修剪引号可以向前兼容格式正确和引号包裹的正文内容。
确保它在System.Text.Json
格式化程序之前在您的启动中注册:
services.AddControllers()
.AddMvcOptions(options =>
options.InputFormatters.Insert(
0,
new JsonStringInputFormatter());
);
【讨论】:
以上是关于ASP.NET Core 3.0 [FromBody] 字符串内容返回“无法将 JSON 值转换为 System.String。”的主要内容,如果未能解决你的问题,请参考以下文章
Linq 查询在 ASP.NET-Core 3.0 及更高版本中对数字等字符串进行排序
将 OpenID Connect 与 .NET Core 3.0 ASP.NET Core API 服务一起使用时出错
深入研究 Angular 和 ASP.NET Core 3.0