ASP.NETMVC3viewmodel、低调的JavaScript和自定义验证
我正在尝试在我的应用程序中编写一个自定义验证方法——我让它在服务器端工作,但我正在尝试扩展它,以便它也在不引人注目的javascript客户端验证中实现。为了增加乐趣,我还使用了viewmodel 这是我做的一个简单的测试-非常简单-一个子对象有三个字段-我正在编写的自定义验证是至少必须填写一个字段(显然我实际的应用程序有一个比这个复杂得多的模型): 型号:ASP.NETMVC3viewmodel、低调的JavaScript和自定义验证,javascript,jquery,asp.net-mvc-3,unobtrusive-validation,Javascript,Jquery,Asp.net Mvc 3,Unobtrusive Validation,我正在尝试在我的应用程序中编写一个自定义验证方法——我让它在服务器端工作,但我正在尝试扩展它,以便它也在不引人注目的javascript客户端验证中实现。为了增加乐趣,我还使用了viewmodel 这是我做的一个简单的测试-非常简单-一个子对象有三个字段-我正在编写的自定义验证是至少必须填写一个字段(显然我实际的应用程序有一个比这个复杂得多的模型): 型号: public class Child { public int Id { get; set; } [MustHaveFav
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 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 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) };
}
}
最后,我的自定义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声明了一个子对象,但是,我的自定义函数在元素名称上没有前缀。有没有办法将该前缀传递到javascript,而不实际将其修改为如下所示:
jQuery.validator.addMethod("musthavefavourite", function (value, element, params) {
var $firstOtherFavouriteObject = $('#theChild_' + params.firstotherfavourite);
var firstOtherFavourite = $firstOtherFavouriteObject.val();
在我看来,这有点挫败了创建我的验证服务器端,然后连接所有这些额外的gumf来进行不引人注目的验证的想法,因为我已经创建了一段javascript,它实际上只能与表单/视图模型组合一起使用。您可以修改您的验证程序来检查任何前缀,并将前缀添加到要检查的元素的选择器中,如我在回答此问题时所述:。您需要(1)将选择器更改为按名称而不是按id搜索,或(2)使用
\u
而不是拆分id