2014-01-02 2 views
4

У меня есть приложение ASP.NET MVC 4, которое работает нормально. Я пишу специальный ValidatorAttribute, чтобы убедиться, что значение одного свойства не меньше другого. Поскольку есть два свойства, я переопределяю IsValid (объект, контекст).Почему пользовательский валидатор ASP.NET MVC 4 вызывает ошибку маршрутизации?

Я пишу модульные тесты, используя Validator.TryValidateObject и элемент Validate (object, context) этого атрибута, и они проходят, как ожидалось. Я включаю тесты для ожидаемого использования с допустимыми значениями и недопустимыми значениями. Я включаю тесты, в которых атрибут применяется к правильному типу, и получает ожидаемое поведение (мой выбор дизайна должен пройти, если какой-либо тип свойства неверен.)

Я добавляю атрибут к своей модели, подключая его в приложение. Что-то вроде:

public abstract class DataElement 
{ 
    ... 

    [Required] 
    public string Version { get; set; } 

    [StringLength(8, ErrorMessage = "8 characters or less")] 
    [Required(ErrorMessage = "Required")] 
    [DisplayName("ID")] 
    public string DataElementNumber { get; set; } 
    ... 
} 

public abstract class SimpleElement : DataElement 
{ 
    [Required] 
    [DisplayName("Minimum")] 
    public int MinimumLength { get; set; } 

    [Required] 
    [DisplayName("Maximum")] 
    [NotSmallerThan("MinimumLength")] 
    public int MaximumLength { get; set; } 
} 

public class CodeList: SimpleElement 
{ 
    public Collection<CodeValue> Values { get; set; } 
} 

У меня есть контроллер что-то вроде

[HttpGet] 
    public ActionResult Edit(string elementId, string version) 
    { 
     CodeList model = Store.GetCodeList(elementId, version); 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Edit(CodeList model) 
    { 
     ActionResult result; 
     if (ModelState.IsValid) 
     { 
      Store.Upsert(model); 
      result = RedirectToAction("Index", "SomeOtherController"); 
     } 
     else 
     { 
      result = View(model.DataElementNumber, model.Version); 
     } 

     return result; 
    } 

Простой, я думаю. Если модель действительна, зафиксируйте хранилище данных. Если это неверно, повторно отобразите форму с сообщением о проверке. В случаях, когда я вводим допустимые значения в форму, валидатор ведет себя так, как ожидалось, то есть приложение фиксирует значения в хранилище данных и переходит дальше.

В случае, когда я ввожу значение для Minimum, которое меньше, чем Maximum, случай, который я защищаю, вместо того, чтобы видеть мой просмотр, снова, я вижу экран ошибки, что-то вроде этого для случая, когда DataElementNumber = «XML-25» и Version = «201301»

Вид «XML-25» или его мастер не был найден, или механизм просмотра не поддерживает найденные местоположения. Поиск в следующих местах:

~/Views/CodeListBuilder/XML-25.aspx

~/Views/CodeListBuilder/XML-25.ascx

~/Views/Shared/XML-25. ASPX

~/Views/Shared/XML-25.ascx

~/Views/CodeListBuilder/201301.master

~/Views/Shared/201301.master

~/Views/CodeListBuilder/XML-25.cshtml

~/Views/CodeListBuilder/XML-25.vbhtml

~/Views/Shared/XML-25.cshtml

~/Views/Shared/XML-25.vbhtml

~/Views/CodeListBuilder/201301.cshtml

~/Views/CodeListBuilder/201301.vbhtml

~/Views/Shared/201301.cshtml

~/Views/Shared/201301.vbhtml

Описание: Необработанное исключение при выполнении текущего веб-запроса.Просмотрите трассировку стека для получения дополнительной информации об ошибке и ее возникновении в коде.

Сведения об исключении: System.InvalidOperationException: ...

Я могу закомментировать пользовательский NotSmallerThanAttribute и система ведет себя, как я ожидаю, кроме формы в состоянии ввести номер Ф.О. максимум, что меньше, чем минимум. Я не уверен, как диагностировать это. Какое поведение в валидаторе может запутать механизм маршрутизации? Как его найти? TIA

+4

Ваша проблема не имеет ничего общего с вашим пользовательским валидатором, но с оператором 'View (model.Id)' ... что такое тип 'Id'? Какова ценность? У вас есть вид под названием «Edit.csthml» в найденных местах? – nemesv

+0

Что делать, если вы меняете 'result = View (model.Id);' to 'result = View (« MyEditView », model);' (также удалить '.Id')? – Marthijn

+0

Почему у вас есть вид с именем Bob, и если это не является конкретным сообщением об ошибке, включите в него * конкретное * сообщение об ошибке, а не пример. –

ответ

2

Ваша проблема не имеет ничего общего с вашим валидатором.

С result = View(model.DataElementNumber, model.Version); вы используете следующую перегрузку View method:

protected internal ViewResult View(
    string viewName, 
    string masterName 
) 

Так структура думает, что ваш model.DataElementNumber ваш VIEWNAME и ваш model.Version ваш masterName, поэтому вы получите этот странный взгляд отсутствующий исключение.

Чтобы исправить это вам просто нужно использовать correct overload с прохождением в вашем model

result = View(model); 

и MVC будет заботиться о повторном отображении вашего ранее размещенных значений DataElementNumber и версии.

+0

Я куплю это. Почему я не вижу такое же поведение при удалении валидатора? Я не изменил контроллер, но нашел правильный вид. –

+0

Да, потому что без валидатора ваша модель будет действительна и ваш код будет запущен или иначе, или потому, что ваши 'model.DataElementNumber' и' model.Version' пусты, поэтому MVC возвращается к своему поведению по умолчанию и ищет правильное представление. – nemesv

+0

: -О Я знал все это! Спасибо за обзор! –

Смежные вопросы