I am quite confused with how to effectively use the Html.DropDownList helper for ASP.NET MVC.
我对如何有效地使用ASP.NET MVC的Html.DropDownList帮助器感到困惑。
Background: I have a 5-page form, which saves data to the form each time "Next" is clicked. Users may navigate back and forth between sections, so previous sections will already be pre-populated with previously-entered data.
背景:我有一个5页的表单,每次单击“下一步”时都会将数据保存到表单中。用户可以在各部分之间来回导航,因此之前的部分已经预先填充了先前输入的数据。
This works for TextBoxes. But not DropDownLists. I have tried a load of different methods, including:
这适用于TextBoxes。但不是DropDownLists。我尝试了很多不同的方法,包括:
- How to add static list of items in MVC Html.DropDownList()
- Setting selected item to DropdownList in MVC Application?
如何在MVC Html.DropDownList()中添加静态项目列表
在MVC应用程序中将所选项目设置为DropdownList?
I have a ViewModel such taht I have got my lists and my Model (a LINQ-to-SQL generated class) as properties. eg:
我有一个ViewModel这样的taht我有我的列表和我的模型(一个LINQ-to-SQL生成的类)作为属性。例如:
public class ConsultantRegistrationFormViewModel
{
public IConsultantRegistration ConsultantRegistration { get; private set; }
public SelectList Titles { get; private set; }
public SelectList Countries { get; private set; }
public SelectList Currencies { get; private set; }
public int CurrentSection { get; private set; }
private ConsultantRegistrationFormViewModel(IConsultantRegistration consultantRegistration)
{
ConsultantRegistration = consultantRegistration;
CurrentSection = 1;
Titles = new SelectList(new string[] { "Mr", "Mrs", "Miss", "Ms", "Dr", "Sir" });
Countries = new SelectList(countries.Select(q => q.Name));
Currencies = new SelectList(currencies,"CurrencyCode","FriendlyForm");
}
}
My Controller's Edit Action on GET looks like:
我的控制器在GET上的编辑操作如下所示:
public class ConsultantRegistrationController : Controller
{
public IConsultantRegistrationRepository ConsultantRegistrationRepository { get; private set; }
public ICountryRepository CountryRepository { get; private set; }
public IEnumerable<ICountry> Countries { get; private set; }
public ConsultantRegistrationController()
{
ConsultantRegistrationRepository = RepositoryFactory.CreateConsultantRegistrationRepository();
CountryRepository = RepositoryFactory.CreateCountryRepository();
Countries = CountryRepository.GetCountries().ToArray();
}
public ActionResult Edit(Guid id, int sectionIndex)
{
IConsultantRegistration consultantRegistration = ConsultantRegistrationRepository.GetConsultantRegistration(id);
SelectList bankBranchCountriesSelectList = new SelectList(Countries, "BankBranchCountry", "CountryName", consultantRegistration.BankBranchCountry);
ViewData["bankBranchCountrySelectList"] = bankBranchCountriesSelectList;
return View(new ConsultantRegistrationFormViewModel(consultantRegistration,sectionIndex, Countries,Currencies));
}
}
With my View doing:
用我的View做:
<%: Html.DropDownList("ConsultantRegistration.BankBranchCountry",ViewData["bankBranchCountrySelectList"] as SelectList) %>
This gives me the error:
这给了我错误:
DataBinding: 'IWW.ArrowPay.ConsultantRegistration.Data.Country' does not contain a property with the name 'BankBranchCountry'.
DataBinding:'IWW.ArrowPay.ConsultantRegistration.Data.Country'不包含名为'BankBranchCountry'的属性。
Which it does, have a look at the schema of this property:
它做了什么,看看这个属性的架构:
public interface IConsultantRegistration
{
Guid ID { get; set; }
[DisplayName("Branch Country")]
string BankBranchCountry { get; set; }
}
(My LINQ-to-SQL type ConsultantRegistration implemented IConsultantRegistration)
(我的LINQ-to-SQL类型ConsultantRegistration实现了IConsultantRegistration)
It seems that it is trying to bind to the wrong type, though?
看来它似乎试图绑定到错误的类型,但是?
If I use this in my view (and use my Controller's Countries property):
如果我在我的视图中使用它(并使用我的Controller的Countries属性):
<%: Html.DropDownList("ConsultantRegistration.BankBranchCountry ",Model.Countries,"(select a Country)") %>
I get the saved value fine, but my model doesn't update on POST.
我得到保存的值很好,但我的模型不会在POST上更新。
And if I use this in my view:
如果我在我的观点中使用它:
<%: Html.DropDownListFor(model=>model.ConsultantRegistration.BankBranchCountry ",Model.Countries,"(select a Country)") %>
I get the list, and it POSTs the selected value back, but does not pre-select the currently selected item in my model on the view.
我得到了列表,并且它返回了所选值,但是没有在视图中预先选择模型中当前选定的项目。
So I have a bit of the solution all over the place, but not all in one place.
所以我在整个地方都有一些解决方案,但不是全部在一个地方。
Hope you can help fill in my ignorance.
希望你能帮助填补我的无知。
2 个解决方案
#1
1
Ok, I solved it. Proper hacky, but it gets the job done.
好的,我解决了。适当的hacky,但它完成了工作。
I'm using the ViewData in my view:
我在我的视图中使用ViewData:
<%: Html.DropDownList("bankBranchCountrySelectList", ViewData["bankBranchCountrySelectList"] as SelectList)%>
With the following in my controller:
在我的控制器中有以下内容:
public ActionResult Edit(Guid id, int sectionIndex)
{
IConsultantRegistration consultantRegistration = ConsultantRegistrationRepository.GetConsultantRegistration(id);
ViewData["bankBranchCountrySelectList"] = Countries.Select(q => new SelectListItem() { Text = q.Name, Value = q.Name, Selected = (q.Name.Trim().Equals(consultantRegistration.BankBranchCountry, StringComparison.InvariantCultureIgnoreCase)) }); // bankBranchCountriesSelectList;
return View(new ConsultantRegistrationFormViewModel(consultantRegistration,sectionIndex, Countries,Currencies));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, int sectionIndex, FormCollection formValues)
{
IConsultantRegistration consultantRegistration = ConsultantRegistrationRepository.GetConsultantRegistration(id);
UpdateModel(consultantRegistration);
ViewData["bankBranchCountrySelectList"] = Countries.Select(q => new SelectListItem() { Text = q.Name, Value = q.Name, Selected = (q.Name.Trim().Equals(consultantRegistration.BankBranchCountry, StringComparison.InvariantCultureIgnoreCase)) });
IEnumerable<RuleViolation> ruleViolations = consultantRegistration.GetRuleViolations(sectionIndex);
if (ruleViolations.Count() == 0)
{
// ...
}
else
{
ModelState.AddRuleViolations(ruleViolations);
return View(new ConsultantRegistrationFormViewModel(consultantRegistration, sectionIndex, Countries, Currencies));
}
}
Not ideal and breaks clean coding. No idea why it works, but that seems to be what MVC is all about with "convention over configuration".
不理想,打破干净的编码。不知道它为什么会起作用,但这似乎是MVC与“约定优于配置”的关系。
#2
0
This article was written with Multi-Select Lists in mind, but the principle applies equally to a single-selection drop down list:
本文是在考虑多选列表的情况下编写的,但该原则同样适用于单选下拉列表:
#1
1
Ok, I solved it. Proper hacky, but it gets the job done.
好的,我解决了。适当的hacky,但它完成了工作。
I'm using the ViewData in my view:
我在我的视图中使用ViewData:
<%: Html.DropDownList("bankBranchCountrySelectList", ViewData["bankBranchCountrySelectList"] as SelectList)%>
With the following in my controller:
在我的控制器中有以下内容:
public ActionResult Edit(Guid id, int sectionIndex)
{
IConsultantRegistration consultantRegistration = ConsultantRegistrationRepository.GetConsultantRegistration(id);
ViewData["bankBranchCountrySelectList"] = Countries.Select(q => new SelectListItem() { Text = q.Name, Value = q.Name, Selected = (q.Name.Trim().Equals(consultantRegistration.BankBranchCountry, StringComparison.InvariantCultureIgnoreCase)) }); // bankBranchCountriesSelectList;
return View(new ConsultantRegistrationFormViewModel(consultantRegistration,sectionIndex, Countries,Currencies));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, int sectionIndex, FormCollection formValues)
{
IConsultantRegistration consultantRegistration = ConsultantRegistrationRepository.GetConsultantRegistration(id);
UpdateModel(consultantRegistration);
ViewData["bankBranchCountrySelectList"] = Countries.Select(q => new SelectListItem() { Text = q.Name, Value = q.Name, Selected = (q.Name.Trim().Equals(consultantRegistration.BankBranchCountry, StringComparison.InvariantCultureIgnoreCase)) });
IEnumerable<RuleViolation> ruleViolations = consultantRegistration.GetRuleViolations(sectionIndex);
if (ruleViolations.Count() == 0)
{
// ...
}
else
{
ModelState.AddRuleViolations(ruleViolations);
return View(new ConsultantRegistrationFormViewModel(consultantRegistration, sectionIndex, Countries, Currencies));
}
}
Not ideal and breaks clean coding. No idea why it works, but that seems to be what MVC is all about with "convention over configuration".
不理想,打破干净的编码。不知道它为什么会起作用,但这似乎是MVC与“约定优于配置”的关系。
#2
0
This article was written with Multi-Select Lists in mind, but the principle applies equally to a single-selection drop down list:
本文是在考虑多选列表的情况下编写的,但该原则同样适用于单选下拉列表: