【问题标题】:Populate DropDownList in ASP.NET MVC from database table using Entity Framework 6 and ViewModel使用 Entity Framework 6 和 ViewModel 从数据库表中填充 ASP.NET MVC 中的 DropDownList
【发布时间】:2017-07-21 20:04:40
【问题描述】:

我整晚都在为一个我可以使用 ajax/jquery 和存储过程快速解决的问题挠头。我想要

1) 从使用实体框架和视图模型的数据库表中获取的值填充下拉列表。我不想使用 VIEWBAG 或 VIEWDATA。任何帮助表示赞赏。

2) 如何使用具有所有默认字段的视图模型生成创建视图?脚手架适用于模型,但不适用于视图模型?

我的模特

public class Employee
{
    public int EmployeeID { get; set; }
    public string Name { get; set; }
    public string Gender { get; set; }
    public string City { get; set; }
    public string Level { get; set; }
    public int DepartmentId { get; set; }
}

public class Grade
{
    public int ID { get; set; }
    public string Level { get; set; }
}

查看模型

public class GradeSelectListViewModel
{

    public Employee Employee { get; set; }
    public IEnumerable<SelectListItem> Grades { get; set; }
    public GradeSelectListViewModel(Employee employee, IEnumerable grades)
    {
        Employee = employee;
        Grades = new SelectList(grades, "Grade", "Name", employee.Level);
    }
}

我的上下文类

public class EmployeeContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }
    public DbSet<Grade> Grades { get; set; }
}

我的控制器

public ActionResult Edit (int? id)
{
    using (var db = new EmployeeContext())
    {
        var model = new GradeSelectListViewModel(db.Employees.Find(id), db.Grades);
        //model.Employee = db.Employees.Single(x => x.EmployeeID == id);
        model.Grades = db.Grades.ToList().Select(x => new SelectListItem
        {
            Value = x.ID.ToString(),
            Text = x.Level
        });
        return View(model);
    }
}

我的剃须刀页面 CSHTML

@model MVCDemo.ViewModels.GradeSelectListViewModel
....
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    ....
    @Html.DropDownListFor(x => Model.Employee.Level,
        new SelectList(Model.Grades, "ID", "Level"),
        "Select Level")
    ....
    <input type="submit" value="Create" class="btn btn-default" />
}

【问题讨论】:

  • 只是@Html.DropDownListFor(x =&gt; Model.Employee.Level, Model.Grades, "Select Level")。但是您的代码还有其他问题。视图模型不应包含数据模型。需要删除GradeSelectListViewModel中的构造函数(或者添加无参构造函数)。 db.Grades.ToList()....中不需要.ToList()
  • 谢谢斯蒂芬。我做了你要求的改变。当我执行Employees/Create 时,下拉列表中的引用为空: System.NullReferenceException: Ligne 16 :
    Ligne 17 :
    Ligne 18:@Html.DropDownListFor(Ligne 19:x => Model.Employee.Level,Ligne 20:Model.Grades,
  • 邮件的详细信息是什么?您的代码显示您填充了model.Grades,因此如果您已将模型返回到视图,则它不能是null
  • 您显示的方法是 Edit() - 但该错误与名为 Create() 的方法有关 :)
  • 是的,操作是编辑,抱歉。几乎得到它。现在它说。当我制作 Employees/Edit/1 时,操作无法完成,因为 DbContext 已被释放。 id 为 1 的员工已经存在。

标签: asp.net-mvc entity-framework razor viewmodel dropdownlistfor


【解决方案1】:

您可以使用以下方法在同一个视图中填充三个 DropDownListFor:

视图模型:

public class GroupViewModel
{  
    public IEnumerable<SelectListItem> Schedules { get; set; }
    public int ScheduleId { get; set; }

    public IEnumerable<SelectListItem> Labs { get; set; }
    public int LabId { get; set; }

    public IEnumerable<SelectListItem> Terms { get; set; } 
    public int TermId { get; set; }
}



控制器:

public ActionResult Create()
{
    //Populate DropDownList binding values
    var model = new GroupViewModel
    {
        //Preselect the Lab with id 2
        //LabId = 2,

        Labs = repository.Labs.Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        }),
        Terms = repository.Terms.Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        }),
        Schedules = repository.Schedules.Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        })
    };
    return View("Create", model);
}



查看:

@Html.DropDownListFor(m => m.LabId, new SelectList(Model.Labs, "Value", "Text"), 
    "Select", new { @class = "selectpicker" })

@Html.DropDownListFor(m => m.ScheduleId, new SelectList(Model.Schedules, "Value", "Text"), 
    "Select", new { @class = "selectpicker" })

@Html.DropDownListFor(m => m.TermId, new SelectList(Model.Terms, "Value", "Text"), 
    "Select", new { @class = "selectpicker" })

希望这会有所帮助...

【讨论】:

    【解决方案2】:

    主要问题是在视图中您有new SelectList(Model.Grades, "ID", "Level"),但GradesIEnumerable&lt;SelectListItem&gt;SelectListItem 不包含名为IDLevel 的属性。

    但是,您的代码还存在一些其他问题。首先,视图模型不应该包含数据模型,而您的视图模型应该是

    public class GradeSelectListViewModel
    {
        public int? ID { get; set; } // make this ID so you do not need an input for it
        public string Name { get; set; }
        .... // other properties of Employee that your editing
        [Required(ErrorMessage = "..")]
        public int? Level { get; set; } // make value types nullable to protect against under-posting attacks
        public IEnumerable<SelectListItem> Grades { get; set; }
    }
    

    并根据需要添加显示和验证属性。注意我删除了构造函数(你好像没有使用,但是如果使用了,那么你还需要包含一个无参数的构造函数,否则提交POST方法时会抛出异常。我也假设Level 应该是 typeof int,因为您绑定到 Gradeint ID 属性。

    你的 GET 方法中的代码应该是

    Employee employee = db.Employees.Find(id);
    var model = new GradeSelectListViewModel()
    {
        ID = employee.EmployeeID,
        Name = employee.Name,
        Level = employee.Level, // convert to int?
        ....
        Grades = db.Grades.Select(x => new SelectListItem
        {
            Value = x.ID.ToString(),
            Text = x.Level
        })
    };
    return View(model);
    

    在视图中

     @Html.DropDownListFor(x => Model.Level, Model.Grades, "Select Level")
    

    另请注意,在 POST 方法中,如果您返回视图,则需要重新分配 SelectList,因为 ModelState 无效。

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签