ModelState недействителен при отправке флажка в установленном флажке
У меня возникла следующая проблема: если я передам форму, содержащую проверочное значение в флажке, в контроллер api через AJAX, объект ModelState говорит, что он недействителен.
Предпосылки:
- Visual Studio 2012
- Фирменный стиль ASP.NET MVC 4
- Последние jQuery и jQuery ненавязчивые материалы проверки (версии 1.8.2 и 1.9.0.1)
Шаги для воспроизведения:
- Создал ViewModel для формы, содержащий поле Boolean:
public class CheckboxViewModel
{
[Display(Name="Test checkbox")]
public bool TestCheckbox { get; set; }
}
- Создано действие контроллера, которое просто подготавливает форму ViewModel и визуализирует:
public ActionResult Index()
{
return View(new CheckboxViewModel());
}
- Создал представление с формой
@using (Ajax.BeginForm("Post", "api/Values", null, new AjaxOptions { HttpMethod = "POST" }, new { id = "form" }))
{
@Html.ValidationSummary(true)
@Html.LabelFor(model => model.TestCheckbox)
@Html.EditorFor(model => model.TestCheckbox)
@Html.ValidationMessageFor(model => model.TestCheckbox)
<input type="submit" value="Submit" />
}
- Создано действие веб-API, которое проверяет, является ли modelstate действительным, и возвращает код состояния 200, иначе 400:
public HttpResponseMessage Post(CheckboxViewModel model)
{
if (!ModelState.IsValid)
return new HttpResponseMessage(HttpStatusCode.BadRequest);
return new HttpResponseMessage(HttpStatusCode.OK);
}
Я сделал несколько поисковых запросов, и я знаю, что редактор для флажка предоставляет дополнительное скрытое поле, но, похоже, он подходит и необходим для привязки модели.
Поэтому, когда я сниму флажок и отправлю форму, все работает нормально, сервер отвечает со статусом 200, благодаря скрытому полю, я полагаю. Однако, когда я делаю checkbox проверен и отправил форму, сервер отвечает со статусом 400, что означает, что ModelState находится в недопустимом состоянии. ModelState в этом случае содержит ошибку с пустым ErrorMessage и после сообщения об исключении:
{System.InvalidOperationException: The parameter conversion from type 'System.Collections.Generic.List`1[System.String]' to type 'System.Boolean' failed because no type converter can convert between these types.
в System.Web.Http.ValueProviders.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)
в System.Web.Http.ValueProviders.ValueProviderResult.UnwrapPossibleArrayType(CultureInfo culture, Object value, Type destinationType)
в System.Web.Http.ValueProviders.ValueProviderResult.ConvertTo(Type type, CultureInfo culture)
в System.Web.Http.ValueProviders.ValueProviderResult.ConvertTo(Type type)
в System.Web.Http.ModelBinding.Binders.TypeConverterModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)}
Я понятия не имею, как правильно это обрабатывать. Должен ли я создавать пользовательские привязки модели? Или я чего-то не хватает?
Любая помощь будет оценена по достоинству. Спасибо.
Я создал решение, которое воспроизводит мою проблему.
ОБНОВЛЕНИЕ: Я выяснил, что форма фактически содержит значения TestCheckbox: true
и TestCheckbox:false
, поэтому я думаю, что это может быть какое-то действие, затрагивающее связующее вещество и вызывающее исключение. По-прежнему нет параметров, как обходиться с этим.
Ответы
Ответ 1
Я столкнулся с той же проблемой, отправив форму в веб-API с JavaScript. Вот основное решение, которое вы можете использовать для решения этой проблемы. Я знаю, что это просто упрощенный или даже уродливый - и не очень практичный, если у вас много флажков. Однако идея проста и может быть легко расширена для удовлетворения ваших требований.
Добавьте это перед отправкой формы (используя jQuery):
if ($('[name="MyCheckbox"]:checked').length > 0)
$('[name="MyCheckbox"]:hidden').detach();
else if ($('[name="MyCheckbox"]:hidden').length < 1)
$('#myForm').append('<input type="hidden" name="MyCheckbox" value="false" />');
// Etc...
$.ajax({ });
Таким образом, вы удаляете скрытое поле, если флажок установлен, и вы добавляете его, если флажок не установлен, и скрытое поле уже удалено.
Смотрите этот скрипт: http://jsfiddle.net/Hsfdg/
Ответ 2
Я попытался реализовать этот
if ($('[name="MyCheckbox"]:checked').length > 0)
$('[name="MyCheckbox"]:hidden').detach();
else if ($('[name="MyCheckbox"]:hidden').length < 1)
$('#myForm').append('<input type="hidden" name="MyCheckbox" value="false" />');
Но в конечном итоге свойство модели удаляется, когда скрытый флажок снят.
Instad задает значение скрытого значения chechbox истинным результатам при установке свойства модели true для значения, ожидаемого иначе false по умолчанию.
if ($('[name="MyCheckbox"]:checked').length > 0)
$('[name="MyCheckbox"]:hidden').val(true);