0

所以我认为这将是非常简单的,但我很难找出它。MVC 5 DropDownListFor&选择列表结果在邮政的错误

首先,我会回顾一下我到目前为止的情况。

的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; } 
} 

注意选择列表的各国。

现在,在我的控制器。当有人进入到注册页面,我填充国家选择列表如下:

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); 
} 

除了我收到后以下错误:此定义

  1. 无参数的构造函数目的。
  2. 没有为此对象定义的无参数构造函数。对象类型“System.Web.Mvc.SelectList”。

任何人都可以帮我指出正确的方向吗?我做了一些研究,但还没有弄清楚。任何输入将大大赞赏。

+0

*此对象定义无参数的构造函数。*不带参数的构造函数添加到您的控制器 –

+0

我已经有一个参数的构造函数,当人第一次进入该页面(而不是HTTP POST)。如果我尝试添加另一个ActionResult Register(),它表示AccountController已经使用相同的参数类型定义了一个名为Register的成员。 – ajtatum

+0

http://stackoverflow.com/a/12701768/4753489 –

回答

3

您正在使用帮助器方法错误!检查页面的视图源!您当前的代码正在生成名为“Countries”的SELECT元素。提交表单时,所选值将针对表单元素键“国家”提交。当模型联编程序尝试将此提交的值映射到您的RegisterViewModel的实例时,它将类型SelectList中的“国家/地区”(根据查看模型类定义),并且它不能从整数值(表单提交的选定国家/地区)中构建SelectList对象。这就是你看到这个错误的原因!所有这一切的原因是,因为你使用了辅助方法错误!

理想情况下,您应该添加另一个属性来保存选定的值。

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财产

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); 
} 

此外,加空选择选项,你不需要在你的控制器代码中添加一个空的项目,你可以简单地使用这个辅助方法的超载。

@Html.DropDownListFor(x => x.SelectedCountry, Model.Countries,string.Empty) 
+0

谢谢你的回应。但是,当我发布到控制器时,出现错误:没有类型为'IEnumerable '的ViewData项目具有“SelectedCountry”关键字。我如何填充DropDownList有什么问题吗?有以上,但它的:rvm.Countries =新的SelectList(国家,“国家ID”,“国家名称”);再次感谢你! – ajtatum

+0

另外,不知道它是否重要,但SelectedCountry是一个字符串。 – ajtatum

+0

@ajtatum,错误是由于您在POST方法中返回视图而导致的,但没有像在GET方法中那样重新填充SelectList(参考[this answer](http://stackoverflow.com/questions/34366305/the-viewdata-item-that-has-the-key-xxx-is-of-type-system-int32-but-must-be-o)) –