我正在尝试使用MVC5和EF6.1定制标识(2.1)。我在Identity users表中添加了一个CountryId,并在CountryId上添加了一个完整的独立国家表(CountryId,CountryName)和FK约束。我正在尝试做一个下拉列表,如果用户在过去已经选择过它(从user表中的CountryId ),它将选择用户国家。但是,如果它尚未被选中,则该值将为空。
我想要实现的逻辑是:
if (Model.Country.CountryName != null) {
@Html.DropDownListFor(m => m.Country, new SelectList(Model.Countries, "Value", "Text"), Model.Country.CountryName)<br />
} else {
@Html.DropDownListFor(m => m.Country, new SelectList(Model.Countries, "Value", "Text"), "Select a Country")<br />
}如果删除上面的If else语句(这两种语句都不起作用),则每个DropDownListFor本身都能工作,但前者在CountryName为null时抛出一个NullRefernceException。后者根本不记得用户在过去选择了什么。这是我的控制器:
var userId = User.Identity.GetUserId();
ApplicationUser user = await UserManager.FindByIdAsync(userId);
var model = new IndexViewModel
{
HasPassword = HasPassword(),
//PhoneNumber = await UserManager.GetPhoneNumberAsync(userId),
//TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId),
//Or we can write like this because of the user statement above.
//PhoneNumber = user.PhoneNumber,
//TwoFactor = user.TwoFactorEnabled,
Logins = await UserManager.GetLoginsAsync(userId),
BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userId),
Country = user.Country,
State = user.State,
City = user.City,
Countries = new SelectList(db.Countries, "CountryId", "CountryName")
};
return View(model);如果我在我的控制器模型中使用这样的东西:
Countries = new SelectList(db.Countries, "CountryId", "CountryName", user.Country.CountryName)然后它向控制器抛出一个NullReferenceException。我明白为什么会发生这样的事,但是对于我的生活来说,在半天的搜寻之后,我还是找不到答案。
我只是想知道是否有一种干净的方法来处理空值,因此,如果CountryId是空的,那么传递一个不同的默认值?
任何帮助都是非常感谢的。
编辑:,我忘了提到视图模型。基本上,我将所有这些添加到IndexViewModel中(尽管我不确定此时是否需要这些):
public int CountryId { get; set; }
public int StateId { get; set; }
public int CityId { get; set; }
public virtual Country Country { get; set; }
public virtual State State { get; set; }
public virtual City City { get; set; }
public IEnumerable<SelectListItem> Countries { get; set; }
public IEnumerable<SelectListItem> States { get; set; }
public IEnumerable<SelectListItem> Cities { get; set; }发布于 2015-05-22 01:46:00
首先,不能将下拉列表绑定到复杂类型。Html对您的c# Country类没有概念。您需要绑定到您的CountryId属性
@Html.DropDownListFor(m => m.CountryId , Model.Countries)还要注意的是,Countries已经是一个SelectList了,所以它有点没有意义,而且不必要的额外开销,然后从它创建另一个SelectList,所以它只是Model.Countries,而不是new SelectList(Model.Countries, "Value", "Text")
接下来,绑定到属性(CountryId),因此它的值CountryId决定选择哪个选项-第三个参数(Model.Country.CountryName)被忽略。但是即使不是,它也不会选择任何东西,因为选项的value属性是CountryId属性的值,而不是CountryName属性。如果存在CountryId,则需要在控制器中设置Country的值。
最后,if (Model.Country.CountryName != null) {抛出一个异常,因为Country的值是null (不能访问null对象的CountryName属性)。
if/else块是完全不必要的,您只需要视图中的一行代码即可。
@Html.DropDownListFor(m => m.CountryId , Model.Countries, "-Please select-")如果CountryId的值是0 (int的默认值),那么将选择"-Please select-“选项。如果CountryId的值与集合中的值之一匹配,则在呈现视图时将选择该选项。因为CountryId是int类型,所以如果用户没有选择有效的国家,就会产生验证错误。
最后,尽管使用了IndexViewModel命名,但它不是视图模型!视图模型只包含在视图中显示/编辑的属性,因此应该删除所拥有的3个虚拟属性(可能还有与States和Cities相关的4个属性,但不确定是否从视图和控制器中省略了一些代码)。
https://stackoverflow.com/questions/30375302
复制相似问题