我有一个DropDownList,其中填充了一个由(匿名类型)生成的SelectList,它有两个属性“CountryId”(int)和“Description”(字符串)。我希望列表中的所选国家/地区为defaultCountry。
Countries = new SelectList(countries, "CountryId", "Description", defaultCountry.CountryId);
其中“countries”是Linq查询中的匿名类型的IQueryable。国家是视图模型上的公共财产:
public class CountryBaseViewModel
{
public SelectList Countries { get; set; }
public Contact Contact { get;set; }
....
}
HTML看起来像这样:
<p>
<label for="CountryId">Home Country:</label>
<%= Html.DropDownList("CountryId", Model.Countries)%>
</p>
这很好,当我加载页面时,选择了正确的国家/地区。
但是当我将更改提交给控制器上的Edit方法时,绑定似乎失败了。
例如,当我使用以下HTML
时<p>
<label for="Contact.Job">Job/Post:</label>
<%= Html.TextBox("Contact.Job", Model.Contact.Job) %>
</p>
我称之为方法
public ActionResult Create(Contact contact)
在控制器上,然后从TextBox正确填写contact.Job值,但CountryId没有。
我认为MVC使用“Contact.Job”(TextBox 1st)参数来设置它。但是DropDownList的第一个参数是“CountryId”而不是“Contact.CountryId”,因为如果是,则在加载时列表中不会显示所选的值。
看起来TextBox的第一个参数用于数据绑定,而DropDownList的第一个参数是查找所选项目。
如何使用这种数据绑定方式在DropDownList中获取所需的值,然后将其与Model.Contact.Country绑定?
答案 0 :(得分:3)
您必须手动绑定下拉列表中的选定值,在POST中调用的控制器操作中查找实际需要绑定的实体。您可以按照第二篇文章中的建议在ViewModel中使用强类型值,也可以在ViewData包中查找下拉列表的值。
因此,您拥有大部分内容,但在处理POST的控制器操作中,您需要获取下拉列表的值,加载与该值关联的实体,然后将该实体附加到你试图更新的对象。根据您的体系结构,它通常只是对存储库或数据访问服务的简单调用。在持久保存对您正在使用的主对象的更改之前,您将执行该手动绑定。
答案 1 :(得分:1)
这可能不是最优雅的解决方案,但我这样做的方法是在ActionResult中手动设置对象的选定值:
contact.CountryID = Request.Form("CountryId")
我觉得可能有更好的解决方案,但我不知道它是什么。
答案 2 :(得分:0)
找到另一种方式,虽然我不认为它是理想的!
如果我将CountryId添加到视图模型并使用它来设置所选项目,那么它会在更改时填充。
然后我做
contact.CountryId = Model.CountryId
仍感觉不太好。