ASP.Net MVC 3 ViewModel, ненавязчивый JavaScript и пользовательская проверка

Я пытаюсь написать собственный метод проверки в своем приложении - у меня он работает на стороне сервера, но я пытаюсь расширить его, чтобы он также реализовывал ненавязчивую проверку на стороне клиента 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 я получаю свои текстовые элементы с идентификатором с префиксом «theChild_» — это имеет смысл, поскольку моя модель представления объявляет дочерний объект, однако моя пользовательская функция не имеет префикса на имена элементов. Есть ли способ передать этот префикс в javascript, не взламывая его, чтобы он выглядел так:

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

что, на мой взгляд, противоречит идее создания моей серверной части проверки, а затем подключения всей этой дополнительной ерунды для прохождения ненавязчивой проверки, поскольку я создал фрагмент javascript, который действительно может использоваться только с этой комбинацией формы/модели представления. комбинация.


person slapthelownote    schedule 13.10.2011    source источник


Ответы (1)


Вы можете изменить свой валидатор для проверки любого префикса и добавить префикс в селектор для проверяемых элементов, как я указал в своем ответе на этот вопрос: Пользовательская проверка MVC3: сравнение двух дат. Вам нужно будет либо (1) изменить селекторы для поиска по имени, а не по идентификатору, либо (2) разделить идентификатор, используя _ вместо ..

person counsellorben    schedule 13.10.2011