#asp.net-mvc #asp.net-mvc-3
#asp.net-mvc #asp.net-mvc-3
Вопрос:
Итак, у меня есть вызов модели представления ProductViewModel, который содержит список сайтов, на которых может быть произведен продукт. Я пытаюсь выяснить, как отобразить это в форме, используя флажок, позволяющий пользователю выбирать сайты, на которых может быть произведен продукт. Кажется простым, не так ли? Ну, это работает не так, как я хочу / нужно. Надеюсь, кто-нибудь может помочь мне указать правильный способ сделать это.
Мои классы:
public class ProductViewModel
{
public List<Sites> SiteList {get; set;}
public string ProductName {get; set;}
public int ProductId {get; set;}
public User ProductOwner{get; set;}
}
public class Sites
{
public int SiteId {get; set;}
public string SiteName {get; set;}
public bool IsSelected {get; set;}
}
Часть моего представления:
@Html.LabelFor(m=>m.Sites):
@foreach (var site in Model.Sites)
{
@Html.CheckBox("Sites", site.IsSelected, new { value = site.SiteName })
@Html.Label(site.SiteName)
}
При использовании @Html.Checkbox () Я вижу следующий вывод в html из браузера:
<input checked="checked" id="Sites" name="Sites" type="checkbox" value="Miami" />
<input name="Sites" type="hidden" value="false" />
Я понимаю скрытое поле, но что мне действительно нужно, так это получить значение для выбранного элемента. Итак, мне нужно вернуть список с Майами в нем. Мне не нужны значения false / true, которые, похоже, хочет отправить помощник html (т. Е. Miami = true)
Поэтому вместо этого я попробовал это.
@for(int id=0; id < Model.Sites.Count(); id )
{
<input type="checkbox" id="@Model.Sites[id].SiteName" name="Sites[@id]" value="@Model.BoxingSites[id].SiteName" @(Model.Sites[id].IsSelected ? @"checked=""checked""": "") />
@Html.Label(Model.Sites[id].SiteName)
}
И вывод такой:
<input type="checkbox" id="Miami" name="Sites[0]" value="Miami" checked=amp;quot;checkedamp;quot; />
<label for="Miami">Miami</label>
В обоих этих случаях я не могу заставить связующее средство сопоставить значения формы с продуктом.Список сайтов при публикации в действие.
Действие выглядит следующим образом:
[HttpPost]
public ActionResult Edit(ProductViewModel Product)
{
//Does something with the form data.
}
Другие значения (ProductName и т.д. …) Отображаются нормально.
Что я делаю не так? Я чувствую, что чего-то не хватает, поскольку это должно быть проще из-за того, как MVC упрощает множество других ситуаций с обработкой форм.
Заранее спасибо…
Комментарии:
1. вы также могли бы использовать помощник checkboxlist отсюда awesome.codeplex.com
2. @Omu — Спасибо за ссылку. Это действительно потрясающе. Я определенно буду использовать это и для некоторых других нужд.
Ответ №1:
Как насчет использования шаблона редактора вместо того, чтобы бороться с циклами:
@model ProductViewModel
@using (Html.BeginForm())
{
... some other form fields
@Html.LabelFor(x => x.SiteList)
@Html.EditorFor(x => x.SiteList)
<input type="submit" value="Create" />
}
и внутри соответствующего шаблона редактора ~/Views/Shared/EditorTemplates/Sites.cshtml
:
@model Sites
<div>
@Html.HiddenFor(x => x.SiteId)
@Html.CheckBoxFor(x => x.IsSelected)
@Html.LabelFor(x => x.SiteName)
</div>
Теперь не только ваш код представления намного более чистый, но и для полей ввода будут сгенерированы правильные имена, так что связующее устройство модели сможет привязать выбранные значения обратно к действию POST.
[HttpPost]
public ActionResult Create(ProductViewModel model)
{
...
}
Комментарии:
1. Вы только что показали мне отличный пример того, когда использовать шаблон. Это работает; однако я вижу странную проблему с ярлыком. @Html.LabelFor(x=>x.SiteName) отправляет «SiteName», а не «Miami» Есть идеи, почему?
2. О, я также заметил другие проблемы. При публикации сопоставление для SiteID, IsSelected работает, но SiteName равно null. Даже после переключения на @Html.Label (модель. Имя сайта).
3. @Racter, это значение равно нулю, потому что оно никогда не отправлялось на сервер. Вы могли бы включить его в качестве скрытого поля внутри шаблона:
@Html.HiddenFor(x => x.SiteName)
, так же, как вы сделали сSiteId
. Что касается вашего первого вопроса, вы могли бы заменить@Html.LabelFor(x => x.SiteName)
на@Html.DisplayFor(x => x.SiteName)
, если хотите отобразить значение.
Ответ №2:
Вот что работает у меня.
// View Model
[Display(Name="Boolean Property")]
[UIHint("booleancheckbox"]
public bool? booleanProperty;
Вид
// View
@Html.EditorFor(m => m.booleanProperty, new { @onclick = "Toggle(this);" })
Шаблон редактора — добавьте еще немного кода для обработки нулевых значений
// Editor Template booleancheckbox.cshtml
@model bool?
@{
labelText = ViewData.ModelMetadata.DisplayName != null ?
ViewData.ModelMetadata.DisplayName :
ViewData.ModelMetadata.PropertyName;
}
<label for="@ViewData.ModelMetadata.PropertyName">@labelText
@Html.CheckBox(string.Empty, Model.Value, ViewContext.ViewData)
</label>