ASP.NET Core 3.0 [FromBody]字符串内容返回“无法将JSON值转换为System.String。”

时间:2019-09-28 22:03:07

标签: c# json asp.net-core asp.net-core-mvc asp.net-core-3.0

在ASP.NET Core 3.0的[FromBody]上使用ApiController字符串内容将返回验证错误:

{"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."]}}

当客户发布内容类型为application/json的数据

如何在.NET Core 3.0的api控制器中以字符串形式获取原始json数据?无需客户端更新其内容类型?

6 个答案:

答案 0 :(得分:7)

不确定是否有此帮助,但我认为他们在.net core 3.0 Newtonsoft.JSON包中进行了一些更改,因此您可以尝试

安装Microsoft.AspNetCore.Mvc.NewtonsoftJson软件包。

在您的startup.cs中添加

services.AddControllers().AddNewtonsoftJson();

答案 1 :(得分:3)

如果将参数[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)        
{
...

直到我意识到有关反序列化的错误消息是正确的之前,我一直在转转!

答案 2 :(得分: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();

}

答案 3 :(得分:1)

[FromBody] string content更改为[FromBody] object content,然后如果要/需要读取为字符串,请使用content.ToString()

答案 4 :(得分:0)

您需要将Json Object转换为字符串,然后将其发送到服务器。像JSON.stringify(jsonObj)。

答案 5 :(得分:-2)

我必须编写一个自定义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());
    });