【问题标题】:Create DropDownList for an ASP.NET MVC5 Relation [duplicate]为 ASP.NET MVC5 关系创建 DropDownList [重复]
【发布时间】:2014-05-05 14:12:57
【问题描述】:

我无法在 ASP.NET MVC5 中创建正确的创建/编辑视图。我有两个型号DogHuman。一只狗属于一个Human。我正在尝试在createedit 视图中为Dog 创建一个下拉列表,这将允许我为特定的Dog 按名称选择Human。这是我的模型:

人类:

public class Human
{
    public int ID { get; set; }
    public string Name { get; set; }
}

狗:

public class Dog
{
    public int ID { get; set; }
    public string Name { get; set; }
    public Human Human { get; set; }
}

我的创建操作:

// GET: /Dog/Create
public ActionResult Create()
{
    ViewBag.HumanSelection = db.Humen.Select(h => new SelectListItem
    {
        Value = h.ID.ToString(),
        Text = h.Name
    });
    return View();
}

这是我观点的相关部分:

<div class="form-group">
    @Html.LabelFor(model => model.Human.Name, new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(model => model.Human, ViewBag.HumanSelection);
    </div>
</div>

运行时出现以下错误:

Compiler Error Message: CS1973: 'System.Web.Mvc.HtmlHelper<Test.Models.Dog>' has no applicable method named 'DropDownListFor' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

我是 C# 和实体框架的新手。我究竟做错了什么?有没有办法在不手动查询数据库的情况下做到这一点?像 Rails 中的收集表单助手之类的东西? 我学习了一堆旧的或太复杂的教程。

【问题讨论】:

标签: c# asp.net asp.net-mvc


【解决方案1】:

需要注意的是,如果使用DropDownListFor(x =&gt; x.Human),下拉列表的返回值应该是Human对象。

不是。在您自己的代码 sn-p 中,您将 SelectListItem 的值设置为人类的 ID。因此,当您提交表单时,您将收到您选择的 ID

将以下内容添加到您的模型中:

public int HumanId { get; set; }

将您的下拉列表绑定到该 int:

@Html.DropDownListFor(model => model.HumanId, (SelectList)ViewBag.HumanSelection);

现在,当您返回控制器时,使用该 ID 查找您想要的实际人类:

[HttpPost]
public ActionResult Create (CreateModel model)
{
    if(model.HumanId > 0)
    {
        model.Human = GetHumanByID(model.HumanId);
        //or however you want to get the Human entoty from your database
    }
}

这是一个简化的解决方案,但我怀疑您的主要困惑源于您希望从 DropDownList 接收一个 Human,而它实际上只会返回一个 int(ID)。

编辑

我没有关于您的数据模型的太多信息,但如果您使用实体框架,您的Dog 类可能会有一个名为HumanId 的外键属性。如果是这种情况,您甚至不需要像我之前向您展示的那样获取Human 实体。如果您将选定的 ID 放在 HumanId 属性中,Entity Framework 应该能够使用它来创建您想要的 Human/Dog 之间的关系。

如果是这种情况,最好在您的问题中详细说明这一点,否则这将是比实际确认更多的猜测。

编辑 2 这里跑题了

您的代码:

db.Humen

man的复数形式是menwomanwomen;但是对于human,它是humans :) Humen 听起来确实是一个很棒的建议;)

【讨论】:

  • 1.错误说它没有这样的方法。 2. 我数据库中的相应列称为 Human_ID 而不是 HumanID(就像我遇到的每个教程一样)。 VS 也不会让我自动完成 model.Human_ID。唯一有效的键是 model.Human。 3. 表名由框架自动生成。
  • 1.请详细说明。异常在哪里抛出?采取什么行动?最好解决你的问题,;所以每个人都知道。 2 重要的不是数据库列。如果您使用实体框架,您的代码运行相对独立于数据库。它更多地与您的实体类的设置方式有关。 3. 类似的答案,在实体框架的案例中,特定的数据库内容不应该是相关的。 4、关于不让你填写HumanId; 您需要自己添加该属性。只有这样你才能使用它。
  • 另外,操作 Human_ID col 不是直接破坏了使用 EF 的全部意义吗?我来自 Rails,我认为它会自动处理这些事情。它自动创建表和 Human_ID 列就好了。是否有类似的帮助方法可以让我直接使用对象?
  • 我不打算告诉你修改数据库列。关键是,如果您使用的是 EF,您的实体类中很可能会有模仿数据库外键列的属性。如果您在您的实体中(而不是数据库)填写 HumanId,EF 应该选择它,并确保将正确的数据添加到数据库中。一般来说,实体框架会为您处理数据库。您所要做的就是确保正确设置实体(即类)并包含正确的数据。
  • 我同意将人类作为人类的复数形式。又跑题了。
【解决方案2】:

问题是您试图将Human 类型绑定到 UI 中的下拉列表,下拉列表的值是字符串(Human 实例的 ID)和文本也是字符串(@987654323 的名称@ 实例)。

您应该绑定到下拉列表的是 Human 的 ID,以匹配 ID 被用作值的事实。因此,使用诸如

之类的视图模型
public class CreateDogModel 
{
    public string Name { get; set; }

    [Range(0, int.MaxValue)]
    public int Human { get; set; }

    public IEnumerable<Human> Humans { get; set; }
}

还有 GET 控制器操作

[HttpGet]
public ActionResult Create()
{
    var model = new CreateDogModel 
    {
         Humans = db.Human.ToList()
    };

    return View(model);
}

然后视图变成

@Html.DropDownListFor(
    model => model.Human, 
    Model.Humans.Select(h => new SelectListItem 
        { 
            Text = h.Name, 
            Value = h.ID.ToString() 
        }),
    "Please select a Human");

在您的 POST 控制器操作中,您现在通过 View 模型中的 Human 属性值查找所选人员

[HttpPost]
public ActionResult Create(CreateDogModel model)
{
    if (!ModelState.IsValid)
    {
        // fetch the humans again to populate the dropdown
        model.Humans =  db.Human.ToList();
        return View(model);
    }

    // create and persist a new dog

    return RedirectToAction("Index");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多