asp.net-core - .NET 核心自定义和默认绑定(bind)相结合

标签 asp.net-core asp.net-core-mvc model-binding custom-model-binder defaultmodelbinder

我正在为 View 模型创建自定义模型绑定(bind)器,实现 IModelBinder
我的 View 模型中有很多属性,其中大部分不需要任何自定义绑定(bind)。而不是从 ModelBindingContext 单独显式设置我的模型上的所有属性值,我将能够让框架为我绑定(bind)模型,然后我将执行任何自定义绑定(bind):

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

基本上我想执行默认模型绑定(bind),然后应用自定义绑定(bind),类似于此 SO post 中采用的方法但对于 .NET Core,而不是框架。

我认为应用默认绑定(bind)会很简单,但无法找到如何做到这一点。我相信解决方案将涉及 ComplexTypeModelBinderComplexTypeModelBinderProvider类(class),但似乎无法找到如何去做。

我知道当 POST 请求到达我的 Controller 方法时我可以进行任何更改,但这似乎是错误的地方和错误的时间。

最佳答案

定制ComplexTypeModelBinder ,您可以从 ComplexTypeModelBinder 继承.

  • 型号

  •     public class BinderModel
        {
           public int Id { get; set; }
           public string Name { get; set; }
           public string BinderValue { get; set; }
        }
    
  • Controller 操作

  •     [HttpPost]
        public void Post([FromForm]BinderModel value)
        {
    
        }
    
  • 自定义绑定(bind)器

  •     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);
            }
        }
    
  • 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;
            }
    
        }
    
  • 注入(inject)提供者

  •     public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options => {
                options.ModelBinderProviders.Insert(0, new CustomBinderProvider());
            });
        }
    

    关于asp.net-core - .NET 核心自定义和默认绑定(bind)相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51921074/

    相关文章:

    asp.net-core - Serilog MSSqlServer 接收器不写入表

    c# - 如何指示 TypeConverter 中的错误

    c# - Nancy FX 在模型绑定(bind)上将字典中的键大写

    asp.net-core-mvc - MVC 6 EF7 RC1 创建多个 dbcontext

    asp.net-core - 具有取消 token 的自定义AspCore中间件

    c# - Asp.Net Core 中间件中的重定向不呈现目标页面

    viewmodel - MVC 6 复杂模型绑定(bind)

    asp.net-core - ASP.NET Core- 有没有办法使用自定义标签助手呈现一组元素?

    asp.net-core - 构建 ASP.NET Core 项目以引用 .Net 标准库

    c# - 将 Context.UserIdentifier 设置为不同的声明