【问题标题】:How to solve 'There is no ViewData item of type 'IEnumerable<SelectListItem>' in ASP.NET MVC?如何解决 ASP.NET MVC 中没有类型为 'IEnumerable<SelectListItem>' 的 ViewData 项?
【发布时间】:2021-12-23 22:59:15
【问题描述】:

我使用@Html.DropDownListFor 进行编辑会话时出错,我使用它来创建方法是成功的,但是当我在编辑方法中使用时失败,像这样的错误警告 System.InvalidOperationException: 'There is no具有键“roles_id”的“IEnumerable”类型的 ViewData 项。

deail 文件如下:

编辑.cshtml:

<div class="form-group">
    @Html.LabelFor(model => model.roles, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-12">
        @Html.DropDownListFor(model => model.roles_id, (SelectList)ViewBag.RolesList, new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.roles_id, "", new { @class = "text-danger" })
    </div>
</div>

EmployeeController.cs

// GET: Employee/Edit/{id}
public ActionResult Edit(int id)
{
    AuthDBHandle dbhandle = new AuthDBHandle();
    adminlteDBHandle sdb = new adminlteDBHandle();

    var roles_id = sdb.GetEmployee().Find(smodel => smodel.employee_id == id).roles_id;
    var roles = dbhandle.GetRoles();
    ViewBag.RolesList = new SelectList(roles, "roles_id", "roles", roles_id);

    return View(sdb.GetEmployee().Find(smodel => smodel.employee_id == id));
}

// POST: Employee/Edit/{id}
[HttpPost]
public ActionResult Edit(EmployeeViewModel smodel)
{
    try
    {
        if (ModelState.IsValid)
        {
            adminlteDBHandle sdb = new adminlteDBHandle();
            if (sdb.EditEmployee(smodel))
            {
                ViewBag.Message = "Edit employee is success";
                ModelState.Clear();
                return RedirectToAction("Index");
            }

            return View();
        }
        return View();
    }
    catch
    {
        return View();
    }
}

EmployeeViewModel.cs

namespace adminlte.Models
{
    public class EmployeeViewModel
    {
        [Display(Name = "Employee Id")]
        public int employee_id { get; set; }

        [Required(ErrorMessage = "Fullname is required.")]
        public string fullname { get; set; }

        [Required(ErrorMessage = "Address is required.")]
        [DataType(DataType.MultilineText)]
        public string address { get; set; }

        public string roles { get; set; }

        [Required(ErrorMessage = "Role ID is required.")]
        public int roles_id { get; set; }

        [Required(ErrorMessage = "Email is required.")]
        [EmailAddress(ErrorMessage = "Invalid Email Address")]
        public string email { get; set; }

        public string password { get; set; }
    }
}

我不知道为什么,我试图寻找一个例子,但都失败了,请帮我解决这个问题。

谢谢。

【问题讨论】:

    标签: asp.net asp.net-mvc


    【解决方案1】:

    您放入ViewBag 的数据不会在请求之间保留。当您尝试再次显示您的视图时,您需要重新填充 ViewBag 项。

    我通常提取代码以将查找填充到单独的方法中,从而避免重复。

    例如:

    private void PopulateLookups(EmployeeViewModel vm)
    {
        AuthDBHandle dbhandle = new AuthDBHandle();
        var roles = dbhandle.GetRoles();
        ViewBag.RolesList = new SelectList(roles, "roles_id", "roles", vm.roles_id);
    }
    
    // GET: Employee/Edit/{id}
    public ActionResult Edit(int id)
    {
        adminlteDBHandle sdb = new adminlteDBHandle();
        var employee = sdb.GetEmployee().Find(smodel => smodel.employee_id == id);
        if (model == null) return RedirectToAction("Index");
        
        var vm = new EmployeeViewModel 
        { 
            employee_id = employee.employee_id,
            fullname = employee.fullname,
            address = employee.address,
            roles = employee.roles,
            roles_id = employee.roles_id,
            email = employee.email,
            password = employee.password, // WARNING!
        };
        
        PopulateLookups(vm);
        return View(vm);
    }
    
    // POST: Employee/Edit/{id}
    [HttpPost]
    public ActionResult Edit(EmployeeViewModel vm)
    {
        try
        {
            if (ModelState.IsValid)
            {
                adminlteDBHandle sdb = new adminlteDBHandle();
                if (sdb.EditEmployee(vm))
                {
                    return RedirectToAction("Index");
                }
            }
            
            PopulateLookups(vm);
            return View();
        }
        catch
        {
            PopulateLookups(vm);
            return View();
        }
    }
    

    注意:根据您的列名,您似乎是以纯文本形式存储员工的密码。不要那样做!使用加密安全的单向散列算法的多次迭代存储密码的加盐散列。

    【讨论】:

    • 感谢帮助我,我想问一下,在这种情况下我在哪里可以获得模型变量'if (model == null) return RedirectToAction("Index");'在函数编辑(GET 方法)中?
    • 哦,谢谢,它的工作,我在 'if (model == null) return RedirectToAction("Index");' 中更改模型,使用员工变量。
    猜你喜欢
    • 2016-05-11
    • 2014-01-12
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 2018-09-11
    • 1970-01-01
    相关资源
    最近更新 更多