У меня есть следующее в .NET MVC3 с использованием viewmodels.Я использую Razor и FluentValidation (но я также пробовал аннотации данных с теми же результатами).
Из представления:
@Html.DropDownListFor(model=>model.L2, Model.RegisteredL2s, "[Select One]")
Из контроллера:
[HttpGet]
[Authorize(Roles = "Supervisor")]
public ActionResult Edit(string siteId, bool? isNew)
{
SiteEditViewModel model = new SiteEditViewModel();
List<SelectListItem> items = RegisteredL2Repository.GetRegisteredL2List()
.Select(x => new SelectListItem() { Text = x.L2, Value = x.L2.Trim() })
.OrderBy(x => x.Text)
.ToList();
model.RegisteredL2s = items.AsEnumerable();
if(!isNew.HasValue)
{
model.IsNew = false;
}
if(isNew.HasValue && (bool)isNew)
{
model.IsNew = true;
return View(model);
}
if(model.IsNew)
{
return View(model);
}
model.ConvertModelToViewModel(SiteRepository.GetSite(siteId));
return View("Edit", model);
}
}
ИзViewModel:
[DisplayName("Site:")]
[TextboxLength(2)]
public virtual string SiteId { get; set; }
[DisplayName("L2:")]
public virtual string L2 { get; set; }
[DisplayName("Description:")]
[TextboxLength(50)]
public virtual string Description { get; set; }
public IEnumerable<SelectListItem> RegisteredL2s { get; set; }
public bool IsNew { get; set; }
public string OverallError { get; set; }
Из моего класса Validator (свободно):
public SiteEditValidator()
{
RuleFor(model => model.SiteId)
.NotEmpty()
.WithMessage("Site is required.")
.Length(2)
.WithMessage("Site must be 2 characters. Ex: 1C")
.Matches(@"^[0-9A-Za-z]{2}$")
.WithMessage("Site contains invalid characters. Only letters and numbers.");
RuleFor(model => model.L2)
.NotEmpty()
.WithMessage("L2 is required.")
.Length(2)
.WithMessage("L2 must be 2 characters. Ex: 30")
.Matches(@"^[\d]{2}$")
.WithMessage("L2 contains invalid characters. Only numbers are allowed.");
RuleFor(model => model.Description)
.NotEmpty()
.WithMessage("Description is required.")
.Length(3, 50)
.WithMessage("Description must be at least 3 characters and not more than 50.")
.Matches(@"^[\w\,\.\'\-\s]{3,50}$")
.WithMessage("Description contains some invalid characters.");
}
И сгенерированный HTML:
<div class="Edit-Field">
<div class="Edit-Field-Label" style="width: 5em">
<label for="SiteId">Site:</label>
</div>
<div class="Editor-For">
<input autocomplete="off" data-val="true" data-val-length="Site must be 2 characters. Ex: 1C" data-val-length-max="2" data-val-length-min="2" data-val-regex="Site contains invalid characters. Only letters and numbers." data-val-regex-pattern="^[0-9A-Za-z]{2}$" data-val-required="Site is required." id="SiteId" maxlength="2" name="SiteId" readonly="readonly" style="width: 2.5em; background-color: LightGrey" type="text" value="30" />
<div class="Validation-For">
<span class="field-validation-valid" data-valmsg-for="SiteId" data-valmsg-replace="true"></span>
</div>
</div>
</div>
<div class="Edit-Field">
<div class="Edit-Field-Label" style="width: 5em">
<label for="L2">L2:</label>
</div>
<div class="Editor-For">
<select data-val="true" data-val-length="L2 must be 2 characters. Ex: 30" data-val-length-max="2" data-val-length-min="2" data-val-regex="L2 contains invalid characters. Only numbers are allowed." data-val-regex-pattern="^[\d]{2}$" data-val-required="L2 is required." id="L2" name="L2"><option value="">[Select One]</option>
<option value="30">30</option>
<option value="31">31</option>
<option value="32">32</option>
</select>
<div class="Validation-For">
<span class="field-validation-valid" data-valmsg-for="L2" data-valmsg-replace="true"></span>
</div>
</div>
</div>
<div class="Edit-Field">
<div class="Edit-Field-Label" style="width: 5em">
<label for="Description">Description:</label>
</div>
<div class="Editor-For">
<input autocomplete="off" data-val="true" data-val-length="Description must be at least 3 characters and not more than 50." data-val-length-max="50" data-val-length-min="3" data-val-regex="Description contains some invalid characters." data-val-regex-pattern="^[\w\,\.\'\-\s]{3,50}$" data-val-required="Description is required." id="Description" maxlength="50" name="Description" style="width: 30em" type="text" value="Central Office-Cash Receipts Unit" />
<div class="Validation-For">
<span class="field-validation-valid" data-valmsg-for="Description" data-valmsg-replace="true"></span>
</div>
</div>
</div>
Теперь проблема:
У меня есть поле L2, извлекаемое из предварительно заполненного IEnumerable (RegisteredL2s) и имеющее его в виде раскрывающегося списка (ID = L2, примерно середина HTML).L2 является обязательным и должен иметь определенную длину (2).Моя проблема в том, что даже когда пользователь выбрал что-то, кроме [Выберите один], появляется ошибка длины.Если я устраню эту ошибку, появится ошибка регулярного выражения.Проверка на стороне сервера при отправке работает правильно.Почему он это делает и как мне это остановить?Или я могу просто отключить клиентскую часть для этого поля?
Обновление: Мне кажется, я обнаружил проблему с jquery.validate.js ... Я хотел бы, чтобы кто-то подтвердилthis.
Вот исходные строки кода, которые я изменил и которые, кажется, устранили мою проблему: это строка 683. Строка 686 - это проблемная точка.
getLength: function(value, element) {
switch( element.nodeName.toLowerCase() ) {
case 'select':
return $("option:selected", element).length; case 'input':
if( this.checkable( element) )
return this.findByName(element.name).filter(':checked').length;
}
return value.length;
},
Я считаю, чтоКогда у вас есть требуемое раскрывающееся значение с валидатором длины, он генерирует ошибку.Когда я запускаю свой код, длина этой строки возвращается 1, а не 2. Если я изменяю жирную строку на return $("option:selected", element).val().length;
, она работает правильно.Любые комментарии, если это правильная ошибка и если мое исправление не будет мешать какой-либо другой части jquery.validation, будут полезны.
Это из jquery.validation 1.8.1 (обновлено с 1.7, так как я думалмои версии могут быть не синхронизированы) Jquery = 1.6.1.
Обновление 2: Не уверен, что это должен быть точный ответ, но:
Оказывается, что в соответствии с документацией JQuery.Validation для диапазона длины (что и является jquery.validation.unobtrusive конструкции для длины ровно 2) здесь В нем говорится, что для выбора (выпадающий список) он предназначен для того, чтобы убедиться, что выбрано определенное количество элементов, а не для проверки длины значения.
После проверки длины значения или выключения проверки на стороне клиента для этого конкретного элемента при сохранении проверки на стороне сервера.