【问题标题】:ASP.NET MVC DataBinder not deserializing simple types from JSONASP.NET MVC DataBinder 没有从 JSON 反序列化简单类型
【发布时间】:2021-09-01 04:04:39
【问题描述】:

输入 JSON:

{ "name": "gerry" }

动作方法:

{ public ActionResult GenerateQrCode([FromBody] string name }

问题:

  • 简单类型的参数为空
  • 模型状态:无效
  • 内置的 json 反序列化器无法处理这种形式的输入

我试过了:

  • ConfigureServices() -> services.AddControllersWithViews().AddNewtonsoftJson(); 切换到我知道/喜欢的 NewtonSoft
  • 我在非 NewtonSoft 内置 MS SystemTextJsonInputFormatter.ctor() 中设置了一个断点,只是为了检查它是否仍在使用:是的,是的,我不知道为什么,当我调用以上.AddNewtonsoftJson()

情况:

  • 客户端将所有输入参数 POST 为一个 JSON 字符串文档,即 UTF8 w/out BOM
  • 该字符串来自服务器端,在即时窗口内使用new System.IO.StreamReader(Request.Body).ReadToEnd() 可以很好地读取
  • 我需要一种 ASP.NET Core 反序列化的方法,因为它可以在 .NET4.X 下运行多年而没有任何问题
  • 我不想在整个服务器操作/参数中添加 [FromBody] 和类似的选择加入签名

【问题讨论】:

    标签: json asp.net-core .net-core data-binding deserialization


    【解决方案1】:

    您将名称作为 json 传递,但作为字符串接受,因此它将为空,您可以使用 InputFormatter,例如:

    public class RawJsonBodyInputFormatter : InputFormatter
    {
        public RawJsonBodyInputFormatter()
        {
            this.SupportedMediaTypes.Add("application/json");
        }
    
        public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
        {
            var request = context.HttpContext.Request;
            using (var reader = new StreamReader(request.Body))
            {
                var content = await reader.ReadToEndAsync();
                return await InputFormatterResult.SuccessAsync(content);
            }
        }
    
        protected override bool CanReadType(Type type)
        {
            return type == typeof(string);
        }
    }
    

    在startup.cs中:

    services
    .AddMvc(options =>
    {
        options.InputFormatters.Insert(0, new RawJsonBodyInputFormatter());
    });
    

    然后就可以得到行字符串了

    要对其进行反序列化,您可以检查一下,使用 Newtonsoft 并将字符串设为模型

    [HttpPost]
        public IActionResult GenerateQrCode([FromBody] string name)
        {
            object o = JsonConvert.DeserializeObject(name);
            MyModel my = JsonConvert.DeserializeObject<MyModel>(o.ToString());
            return View();
        }
    

    【讨论】:

    • 谢谢,但是: - 我需要接受许多参数,而不仅仅是 1 个字符串 - 我需要自定义格式化程序用于所有参数,而不仅仅是一个 [FromBody] 参数我发布正文有效负载中的 JSON 文档,并期望输入格式化程序从一个有效/通常的 JSON 文档中读取所有命名参数,例如: application/json: { "param1": "hello", "param2": "world", " param3": true, "param4": 1974 } i-face: Foo(string param1, string param2, bool param3, int param4) { }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 2013-12-15
    相关资源
    最近更新 更多