ASP.NET中表单模型绑定到dynamic/object动态类型参数的实现咨询
结论
可以将明确类型实体类的属性声明为dynamic类型完成表单绑定,但如果直接将Action的入参声明为无类型的dynamic/object,框架无法完成绑定,会得到空实例。你给出的使用场景本身是可行的,只需要修正代码里的几处错误即可正常运行。
绑定规则说明
ASP.NET Core的模型绑定依赖编译期的类型元数据解析字段映射关系:
- 若Action入参直接写为
public IActionResult Submit(dynamic form),框架没有元数据判断需要实例化的结构,最终拿到的只会是未赋值的object空实例,无法拿到表单字段值。 - 若顶层模型为明确的自定义类型(比如你的
ExampleClass),框架可以读取到类的属性定义,dynamic和Dictionary<string, dynamic>类型的属性都可以正常绑定:- 单个
dynamic属性会根据提交的表单值自动适配类型,比如输入数字会被解析为int,输入普通文本会被解析为string Dictionary<string, dynamic>类型的属性支持原生的键值对绑定,只要表单字段名符合属性名[键名]的格式即可正常映射值
- 单个
你现有代码的错误修正
1. 实体类语法错误
类声明末尾多了多余的冒号,建议同时给exampleDict初始化默认空字典,避免页面渲染时空引用异常:
public class ExampleClass { public dynamic exampleAttribute { get; set; } public Dictionary<string, dynamic> exampleDict { get; set; } = new Dictionary<string, dynamic>(); }
2. Razor视图错误
- 循环中访问属性需要加
Model.前缀 exampleDict拼写错误,少写了字母l
@model ExampleClass <input asp-for="exampleAttribute" /> @foreach (var key in Model.exampleDict.Keys) { <input asp-for="exampleDict[key]" /> }
补充注意点
如果需要绑定嵌套结构的dynamic属性(比如dynamic类型属性下还有子属性),需要手动指定表单字段名的层级,或者自定义模型绑定器处理,框架无法自动识别dynamic下的嵌套元数据。如果需要完全无固定结构的动态表单绑定,也可以直接在Action入参声明IFormCollection类型接收所有表单字段,手动处理键值对映射更稳定。
内容的提问来源于stack exchange,提问作者user8088462
相关产品推荐
相关产品推荐

