.NET核心的定制和默认绑定组合

问题描述 投票:3回答:1

我创建一个视图模型自定义模型绑定,实现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; 
    }
}

基本上我想进行默认模型绑定,然后应用自定义绑定,类似于本SO post但对于.NET的核心,而不是框架所采取的做法。

我认为应用默认绑定是直截了当的,但一直没能找出如何做到这一点。我相信该解决方案将涉及ComplexTypeModelBinderComplexTypeModelBinderProvider类,但似乎无法找出如何去做。

我知道我可以只进行任何更改时POST请求打我控制器的方法,但这似乎错误的地点和错误的时间这样做。

asp.net-core asp.net-core-mvc model-binding custom-model-binder defaultmodelbinder
1个回答
7
投票

对于自定义ComplexTypeModelBinder,你可以从ComplexTypeModelBinder继承。

  1. 模型 public class BinderModel { public int Id { get; set; } public string Name { get; set; } public string BinderValue { get; set; } }
  2. 控制器动作 [HttpPost] public void Post([FromForm]BinderModel value) { }
  3. 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); } }
  4. 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; } }
  5. 注射提供商 public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.ModelBinderProviders.Insert(0, new CustomBinderProvider()); }); }
© www.soinside.com 2019 - 2024. All rights reserved.