我知道已经有一些关于这个话题的线索,我跟着其中一些没有成功。
问题: 我有一个DropDownListFor,它有一个国家列表。当我选择一个国家并提交表单时,它会在数据库中正确保存,但是当我再次加载表单进行编辑时,它总是显示第一个项目。 我有其他下拉列表以类似的方式实现,他们正在正常工作。
我尝试了什么
我更改了属性的名称,因为我读到使用ViewBag传递列表来填充下拉列表时,它可能无法选择正确的值。没有成功。
我已经在ViewModel中替换了一个属性的viewbag。没有成功。
守则
查看:
<div class="input-group col-md-5">
@Html.DropDownListFor(model => Model.CountryCode, new SelectList(Model.Countries, "Alpha2Code", "Name"), new { @class = "form-control" })
</div>
控制器:
var userViewModel = await _userLogicLayer.GetUserViewModelAsync(MySession.UserId);
userViewModel.Countries = LocaleLogicLayer.Countries;
return View(userViewModel);
LocaleLogicLayer:
public static class LocaleLogicLayer
{
public static List<Country> Countries { get; set; }
static LocaleLogicLayer()
{
Countries = new List<Country>
{
new Country() {Alpha2Code = "PT", Name = "Portugal"},
new Country() {Alpha2Code = "BR", Name = "Brasil"},
new Country() {Alpha2Code = "XX", Name = "Outro"}
};
}
}
GetUserViewModelAsync
public async Task<UserViewModel> GetUserViewModelAsync(string userId)
{
var userProfile = await _userProfileRepository.GetAsync(userId);
var userViewModel = new UserViewModel();
if (userProfile != null)
{
userViewModel.Id = userProfile.Id;
userViewModel.LinkedInProfile = userProfile.LinkedInProfile;
userViewModel.Nif = userProfile.Nif;
userViewModel.Bi = userProfile.Bi;
userViewModel.Picture = userProfile.Picture;
userViewModel.CountryCode = userProfile.CountryCode;
}
return string.IsNullOrWhiteSpace(userViewModel.Id) ? null : userViewModel;
}
我感谢你的帮助。它必定是一个非常基本的错误,但我找不到它。 非常感谢你。
编辑(新方法)
新DropDownlList
@Html.DropDownListFor(model => model.CountryCode, (SelectList)ViewBag.CountriesX, new { @class = "form-control" })
(仍然没有工作,令人沮丧)
答案 0 :(得分:1)
Html.DropDownListFor
的第一个参数是lambda表达式,因此您应该传递model => model.CountryCode
而不是model => Model.CountryCode
(注意大小M差异)。我还建议将List<SelectListItem>
的实例作为Html.DropDownListFor
方法的第二个参数传递,并将其设置在UserViewModel
的构造函数中。
将您的模型类代码更改为以下内容,您需要做的是将Countries
属性的类型更改为List<SelectListItem>
并添加构造函数方法:
using System.Web.Mvc;
public class UserViewModel
{
public UserViewModel()
{
this.Countries = new List<SelectListItem>
{
new SelectListItem() { Text = "Portugal", Value = "PT" }
new SelectListItem() { Text = "Brasil", Value = "BR" }
new SelectListItem() { Text = "Outro", Value = "XX" }
};
}
public List<SelectListItem> Countries { get; set; }
.... // other existing properties
}
然后您的控制器代码应如下所示
var userViewModel = await _userLogicLayer.GetUserViewModelAsync(MySession.UserId);
return View(userViewModel);
和您的观看代码
<div class="input-group col-md-5">
@Html.DropDownListFor(model => model.CountryCode, Model.Countries, new { @class = "form-control" })
</div>
答案 1 :(得分:0)
首先尝试@ ekad的答案,因为这很可能是问题所在,你需要纠正这两种方式。但是,如果它仍无效,请尝试不创建自己的SelectList
。 SelectList
作为其构造函数的参数,选择一个您未传入的值,这意味着最初不会选择任何内容。如果@ ekad的答案足以解决您的问题,那么这意味着Razor会帮助您摆脱困境并设置所选值。
无论哪种方式,最好将IEnumerable<SelectListItem>
传递给Html.DropDownListFor
,您可以通过以下方式创建:
Model.Countries.Select(m => new SelectListItem { Value = m.Alpha2Code, Text = m.Name })
如果您使用视图模型,最好将其移动到您的操作代码中,并在视图模型上实际设置属性。然后你可以做类似的事情:
Html.DropDownListForm(m => m.CountryCode, Model.CountryChoices)
您的视图中的代码和逻辑要少得多,这总是一件好事。
答案 2 :(得分:0)
你没有选择一个值来下拉选中它! 试试你的html:
@Html.DropDownListFor(m => m.CountryCode,null,null)
您的代码是:
var userViewModel = await _userLogicLayer.GetUserViewModelAsync(MySession.UserId);
ViewBag.CountryID = new SelectList(LocaleLogicLayer.Countries,"Alpha2Code","Name",userViewModel.CountryCode);
return View(userViewModel);
答案 3 :(得分:0)
经过几个小时的研究,我终于找到了解决问题的方法: 我不明白的是为什么类似的代码适用于其他领域,而不是这个。在我将它绑定到另一个属性后,它完美地工作了。所以,我发现我的基本Controller类有一个静态属性:
ApplicationController.Locale.CountryCode = countryCode;
结论:我说得很好,但任何人都可以解释为什么会发生这种情况?对我来说,没有任何意义。
注意:看起来我们不需要在selectedList中传递selectedListItem。无论如何,它应该对代码一致性有好处并且不会受到伤害。 Problem with DropDownListFor SelectedItem
所有帖子都很有价值,我基于此改进了我的最终解决方案,感谢大家的时间和见解。