能否在MVC属性上使用Bind特性替代类级别的Include配置?
实现属性级别的绑定标记方案
当然有可行的方案!你可以通过自定义绑定特性+自定义模型绑定器的组合,实现像[Required]那样在属性上直接标记绑定规则的效果,具体步骤如下:
1. 创建自定义属性级绑定特性
首先定义一个只作用于属性的特性,用来标记哪些属性需要被包含在模型绑定中:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class BindIncludeAttribute : Attribute { // 不需要额外逻辑,仅作为标记使用 }
如果你的需求是标记不需要绑定的属性,也可以改成BindExcludeAttribute,后续绑定器的判断逻辑反过来即可。
2. 实现自定义模型绑定器
继承自MVC的DefaultModelBinder,重写属性绑定的逻辑,只处理带有自定义标记的属性:
public class IncludePropertyModelBinder : DefaultModelBinder { protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) { // 检查当前属性是否带有BindInclude特性 var isPropertyIncluded = propertyDescriptor.Attributes .OfType<BindIncludeAttribute>() .Any(); // 只有标记了BindInclude的属性才执行绑定,否则跳过 if (isPropertyIncluded) { base.BindProperty(controllerContext, bindingContext, propertyDescriptor); } else { // 跳过绑定,维持属性默认值(或设置为空值) bindingContext.ModelState.SetModelValue( propertyDescriptor.Name, new ValueProviderResult(string.Empty, string.Empty, CultureInfo.InvariantCulture) ); } } }
3. 应用自定义绑定规则
有两种方式可以让这个绑定器生效:
方式一:仅作用于单个模型类
在你的模型类上标记[ModelBinder]特性,指定使用自定义绑定器:
[ModelBinder(typeof(IncludePropertyModelBinder))] public class MyClass { [Required] [BindInclude] // 标记该属性需要绑定 public string FirstName { get; set; } [Required] [BindInclude] // 标记该属性需要绑定 public string LastName { get; set; } public string Discreet { get; set; } // 无标记,不会被绑定 }
方式二:全局生效(所有模型通用)
如果希望整个项目的模型都遵循这个绑定规则,可以在项目启动时注册默认绑定器:
// 在Global.asax.cs的Application_Start方法中添加 protected void Application_Start() { // ...其他初始化代码 ModelBinders.Binders.DefaultBinder = new IncludePropertyModelBinder(); }
这样配置后,你就可以像使用[Required]一样,在属性上通过[BindInclude](或[BindExclude])来精准控制哪些属性需要被模型绑定处理,完全替代类级别的[Bind(Include)]配置。
内容的提问来源于stack exchange,提问作者Omtechguy
相关产品推荐
相关产品推荐

