2011-10-13 148 views
0

我想在我的应用程序中写一个自定义验证方法 - 我有它的工作服务器端,但我试图扩展,以便它也实现不显眼的JavaScript客户端验证。我也使用视图模型,以增加乐趣。ASP.Net MVC 3 ViewModel,不显眼的JavaScript和自定义验证

下面是我作为一个微不足道的测试 - 它很简单 - 一个子对象有三个字段 - 我写的自定义验证是至少有一个字段必须填写(显然我的实际应用程序有一个比这显著更复杂的模型):

型号:

public class Child 
{ 
    public int Id { get; set; } 
    [MustHaveFavouriteValidator("FavouritePudding", "FavouriteGame")] 
    public string FavouriteToy { get; set; } 
    public string FavouritePudding { get; set; } 
    public string FavouriteGame { get; set; } 
} 

视图模型:

public class ChildViewModel 
{ 
    public Child theChild { get; set; } 
} 

控制器:

public ActionResult Create() 
    { 
     var childViewModel = new PeopleAgeGroups.ViewModels.ChildViewModel(); 
     return View(childViewModel); 
    } 

我已经按照什么documentatation我可以在网上找到,并刮起了自定义的验证,看起来像这样:

public class MustHaveFavouriteValidator:ValidationAttribute, IClientValidatable 
{ 
    private const string defaultError = "You must have one favourite"; 

    public string firstOtherFavourite { get; set; } 
    public string secondOtherFavourite { get; set; } 

    public MustHaveFavouriteValidator(string firstFave, string secondFave) 
     : base(defaultError) 
    { 
     firstOtherFavourite = firstFave; 
     secondOtherFavourite = secondFave; 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(ErrorMessageString, name, firstOtherFavourite, secondOtherFavourite); 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 

     var aFavouriteObject = validationContext.ObjectInstance.GetType().GetProperty(firstOtherFavourite); 
     var bFavouriteObject = validationContext.ObjectInstance.GetType().GetProperty(secondOtherFavourite); 

     var aFavourite = aFavouriteObject.GetValue(validationContext.ObjectInstance, null); 
     var bFavourite = bFavouriteObject.GetValue(validationContext.ObjectInstance, null); 

     if(value==null && aFavourite ==null && bFavourite == null){ 
      return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName, aFavouriteObject.Name, bFavouriteObject.Name }); 


     } 


     return ValidationResult.Success; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     return new[] { new MustHaveFavourite(FormatErrorMessage(metadata.GetDisplayName()), firstOtherFavourite, secondOtherFavourite) }; 
    } 
} 

好东西,我的服务器端验证工作。 接下来我有模型客户验证规则:

public class MustHaveFavourite : ModelClientValidationRule 
{ 
    public MustHaveFavourite(string errorMessage, string firstotherfavourite, string secondotherfavourite) 
    { 
     ErrorMessage = errorMessage; 
     ValidationType = "musthavefavourite"; 
     ValidationParameters.Add("firstotherfavourite", firstotherfavourite); 
     ValidationParameters.Add("secondotherfavourite", secondotherfavourite); 
    } 
} 

终于,我的自定义JavaScript来将其结合在一起:

(function ($) { 
jQuery.validator.addMethod("musthavefavourite", function (value, element, params) { 

    var $firstOtherFavouriteObject = $('#' + params.firstotherfavourite); 
    var firstOtherFavourite = $firstOtherFavouriteObject.val(); 
    var $secondOtherFavouriteObject = $('#' + params.secondotherfavourite); 
    var secondOtherFavourite = $secondOtherFavouriteObject.val(); 
    if (value == '' && firstOtherFavourite == '' && secondOtherFavourite == '') { 
     return false; 
    } else { 
     return true; 

    } 
}); 
$.validator.unobtrusive.adapters.add("musthavefavourite", ["firstotherfavourite", "secondotherfavourite"], 
    function (options) { 
     options.rules['musthavefavourite'] = { 
      firstotherfavourite: options.params.firstotherfavourite, 
      secondotherfavourite: options.params.secondotherfavourite 
     }; 
     options.messages['musthavefavourite'] = options.mesage; 
    } 

); 
} (jQuery)); 

,发生的问题是,在生成的HTML,我得到我的文本元素的ID为前缀“theChild_” - 这是有道理的,因为我的viewmodel声明了一个Child对象,但是,我的自定义函数在元素名称上没有前缀。有没有办法通过对JavaScript来传递前缀,而无需实际黑客它看起来像这样:

jQuery.validator.addMethod("musthavefavourite", function (value, element, params) { 
    var $firstOtherFavouriteObject = $('#theChild_' + params.firstotherfavourite); 
    var firstOtherFavourite = $firstOtherFavouriteObject.val(); 

这在我的脑海里那种失败创建我的验证服务器端,然后钩住这些额外gumf的想法直到经过不显眼的验证,因为我创建了一段只能真正与form/viewmodel组合使用的javascript。

回答

0

您可以修改您的验证器以检查任何前缀,并将前缀添加到要检查的元素的选择器中,如我在回答此问题时概述的那样:MVC3 custom validation: compare two dates。您需要(1)将选择器更改为按名称而不是按ID搜索,或者(2)使用_而不是.来拆分ID。

相关问题