Почему ASP.NET MVC Html.CheckBox выводит два INPUT с одинаковым именем?
Почему в мире так делают строки:
<%= Html.CheckBox("ForSale", Model.Product.ForSale)%> For Sale
результат в следующем HTML:
<input id="ForSale" name="ForSale" type="checkbox" value="true" />
<input name="ForSale" type="hidden" value="false" />
For Sale
Теперь, когда я проверяю флажок и доступ Request.Form["ForSale"]
Я получаю нелепый ответ "true,false"
, Я должен разобрать это?
Это скрытое поле не отображается для других элементов управления HtmlHelper, так почему оно используется для CheckBox?
Как мне отключить эту глупую "функцию"? Или сделал HtmlHelper
просто перерасти свою полезность?
Обновить
Из приведенного ниже ответа кажется, что за этим стоит некоторая логика. Я подготовил небольшой метод расширения, поэтому мне не нужно об этом думать (спасибо @eu-ge-ne):
public static bool GetCheckBoxValue(this System.Web.HttpRequestBase req,
string name) {
return Convert.ToBoolean(req.Form.GetValues(name).First());
}
7 ответов
Это заставляет поле быть включенным, если оно не отмечено. Если вы снимите флажок, он не будет отправлен как часть страницы - они будут отправлены, только если они отмечены, и тогда будет значение true. Скрытое поле гарантирует, что false будет отправлено, если флажок снят, поскольку скрытое поле всегда отправляется.
Я выбрал другой подход:
Не используйте вспомогательный метод Html.CheckBoxFor или Html.CheckBox для визуализации флажка, но визуализируйте его с использованием обычного HTML:
<input id="ShowOther" name="ShowOther" value="<%=Model.ShowOther %>" type="checkbox" <% if (Model.ShowOther) { %>checked="checked"<% } %> />
И я добавил скрипт jQuery, который устанавливает значение, когда флажок установлен / снят.
<script type="text/javascript">
$(function() {
$('#ShowOther').click(function() {
var checked = $(this).attr('checked');
if (checked != undefined)
$(this).val(true);
else
$(this).val(false);
});
});
</script>
Насколько я мог проверить это, кажется, что правильное значение всегда отправляется в контроллер, и больше никаких проблем с "true, false".
Вот как я это сделал в одном из моих приложений. Расстраивает, но, похоже, работает.
public virtual ActionResult Edit(int id, FormCollection values)
{
SomeObject dbData = _repository.GetSomeObject(id);
try
{
UpdateModel(dbData);
if (values.GetValues("CheckBoxId").Contains("true"))
dbData.SomeBooleanProperty = true;
else
dbData.SomeBooleanProperty = false;
_repository.Save();
Session["Success"] = "Successfully edited the part.";
return RedirectToAction("Index");
}
catch
{
// Handle validation errors here
return View(new SomeObjectFormViewModel(dbData));
}
}
Надеюсь это поможет. Если у вас есть дополнительные вопросы, просто оставьте комментарий, и я обновлю свой ответ соответственно.
Теперь, когда бы я ни поставил галочку и получил доступ к Request.Form["ForSale"], я получал нелепый ответ "true,false". Я должен разобрать это?
Попробуй это:
var ForSale = Convert.ToBoolean(Request.Form.GetValues("ForSale").First());
ОБНОВЛЕНО:
Что если в следующей сборке MVC он вернет значение в обратном порядке "false, true"? ... - вдохновитель
var ForSale = Request.Form.GetValues("ForSale")
.Select(x => x.ToUpperInvariant()).Contains("TRUE");
// or
// FormatException can be thrown from Convert.ToBoolean()
var ForSale = Request.Form.GetValues("ForSale")
.Select(x => Convert.ToBoolean(x)).Contains(true);
Если флажок не отмечен, он не будет включен в отправку формы. Так что эта "функция" дает вам результат для каждого CheckBox. Те, которые не проверены, будут просто "ложными".
Я реализовал свои собственные вспомогательные функции CheckBox, которые работают по-разному. Большую часть времени я хочу не просто true или false, а просто набор значений отмеченных флажков. Он отлично подходит для выбора определенных предметов по их идентификатору, для которого нужно выполнить действие. Я не хочу непроверенные элементы даже в списке.
Вы можете взглянуть на исходный код для расширений HTML и использовать аналогичную структуру для создания собственных методов CheckBox.
http://aspnet.codeplex.com/sourcecontrol/changeset/view/23011?projectName=aspnet
Я бы опубликовал свой, но я не использую стандартный класс HtmlHelper, так что это, вероятно, будет более запутанным. Я добавил параметр value в свои функции CheckBox, чтобы я мог использовать определенное значение id вместо "true" или "false".
Пытаться
request.form["chkBoxes"].replace("false","").split(new char[] {','}, stringsplitoptions.removeemptyentries);
Я думаю, что самое чистое решение - это сделать:
(bool)formCollection["key"].ConvertTo(typeof(bool))