我对如何有效地使用ASP.NET MVC的Html.DropDownList帮助器感到困惑。
背景:我有一个5页的表单,每次单击“下一步”时都会将数据保存到表单中。用户可以在不同部分之间来回导航,因此之前的部分已预先填充了先前输入的数据。
这适用于TextBoxes。但不是DropDownLists。我尝试了很多不同的方法,包括:
我有一个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");
}
}
我的控制器在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));
}
}
我的观点在做:
<%: Html.DropDownList("ConsultantRegistration.BankBranchCountry",ViewData["bankBranchCountrySelectList"] as SelectList) %>
这给了我错误:
数据绑定: 'IWW.ArrowPay.ConsultantRegistration.Data.Country' 不包含属性 名称'BankBranchCountry'。
它做了什么,看看这个属性的架构:
public interface IConsultantRegistration
{
Guid ID { get; set; }
[DisplayName("Branch Country")]
string BankBranchCountry { get; set; }
}
(我的LINQ-to-SQL类型ConsultantRegistration实现了IConsultantRegistration)
但它似乎试图绑定到错误的类型?
如果我在我的视图中使用它(并使用我的Controller的Countries属性):
<%: Html.DropDownList("ConsultantRegistration.BankBranchCountry ",Model.Countries,"(select a Country)") %>
我保存的值很好,但我的模型在POST时没有更新。
如果我在我的观点中使用它:
<%: Html.DropDownListFor(model=>model.ConsultantRegistration.BankBranchCountry ",Model.Countries,"(select a Country)") %>
我获取了列表,然后将所选值POST回来,但不会在视图中预先选择模型中当前选定的项目。
所以我在整个地方都有一点解决方案,但不是全部在一个地方。
希望你能帮助填补我的无知。
答案 0 :(得分:1)
好的,我解决了。适当的hacky,但它完成了工作。
我在我的视图中使用ViewData:
<%: Html.DropDownList("bankBranchCountrySelectList", ViewData["bankBranchCountrySelectList"] as SelectList)%>
我的控制器中有以下内容:
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));
}
}
不理想并打破干净的编码。不知道它为什么会起作用,但这似乎是MVC所谓的“约定优于配置”。
答案 1 :(得分:0)
本文是以多选列表编写的,但该原则同样适用于单选下拉列表: