2010-04-09 47 views
1

我很困惑如何有效地使用ASP.NET MVC的Html.DropDownList助手。DropDownList不能在ASP.Net中工作100%MVC

背景:我有一个5页的表单,每次单击“下一步”时将数据保存到表单中。用户可以在部分之间来回导航,因此以前的部分将已经预填充了先前输入的数据。

这适用于TextBoxes。但不是DropDownLists。我曾尝试不同的方法的负载,包括:

我有一个视图模型等taht我有我的名单,我的模型(生成的LINQ到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"); 
    } 
} 

上得到我的控制器的编辑操作是这样的:

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) %> 

这给我的错误:

DataBinding: 'IWW.ArrowPay.ConsultantRegistration.Data.Country' does not contain a property with the name 'BankBranchCountry'.

它所做的,看看架构此属性的:

public interface IConsultantRegistration 
{ 
    Guid ID { get; set; } 


    [DisplayName("Branch Country")] 
    string BankBranchCountry { get; set; } 

} 

(我的LINQ到SQL类型ConsultantRegistration实现IConsultantRegistration)

看来,它正试图绑定到错误类型有关系吗?

如果我用这个在我看来(和使用我的控制器的国家属性):

 <%: Html.DropDownList("ConsultantRegistration.BankBranchCountry ",Model.Countries,"(select a Country)") %> 

我得到保存的值很好,但我的模型不会在之后的更新。

如果我用这个在我看来:在我的视图模型

 <%: Html.DropDownListFor(model=>model.ConsultantRegistration.BankBranchCountry ",Model.Countries,"(select a Country)") %> 

我得到的名单,并将其职位所选择的值改回,但不预先选择当前选定的项目。

所以我有一个解决方案遍布各地,但不是全部在一个地方。

希望你能帮助填补我的无知。

+0

你能为下拉菜单显示呈现的HTML吗? – 2010-04-09 11:51:57

+0

谢谢马尔科姆,抱歉,我现在不能。我太过于剽窃它,无法使用它。无论如何,它已经有了工作。 – 2010-04-09 14:44:24

回答

1

好吧,我解决了这个问题。适当的哈克,但它完成了工作。

我使用的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关于“约定优于配置”的全部内容。

+0

因此,您已将创建的下拉列表添加到编辑的GET和POST的编辑,对吧?我用同样的解决方案遇到了同样的问题,但我不明白: http://stackoverflow.com/questions/2365824/strongly-typed-view-with-a-selectlist-for-dropdownlist-via-viewdata -type-mismatc – Cymen 2010-04-09 19:15:04

+1

我在haacked.com上向Phil Haack发送了照明请求。希望他能解释发生了什么。如果他回应,我会再添加一条评论。 – Cymen 2010-04-09 19:23:42

+0

谢谢Cymen。 .. – 2010-04-10 09:12:09

0

文章在考虑多选择列表写的,但其原理同样适用于单一选择下拉列表:

http://www.stevefenton.co.uk/Content/Blog/Date/201002/Blog/How-To-Handle-Multiple-Select-Lists-In-ASP-NET-MVC/

+0

谢谢。这看起来或多或少是我自己如何做的。所以我仍然坚持,恐怕。 – 2010-04-09 10:36:59

+0

BankBranchCountry在调用“SelectList bankBranchCountriesSelectList = new SelectList(Countries,”BankBranchCountry“,”CountryName“,consultantRegistration.BankBranchCountry)之前明确填充了”; – Fenton 2010-04-09 10:49:17

+0

假设这是我认为它的工作原理,是的。 Edit操作从存储库/数据存储中获取已经保存的记录 - 然后处理SelectLists。问题是,这是否在视图之前运行 - 并且这很重要吗?我不知道。 – 2010-04-09 11:05:25