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。”的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.NET Core 2.2 升级到 3.0

Linq 查询在 ASP.NET-Core 3.0 及更高版本中对数字等字符串进行排序

将 OpenID Connect 与 .NET Core 3.0 ASP.NET Core API 服务一起使用时出错

深入研究 Angular 和 ASP.NET Core 3.0

在 Elastic Beanstalk 上的 Asp.net core 3.0

属性路由在 asp.net core 3.0 中无法正常工作