ASP.Net MVC 3 ViewModel,不引人注目的JavaScript和自定义验证

时间:2011-10-13 09:28:22

标签: javascript jquery asp.net-mvc-3 unobtrusive-validation

我正在尝试在我的应用程序中编写自定义验证方法 - 我有它在服务器端工作,但我正在尝试扩展它,以便它也在不显眼的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);
    } 

我已经关注了我可以在网上找到的文件,并提出了一个如下所示的自定义验证器:

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,以通过不显眼的验证,因为我已经创建了一个只能真正用于该组合的javascript的javascript form / viewmodel组合。

1 个答案:

答案 0 :(得分:0)

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

相关问题