与表单的模型绑定:IEnumerable <modelname>与IEnumerable <object>

时间:2016-08-04 03:15:28

标签: asp.net asp.net-mvc

我正在尝试学习使用Asp.Net MVC进行编程,并且正在努力理解这一点。有人可以解释一下:

如果我使用以下ViewModel,Controller和View,POST方法中的ModelState.IsValid将计算为 true ,并且我能够处理表单中的数据。

视图模型

public class RegisterViewModel
{
    [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; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    public int UsersCompany { get; set; }

    [Display(Name = "Company")]
    public IEnumerable<object> Companies { get; set; }

    public IEnumerable<object> Roles { get; set; }
}

控制器

// GET: /Users/Create
public async Task<ActionResult> Create()
{
    RegisterViewModel registerViewModel = new RegisterViewModel();

    //Get the list of Roles
    var allRoles = await RoleManager.Roles.ToListAsync();

    registerViewModel.Roles = allRoles.ToList();
      ApplicationUser user = System.Web.HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()
            .FindById(System.Web.HttpContext.Current.User.Identity.GetUserId());

    var company = await db.CompanyModels.FindAsync(user.CompanyModelId);

    var companyAcct = await db.CompanyAccountModels.FindAsync(company.CompanyAccountModelId);

    var companies = db.CompanyModels
            .Where(c => c.CompanyAccountModelId == companyAcct.Id);

    registerViewModel.UsersCompany = user.CompanyModelId;
    registerViewModel.Companies = companies;

    return View(registerViewModel);
}

查看代码段

<div class="form-group">
    @Html.LabelFor(c => c.Companies, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.DropDownListFor(c => c.Companies, new SelectList(Model.Companies, "Id", "CompanyName"), new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.Companies, "", new { @class = "text-danger" })
    </div>
</div>

但是如果我在ViewModel IEnumerable中使用一种MyModel,如下所示,在POST方法中检查ModelState时会发生以下错误:

消息&#34;参数转换类型&#39; System.String&#39;输入&#39; xyz.Models.CompanyModel&#39;失败,因为没有类型转换器可以在这些类型之间进行转换。&#34;串

我正在使用断点在调试器模式下看到的实时变量数据的值字段中读取此错误。

public class RegisterViewModel
{
    //snipped

    [Display(Name = "Company")]
    public IEnumerable<CompanyModel> Companies { get; set; }

    //snipped
}

所以主要的问题是为什么会发生这种情况,而相关的问题是我应该在这里做些什么。提前感谢您的任何反馈。

请随时评论我在此代码中所做的任何不良做法或愚蠢的事情。

1 个答案:

答案 0 :(得分:1)

Html.DropDownListFor方法中的第一个参数是下拉列表中所选项目将填充的值。

@Html.DropDownListFor(
    c => c.Companies, // the selected item in the collection (this is the problem line)
    new SelectList(Model.Companies, "Id", "CompanyName"), // the collection
    new { @class = "form-control" })

上面代码中的行试图将所选值从下拉列表(所选Id的{​​{1}}属性)绑定到整个CompanyModel集合。

CompanyModel工作的原因是因为MVC能够绑定所选值并将其转换为IEnumerable<object>,其中只有一个项目(这是一个公司IEnumerable<object>串)。 MVC可以弄清楚如何将Id绑定到"2",而不是IEnumerable<object>

您要做的是为所选值创建属性。这是一个例子:

IEnumerable<CompanyModel>
public class RegisterViewModel
{
    [Display(Name = "Company")]
    public IEnumerable<CompanyModel> Companies { get; set; }

    [Required]
    public int? SelectedCompanyId { get; set; }
}