Asp.net core .NET核心自定义绑定和默认绑定的组合

Asp.net core .NET核心自定义绑定和默认绑定的组合,asp.net-core,asp.net-core-mvc,model-binding,custom-model-binder,defaultmodelbinder,Asp.net Core,Asp.net Core Mvc,Model Binding,Custom Model Binder,Defaultmodelbinder,我正在为视图模型创建自定义模型绑定器,实现IModelBinder 我的视图模型中有很多属性,其中大多数不需要任何自定义绑定。与其从ModelBindingContext分别显式设置模型上的所有属性值,我希望能够获得框架来为我绑定模型,然后我将执行任何自定义绑定: public class ApplicationViewModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingCo

我正在为视图模型创建自定义模型绑定器,实现
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; 
    }
}
基本上,我希望执行默认的模型绑定,然后应用自定义绑定,类似于本文中采用的方法,但针对.NET核心,而不是框架

我假设应用默认绑定是很简单的,但还没有找到如何实现。我相信解决方案将涉及
ComplexTypeModelBinder
ComplexTypeModelBinderProvider
类,但似乎无法找到如何进行


我知道,当POST请求点击我的控制器方法时,我可以进行任何更改,但这似乎是错误的位置和错误的时间。对于自定义
ComplexTypeModelBinder
,您可以从
ComplexTypeModelBinder
继承

  • 模型

    public class BinderModel
    {
       public int Id { get; set; }
       public string Name { get; set; }
       public string BinderValue { get; set; }
    }
    
  • 控制器动作

    [HttpPost]
    public void Post([FromForm]BinderModel value)
    {
    
    }
    
  • 定制活页夹

    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);
        }
    }
    

  • ComplexTypeModelBinder没有单参数构造函数。伊莫代尔宾德为我工作。
    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;
        }
    
    }
    
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(options => {
            options.ModelBinderProviders.Insert(0, new CustomBinderProvider());
        });
    }