IModelBinder上的BindProperty和SetProperty有什么区别

And*_*age 11 asp.net-mvc modelbinders

我在Mvc应用程序中创建自定义模型绑定器,我想将字符串解析为枚举值并将其分配给模型属性.我已经让它覆盖了该BindProperty方法,但我也注意到有一种SetProperty方法.

    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
    {
        switch (propertyDescriptor.Name)
        {
            case "EnumProperty":
                BindEnumProperty(controllerContext, bindingContext);
                break;
        }

        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }

    private static void BindEnumProperty(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var formValue = controllerContext.HttpContext.Request.Form["formValue"];

        if (String.IsNullOrEmpty(formValue))
        {
            throw new ArgumentException();
        }

        var model = (MyModel)bindingContext.Model;
        model.EnumProperty = (EnumType)Enum.Parse(typeof(EnumType), formValue);
    }
Run Code Online (Sandbox Code Playgroud)

我不确定两者之间的区别是什么,以及我是否以推荐的方式这样做.

m0s*_*0sa 7

首先,BindProperty不是IModelBinder的一部分,而是DefaultModelBinder中的受保护方法.只有在对DefaultModelBinder进行子类化时才能访问它.

以下几点应该回答你的问题:

  • BindProperty使用从propertyDescriptor参数的PropertyType获取的IModelBinder接口.这允许您将自定义属性注入属性元数据.
  • BindProperty正确处理验证.它(也)只有在新值有效时才调用SetProperty方法.

因此,如果您想要进行适当的验证(使用注释属性),您一定要调用BindProperty.通过调用SetProperty,您可以绕过所有内置验证机制.

您应该查看DefaultModelBinder的源代码,看看每个方法的作用,因为intellisense只提供有限的信息.