Проблемы с реализацией IClientValidatable- GetClientValidationRules никогда не запускаются

0

Я создаю специальный валидатор для моего приложения MVC4. Чтобы все было просто и сосредоточиться на этом вопросе, скажите, что я переопределяю проверку сервера класса RequiredAttribute и проверку на стороне клиента:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MyRequiredAttribute: ValidationAttribute, IClientValidatable
{
    public MyRequiredAttribute() : base("The {0} field is required.")
    {
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null)
        {
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }
        return null;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRequiredRule(ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()));
    }
}

Чтобы проверить это, у меня есть очень простой контроллер:

public class TestController : Controller
{
    public ActionResult Index()
    {
        return View(new MyThing {Value = "whatever"});
    }
    [HttpPost]
    public ActionResult Index(MyThing thing)
    {
        if (ModelState.IsValid)
        {
            return Content("Good choice!");
        }
        return View(thing);
    }
}

и очень простая модель:

public class MyThing
{
    [MyRequired]
    public string Value { get; set; }
    [Required]
    public string OtherValue { get; set; }
}

и, наконец, индекс:

@model MyThing

@{
    Layout = "~/Views/Shared/_LayoutWithAllTheAppropriateValidationScripts.cshtml";
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
        @using(Html.BeginForm()){
        @Html.ValidationSummary(true)
        @Html.EditorForModel()
        <input type="submit" value="submit"/>
        }
    </div>
</body>
</html>

Вы заметите, что у меня есть Value который украшен пользовательским MyRequiredAttribute и OtherValue который украшен стандартным RequiredAttribute.

Обе из них прекрасно работают на стороне сервера и возвращают соответствующие сообщения проверки при обратной передаче, но только клиентский RequiredAttribute работает на стороне клиента. Поскольку я использую ModelClientValidationRequiredRule вместо ModelClientValidationRule с настраиваемым свойством ValidationType я предполагаю, что никакие настраиваемые правила проверки клиентов не должны определяться, но я не знаю этого точно, потому что я не смог получить это далеко. Отладчик никогда не ломается внутри метода GetClientValidationRules и элемент ввода html, сгенерированный для свойства Value в моей модели, не имеет атрибутов data-val-required и data-val как и поле OtherValue, которое я предполагаю, является тем, что Метод GetClientValidationRules отвечает за выполнение.

Мне, должно быть, здесь что-то не хватает... что это?

Теги:
validation
asp.net-mvc-4

2 ответа

3
Лучший ответ

Это оказалось ошибкой пользователя, но я все равно отправлю решение в надежде, что это поможет кому-то еще с подобной проблемой в будущем.

Код в исходном вопросе находится в отдельной сборке из проекта MVC, который его использует. Недавно проект MVC был повышен с MVC3 до MVC4. Я выполнил инструкции, предоставленные Microsoft по вопросам модернизации, или, как я думал. Я пропустил одну часть в файле web.config:

<runtime>
   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
     <dependentAssembly>
       <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
       <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0"/>
     </dependentAssembly>
   </assemblyBinding>
</runtime>

Это говорит о проекте MVC, как играть хорошо с сборками, от которых зависит, которые были скомпилированы со ссылкой на более раннюю версию сборки System.Web.Mvc. После обновления моего проекта MVC он ссылался на System.Web.Mvc v4 и мой "Common" (где расширен расширенный ValidatorAttribute реализующий IClientValidatable), на который ссылается v3. Конфигурация выше должна была быть обновлена с обновлением, но она пропустила. Проблема не проявлялась ни в каком другом ключе, кроме проблемы проверки на стороне клиента, изложенной в исходном вопросе.

Оскорбительная линия здесь была

       <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0"/>

которые должны были быть

       <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>

которая фиксировала проблему.

0

Добавьте это в свой Global.asax:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyRequiredAttribute), typeof(RequiredAttributeAdapter));

Это должно решить проблему проверки на стороне клиента.

  • 0
    Это на самом деле объединяет два разных подхода к созданию пользовательских атрибутов проверки, как описано здесь и здесь . Я использую подход IClientValidatable в коде, который я предоставил. Простого добавления предоставленной вами строки кода недостаточно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню