将变量传递给验证器

时间:2014-02-28 19:56:21

标签: c# asp.net asp.net-mvc

我正在尝试设置类似于此示例中的远程验证: Example

我的应用程序有一个转折,但我的表单元素是动态生成的,因此这个标记:

[Remote("doesUserNameExist", "Account", HttpMethod = "POST", ErrorMessage = "User name already exists. Please enter a different user name.")]

不是一成不变的,我需要更改ErrorMessage,例如,最好改变动作。是否可能,或者你建议采取长远的方式,意味着我自己实现整个ajax验证。

任何建议都表示赞赏。

2 个答案:

答案 0 :(得分:3)

如果您需要动态错误消息,则可以将其作为验证操作中的字符串返回:

public ActionResult DoesUserNameExist(string username)
{
    if (Exists(uasername))
    {
        string errorMessage = "Some dynamic error message";
        return Json(errorMessage, JsonRequestBehavior.AllowGet);
    }

    return Json(true, JsonRequestBehavior.AllowGet);
}

如果您需要更多灵活性,例如调用动态动态操作,那么您最好滚动自定义验证解决方案,而不是依赖于内置的Remote属性。

答案 1 :(得分:2)

您可以从RemoteAttribute继承并使其根据您自己的逻辑从服务或工厂中获取所需的值。这是一个例子:

    [AttributeUsage(AttributeTargets.Property)]
    public class MyRemoteAttribute : RemoteAttribute
    {
        public MyRemoteAttribute(Type type, string propertyName)
            : base(MyRemoteAttributeDataProvider.GetAttributeData(type,propertyName).Action,               MyRemoteAttributeDataProvider.GetAttributeData(type,propertyName).Controller)
        {
            var data = MyRemoteAttributeDataProvider.GetAttributeData(type,propertyName);
            base.ErrorMessage = data.ErrorMessage;
            base.HttpMethod = data.HttpMethod;
        }
    }

    public static class MyRemoteAttributeDataProvider
    {
        public static RemoteAttributeData GetAttributeData(Type type
           , string propertyName)
        {
            //this is where you are going to implement your logic im just implementing                 as an example
            //you can pass in a different type to get your values. For example you can  pass in a service to get required values.

            //property specific logic here, again im going to implement to make this
            //specification by example
           var attrData = new RemoteAttributeData();            
           if(propertyName == "MyOtherProperty")
           {
                attrData.Action = "MyOtherPropertyRelatedAction";
                attrData.Controller = "MyOtherPropertyRelatedController";
                attrData.ErrorMessage = "MyOtherPropertyRelated Error Message";
                attrData.HttpMethod = "POST";
           }            
           else 
           {            
                attrData.Action = "UserNameExists";
                attrData.Controller = "AccountController";
                attrData.ErrorMessage = "Some Error Message";
                attrData.HttpMethod = "POST";
           }
           return attrData;
        }
    }

    public class RemoteAttributeData
    {
        public string Controller { get; set; }
        public string Action { get; set; }
        public string HttpMethod { get; set; }
        public string ErrorMessage { get; set; }
    }

这就是你应该使用的方式:

public class RegisterViewModel
{
    [Required]
    [Display(Name = "User name")]
    [MyRemote(typeof(RegisterViewModel),"UserName")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    [Required]
    [MyRemote(typeof(RegisterViewModel),"MyOtherProperty")]
    public string MyOtherProperty { get; set; }
}

正如我在评论中也提到的那样。您应该根据您的需要专门提供该提供商。

我希望这会有所帮助。

<强>更新 我根据你的评论更新了实现,因此它需要一个属性名称并进行一些属性名称的特定连接。