DropDownListFor总是给出null

时间:2013-05-07 00:47:55

标签: asp.net-mvc entity-framework

模型

public class Cidade
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string Nome { get; set; }
}

public class Usuario
{
    [Key]
    public int Id { get; set; }

    [Required]
    public Cidade Cidade { get; set; }

    /* more fields... */
}

控制器

public ActionResult Registrar()
{
    using (var db = new MyContext())
    {
        ViewBag.Cidades = new SelectList(db.Cidades.ToList(), "Id", "Nome");
    }
    return View();
}

[HttpPost]
public ActionResult Registrar(Usuario usuario)
{
    if (ModelState.IsValid)
    {
        using (var db = new MyContext())
        {
            db.Usuarios.Add(usuario);
            db.SaveChanges();
        }

        return RedirectToAction("Index", "Home");
    }

    return Registrar();
}

查看

@Html.LabelFor(m => m.Cidade)
@Html.DropDownListFor(m => m.Cidade, (SelectList)ViewBag.Cidades)

但总是ModelState.IsValid == false,因为usuario.Cidade == null

:(

1 个答案:

答案 0 :(得分:1)

绑定到模型的属性,而不绑定到模型本身。所以不要这样做

@Html.DropDownListFor(m => m.Cidade, (SelectList)ViewBag.Cidades)

你需要这样做

@Html.DropDownListFor(m => m.Cidade.Id, (SelectList)ViewBag.Cidades)

但这可能无法完全解决您的问题,因为您有一个必需的名称属性。但是,您使用模型的方式也不是您希望在视图中使用它的方式。因此,您应该问自己的问题是:您是否在视图中创建了Cidade以及Usuario?我认为答案是“不”。我根据您的问题了解您的设置的方式是,您希望将Cidade分配给您正在创建/编辑的Usuario

这又是另一种情况,你将使用viewmodels,这是一种标准做法,特别是对于这种事情。如果您不想使用viewomdel,那么您至少应该将Usuario更改为:

public class Usuario
{
    [Key]
    public int Id { get; set; }

    public Cidade Cidade { get; set; }

    [Required]
    public int CidadeId { get; set; }
}

注意额外的CidadeId并将其标记为必需。在您的视图中,您将执行此操作:

@Html.DropDownListFor(m => m.CidadeId, (SelectList)ViewBag.Cidades)

<强>更新

  

唯一不方便的事情是必须看到“Cidade”为null时   调试。很高兴见到它。

这真的没有必要,也不是一个好方法。但是,如果你真的觉得它适合你的项目,它仍然可以做到。因此,您添加了一个隐藏字段,该字段将映射到Cidade.Nome

@Html.HiddenFor(m => m.Cidade.Nome)
// then change your binding again to this
@Html.DropDownListFor(m => m.Cidade.Id, (SelectList)ViewBag.Cidades)

添加脚本以在下拉列表更改时填充该字段:

$("#Cidade_Id").change(function(){
    $("#Cidade_Name").val($(this).text());
});