Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 使用DataAnnotationsModelValidator适配器进行MVC3远程验证_Asp.net Mvc_Asp.net Mvc 3_Data Annotations_Model Validation_Remote Validation - Fatal编程技术网

Asp.net mvc 使用DataAnnotationsModelValidator适配器进行MVC3远程验证

Asp.net mvc 使用DataAnnotationsModelValidator适配器进行MVC3远程验证,asp.net-mvc,asp.net-mvc-3,data-annotations,model-validation,remote-validation,Asp.net Mvc,Asp.net Mvc 3,Data Annotations,Model Validation,Remote Validation,我想使用自定义DataAnnotationsAttribute验证模型的DTO属性上的各种电话号码属性。我不想将DataAnnotations复制到ViewModels上,以保持代码干燥,而是使用DataAnnotationsModelValidatorProvider注册了一个用于客户端验证的自定义适配器。此适配器提供通常由RemoteAttribute使用的ModelClientValidationRemoteRules。jQuery不引人注目的验证然后调用我的验证操作,该操作验证各个字段

我想使用自定义DataAnnotationsAttribute验证模型的DTO属性上的各种电话号码属性。我不想将DataAnnotations复制到ViewModels上,以保持代码干燥,而是使用DataAnnotationsModelValidatorProvider注册了一个用于客户端验证的自定义适配器。此适配器提供通常由RemoteAttribute使用的ModelClientValidationRemoteRules。jQuery不引人注目的验证然后调用我的验证操作,该操作验证各个字段

然而,这种设置实际上并不充分

  • 该属性当前使用its ContainerType确定 要调用的验证操作。DTO用于不同的ViewModel 然而,在不同的筑巢水平上,我们不知道到底是什么 要在操作上使用的前缀。取决于配置文件的位置 在模型层次结构中,操作前缀需要更改

  • 验证操作使用Request.Form.Keys确定 应验证的属性。我知道最好的做法是 为了单元的安全,请远离正在运行的请求对象 测试等

  • 有没有一种好方法可以在回发中包含要验证的字段的名称,这样我就可以将其作为附加参数而不是使用Request.Form

    有没有办法让模型绑定器绑定我的属性,因为它们将使用依赖于子模型名称的前缀发回

    提前谢谢


    该属性如下所示:

    public class PhoneNumberAttribute : ValidationAttribute
    {
        public PhoneNumberType RequiredType { get; set; }
    
        public PhoneNumberAttribute()
            : base("{0} is not a valid phone number.")
        {
        }
    
        public override bool IsValid(object value)
        {
            string s = value as string;
            if (s == null)
            {
                return false;
            }
            if (!PhoneNumberUtils.IsValidNumber(s, RequiredType))
            {
                return false;
            }
    
            return true
        }
    
        public override string FormatErrorMessage(string name)
        {
            return string.Format(ErrorMessageString, name);
        }
    }
    
    和适配器:

    public class PhoneNumberAttributeAdapter : DataAnnotationsModelValidator<PhoneNumberAttribute>
    {
        public PhoneNumberAttributeAdapter(ModelMetadata metadata, ControllerContext context, PhoneNumberAttribute attribute)
            : base(metadata, context, attribute)
        {
        }
    
        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            var errorMessage = Attribute.FormatErrorMessage(Metadata.GetDisplayName());
            var routeData = new RouteValueDictionary { 
                { "controller", "Validate" },
                { "action", Metadata.ContainerType.Name },
            };
    
            var path = RouteTable.Routes.GetVirtualPathForArea(ControllerContext.RequestContext, routeData);
    
            var rule = new ModelClientValidationRemoteRule(
                errorMessage, 
                path.VirtualPath, 
                "POST", 
                "*." + Metadata.PropertyName);
    
            return new[] { rule };
        }
    }
    

    看一看这个示例,其中显示了如何在自定义jQuery验证器中甚至使用前缀来获取嵌套属性

    其次,MVC模型绑定器应该自动绑定前缀

    public ActionResult ProfileDto([Bind(Prefix = "Dto")]ProfileDto model)
    {
        string fieldToValidate = Request.Form.Keys[0];
        if (ModelState.IsValidField(fieldToValidate))
        {
            return Json(true);
        }
    
        var fieldErrors = ModelState[fieldToValidate].Errors;
    
        return Json(fieldErrors.First().ErrorMessage);
    }