Dav*_*504 6 defaultmodelbinder model-binding custom-model-binder asp.net-core-mvc asp.net-core
我正在为视图模型创建自定义模型活页夹,实现 IModelBinder
我的视图模型中有很多属性,其中大多数不需要任何自定义绑定。与其从单独显式设置模型上的所有属性值,不如让ModelBindingContext我能够获得为我绑定模型的框架,然后执行任何自定义绑定:
public class ApplicationViewModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
// get .net core to bind values on model
// Cary out any customization of the models properties
bindingContext.Result = ModelBindingResult.Success(bindingContext.Model);
return Task.CompletedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,我想执行默认的模型绑定,然后应用自定义绑定,类似于本SO帖子中采用的方法,但适用于.NET Core,而不是框架。
我以为应用默认绑定会很简单,但是还没有找到方法。我相信该解决方案将涉及ComplexTypeModelBinder和ComplexTypeModelBinderProvider类,但似乎无法找出解决方法。
我知道我可以在POST请求命中我的控制器方法时进行任何更改,但这似乎是错误的位置和错误的时间。
对于自定义ComplexTypeModelBinder,您可以从继承ComplexTypeModelBinder。
模型
public class BinderModel
{
public int Id { get; set; }
public string Name { get; set; }
public string BinderValue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)控制器动作
[HttpPost]
public void Post([FromForm]BinderModel value)
{
}
Run Code Online (Sandbox Code Playgroud)CustomBinder
public class CustomBinder : ComplexTypeModelBinder
{
private readonly IDictionary<ModelMetadata, IModelBinder> _propertyBinders;
public CustomBinder(IDictionary<ModelMetadata, IModelBinder> propertyBinders)
: base(propertyBinders)
{
_propertyBinders = propertyBinders;
}
protected override Task BindProperty(ModelBindingContext bindingContext)
{
if (bindingContext.FieldName == "BinderValue")
{
bindingContext.Result = ModelBindingResult.Success("BinderValueTest");
return Task.CompletedTask;
}
else
{
return base.BindProperty(bindingContext);
}
}
protected override void SetProperty(ModelBindingContext bindingContext, string modelName, ModelMetadata propertyMetadata, ModelBindingResult result)
{
base.SetProperty(bindingContext, modelName, propertyMetadata, result);
}
}
Run Code Online (Sandbox Code Playgroud)CustomBinderProvider
public class CustomBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.IsComplexType && !context.Metadata.IsCollectionType)
{
var propertyBinders = new Dictionary<ModelMetadata, IModelBinder>();
for (var i = 0; i < context.Metadata.Properties.Count; i++)
{
var property = context.Metadata.Properties[i];
propertyBinders.Add(property, context.CreateBinder(property));
}
//var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
//return new ComplexTypeModelBinder(propertyBinders, loggerFactory);
return new CustomBinder(propertyBinders);
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)注入提供者
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options => {
options.ModelBinderProviders.Insert(0, new CustomBinderProvider());
});
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
1102 次 |
| 最近记录: |