【发布时间】:2019-12-13 22:12:59
【问题描述】:
我正在尝试使用继承的子类在 Core(2.2/3.1) 中进行自定义模型绑定。
我使用IModelBinderProvider 和IModelBinder 来操作我的模型绑定,因为MVC 不知道是将基类Device 转换为Teddybear 还是Legobrick。
IModelBinder 的BindModelAsync 方法被我的Product 类调用,我想这就是我应该寻找Data 属性并检查它的Kind 的地方。然后从参数bindingContext.Model 中提取设备数据并将Data 属性的值替换为Teddybear 或Legobrick。
但是bindingContext.Model 为空;我没有数据。
MSDN 底部有一个示例,但其中的根是基类。
我有一个常规的根,但一个属性是一个基/继承的类构造。
在某些地方我没有正确连接呼叫,或者我没有找到读取数据的正确方法。
我猜我的IModelBinderProvider 是正确的,它捕获了Product 类型并将绑定器添加到子类Teddybear 和Legobrick。
public class DeviceTypeDataContractProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
var binders = new Dictionary<Type, (ModelMetadata, IModelBinder)>();
if (context.Metadata.ModelType == typeof(Product))
{
foreach (var type in new[] { typeof(Teddybear), typeof(Legobrick) })
{
var modelMetadata = context.MetadataProvider.GetMetadataForType(type);
binders[type] = (modelMetadata, context.CreateBinder(modelMetadata));
}
}
else
{
return null;
}
return new DeviceModelBinder(binders);
}
}
IModelBinder/BindModelAsync 的代码仍然让我无法理解。
public class DeviceModelBinder : IModelBinder
{
private Dictionary<Type, (ModelMetadata, IModelBinder)> binders;
public DeviceModelBinder(Dictionary<Type, (ModelMetadata, IModelBinder)> binders)
{
this.binders = binders;
}
public async Task BindModelAsync(ModelBindingContext bindingContext){
... I totally lost it here and am beginning to feel dizzy.
}
}
通过互联网来一个电话,例如:
"product": {
"id": "56-1",
"data": {
"kind": "teddy",
"name": "Tutu"
}
}
或
"product": {
"id": "66-1",
"data": {
"kind": "lego",
"studCount": 8
}
}
Aspnet 用来填充的:
public class Product{
string Id {get;set;}
Device Data{get;set;}
}
public class Device{
string Kind {get;set}
}
public class Teddybear: Device{
string Name {get;set}
}
public class Legobrick: Device{
int StudCount {get;set}
}
控制器规整,自定义造型挂上:
[HttpPost]
public async Task<IActionResult> Create([FromBody] Product product){...
services.AddMvc(options => {
...
options.Filters.Add(new AuthorizeFilter(policy));
})
.AddJsonOptions(options => {
options.ModelBinderProviders.Insert(0, new DeviceTypeDataContractProvider());
});
【问题讨论】:
标签: c# asp.net-mvc asp.net-core