MVC 5 DropDownListFor & Select 列表在 Post 上产生错误
MVC 5 DropDownListFor & Select List results in error on Post
所以我认为这会非常简单,但我很难弄明白。
首先,我将回顾一下目前为止的内容。
RegisterViewModel:
public class RegisterViewModel
{
[Display(Name = "First Name:")]
public string FirstName { get; set; }
[Display(Name = "Last Name:")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email:")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password:")]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Confirm password:")]
[System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Display(Name = "Please choose the category that best describes your professional relation to the field of Orthotics and Prosthetics:")]
public List<string> ProfessionalRelations { get; set; }
[Display(Name = "Please check all of the following that apply to you:")]
public List<string> UserRelations { get; set; }
[Required]
[Display(Name = "Country")]
public SelectList Countries { get; set; }
[Required]
[Display(Name = "EDGE Direct E-mail Newsletter:")]
public List<string> EdgeNewsletter { get; set; }
}
注意Select国家列表。
现在,在我的控制器中。当有人进入注册页面时,我按如下方式填充国家 Select 列表:
var countries = oandpService.GetCountries().OrderBy(x => x.CountryName).ToList();
var usa = countries.FirstOrDefault(x => x.CountryID == "US");
countries.Remove(usa);
countries.Insert(0, new Country() { CountryID = string.Empty, CountryName = string.Empty });
countries.Insert(1, usa);
rvm.Countries = new SelectList(countries, "CountryID", "CountryName");
最后,这是国家 DropDownListFor 视图的一部分:
@Html.DropDownListFor(x => x.Countries, Model.Countries, Model.Countries)
当您转到该页面时,这一切都显示正常。国家/地区下拉列表是使用 CountryID 作为值和 CountryName 作为显示文本生成的。
然后,为了测试单选按钮、复选框和下拉菜单,我有以下内容:
[HttpPost]
[ValidateAntiForgeryToken]
[ReCaptchaFilter]
public ActionResult Register(RegisterViewModel rvm)
{
ViewBag.Countries = rvm.Countries.SelectedValue;
ViewBag.UserRelation = rvm.UserRelations;
ViewBag.ProfessionalRelation = rvm.ProfessionalRelations;
return View(rvm);
}
除了我在 post 上收到以下错误:
- 没有为此对象定义无参数构造函数。
- 没有为此对象定义无参数构造函数。对象类型 'System.Web.Mvc.SelectList'.
谁能帮我指明正确的方向?我做了一些研究,但还没有弄明白。任何输入都会非常赞赏。
你用错了辅助方法!检查页面的查看源!您当前的代码正在生成名称为 "Countries" 的 SELECT 元素。提交表单时,将根据表单元素键 "Countries" 提交 selected 值。当模型绑定器尝试将此提交的值映射到您的 RegisterViewModel
的实例时,它会看到"Countries" 从类型 SelectList
开始(根据视图模型 class 定义)并且它无法从整数值构建 SelectList
对象(Selected CountryId 已提交来自表格 )。这就是您看到此错误的原因!之所以会这样,是因为你用错了辅助方法!
理想情况下,您应该添加另一个 属性 来保存 selected 值。
public class RegisterViewModel
{
[Required]
[Display(Name = "Country")]
public int SelectedCountry { set;get;}
public SelectList Countries { get; set; }
//Your existing properties goes here
}
并在视图中
@Html.DropDownListFor(x => x.SelectedCountry, Model.Countries )
并且在您的 HttpPost 操作中,您将在 SelectedCountry 属性
中获得 selected 选项值
public ActionResult Register(RegisterViewModel rvm)
{
var selectedCountry = rvm.SelectedCountry;
//to do : Reload Countries property of rvm again here(same as your GET action)
return View(rvm);
}
此外,要添加空 select 选项,您无需在控制器代码中添加空项,只需使用 DropDownListFor
辅助方法的重载即可。
@Html.DropDownListFor(x => x.SelectedCountry, Model.Countries,string.Empty)
所以我认为这会非常简单,但我很难弄明白。
首先,我将回顾一下目前为止的内容。
RegisterViewModel:
public class RegisterViewModel
{
[Display(Name = "First Name:")]
public string FirstName { get; set; }
[Display(Name = "Last Name:")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email:")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password:")]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Confirm password:")]
[System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Display(Name = "Please choose the category that best describes your professional relation to the field of Orthotics and Prosthetics:")]
public List<string> ProfessionalRelations { get; set; }
[Display(Name = "Please check all of the following that apply to you:")]
public List<string> UserRelations { get; set; }
[Required]
[Display(Name = "Country")]
public SelectList Countries { get; set; }
[Required]
[Display(Name = "EDGE Direct E-mail Newsletter:")]
public List<string> EdgeNewsletter { get; set; }
}
注意Select国家列表。
现在,在我的控制器中。当有人进入注册页面时,我按如下方式填充国家 Select 列表:
var countries = oandpService.GetCountries().OrderBy(x => x.CountryName).ToList();
var usa = countries.FirstOrDefault(x => x.CountryID == "US");
countries.Remove(usa);
countries.Insert(0, new Country() { CountryID = string.Empty, CountryName = string.Empty });
countries.Insert(1, usa);
rvm.Countries = new SelectList(countries, "CountryID", "CountryName");
最后,这是国家 DropDownListFor 视图的一部分:
@Html.DropDownListFor(x => x.Countries, Model.Countries, Model.Countries)
当您转到该页面时,这一切都显示正常。国家/地区下拉列表是使用 CountryID 作为值和 CountryName 作为显示文本生成的。
然后,为了测试单选按钮、复选框和下拉菜单,我有以下内容:
[HttpPost]
[ValidateAntiForgeryToken]
[ReCaptchaFilter]
public ActionResult Register(RegisterViewModel rvm)
{
ViewBag.Countries = rvm.Countries.SelectedValue;
ViewBag.UserRelation = rvm.UserRelations;
ViewBag.ProfessionalRelation = rvm.ProfessionalRelations;
return View(rvm);
}
除了我在 post 上收到以下错误:
- 没有为此对象定义无参数构造函数。
- 没有为此对象定义无参数构造函数。对象类型 'System.Web.Mvc.SelectList'.
谁能帮我指明正确的方向?我做了一些研究,但还没有弄明白。任何输入都会非常赞赏。
你用错了辅助方法!检查页面的查看源!您当前的代码正在生成名称为 "Countries" 的 SELECT 元素。提交表单时,将根据表单元素键 "Countries" 提交 selected 值。当模型绑定器尝试将此提交的值映射到您的 RegisterViewModel
的实例时,它会看到"Countries" 从类型 SelectList
开始(根据视图模型 class 定义)并且它无法从整数值构建 SelectList
对象(Selected CountryId 已提交来自表格 )。这就是您看到此错误的原因!之所以会这样,是因为你用错了辅助方法!
理想情况下,您应该添加另一个 属性 来保存 selected 值。
public class RegisterViewModel
{
[Required]
[Display(Name = "Country")]
public int SelectedCountry { set;get;}
public SelectList Countries { get; set; }
//Your existing properties goes here
}
并在视图中
@Html.DropDownListFor(x => x.SelectedCountry, Model.Countries )
并且在您的 HttpPost 操作中,您将在 SelectedCountry 属性
中获得 selected 选项值public ActionResult Register(RegisterViewModel rvm)
{
var selectedCountry = rvm.SelectedCountry;
//to do : Reload Countries property of rvm again here(same as your GET action)
return View(rvm);
}
此外,要添加空 select 选项,您无需在控制器代码中添加空项,只需使用 DropDownListFor
辅助方法的重载即可。
@Html.DropDownListFor(x => x.SelectedCountry, Model.Countries,string.Empty)