MVC:DropdownListFor错误“无法将lambda表达式转换为类型'string',因为它不是委托类型”

时间:2016-07-26 12:04:00

标签: c# asp.net-mvc entity-framework model-view-controller lambda

我有以下问题。

我有一个名为Users的表,我有另一个名为Department的表。

现在我想要的是,在用户界面中,当用户打算将自己创建为用户表单的用户时,他会在部门字段中的下拉列表中显示部门表中可用的所有部门标题。原因:部门表将用于其他操作,不应与Userdata链接。所以Userdata应该只包含表中的部门名称,这就足够了。

我的控制器看起来像这样:

public ActionResult UserCreate()
{
    ViewBag.AppDataDepartment = new SelectList(database.department, "department_title", "department_title");
    return View();
}

[HttpPost]
public ActionResult UserCreate(Users user)
{
    if (user.UserID == "" || user.UserID == null)
    {
        ModelState.AddModelError(string.Empty, "UserID cannot be blank");
    }
    try
    {
        if (ModelState.IsValid)
        {
            List<string> results = database.Database.SqlQuery<String>(string.Format("SELECT UserID FROM USERS WHERE UserID = '{0}'", user.UID)).ToList();
            bool _userExistsInTable = (results.Count > 0);
            Users _user = null;
            if (_userExistsInTable)
            {
                _user = database.Users.Where(p => p.UserID == user.UserID).FirstOrDefault();
                if (_user != null)
                {
                   if(_user.active == true)
                    { 
                            ModelState.AddModelError(string.Empty, "USER already exists!");
                    }
                    else
                    {
                        database.Entry(_user).Entity.active = true;
                        database.Entry(_user).Entity.Last_Modified = System.DateTime.Now;
                        database.Entry(_user).State = EntityState.Modified;
                        database.SaveChanges();
                        return RedirectToAction("Index");
                    }
                }
            }
            else
            {
                _user = new Users();
                _user.UserID = user.UserID;
                _user.lastname = user.lastname;
                _user.firstname = user.firstname;
                _user.mail = user.mail;
                _user.department = user.department;
                _user.user_image = user.user_image;
                _user.image_path = user.image_path;
                 if (ModelState.IsValid)
                 {
                    _user.active = true;
                    _user.Last_Modified = System.DateTime.Now;
                    database.Users.Add(_user);
                    database.SaveChanges();
                    ViewBag.AppDataDepartment = new SelectList(database.department, "department_title", "department_title");
                    return RedirectToAction("Index");
                }
            }
        }
    }
    catch (Exception ex)
    {
        //return base.ShowError(ex);
    }
    return View(user);
}

这是我的HTML部分:

<div class="row">
    @Html.LabelFor(model => model.UserID, "UserID", new { @class = "col-sm-2 control-label" })
    <div class="col-md-4">
        @Html.TextBoxFor(model => model.UserID, new { @class = "col-md-4 control-label form-control", @id = "inputEmail3" })
    </div>

    @Html.LabelFor(model => model.department, "Department", new { @class = "col-sm-2 control-label" })
    <div class="col-md-4">
        @Html.DropDownList(model => model.department, (SelectList) ViewBag.AppDataDepartment, htmlAttributes: new { @class = "form-control" })
    </div>
</div>

最后我的部门班来自表:

[Table("department")]
public partial class department
{
    [Key]
    public int departmentid { get; set; }
    [Required]
    public string department_title { get; set; }
    public string subdepartment { get; set; }
}

但是我无法编译,因为我收到错误:

  

错误CS1660无法将lambda表达式转换为'string'类型,因为   它不是委托类型BTKPI

为什么这不起作用?我该如何解决这个问题?

我已经查看了这个SolutionProposal,但这没有用,因为已经引用了模型Linq和Data.Entity。

1 个答案:

答案 0 :(得分:3)

它必须是DropDownListFor(),而不是DropDownList()

@Html.DropDownListFor(m => m.department, (SelectList)ViewBag.AppDataDepartment, new { @class = "form-control" })

如果您使用DropDownList(),那么它将是

@Html.DropDownList("department", (SelectList)ViewBag.AppDataDepartment, new { @class = "form-control" })

但是您的代码还有许多其他问题需要解决。

  1. 您的控制器应为UserController,方法为Create() 以便网址为../User/Create,而不是User/UserCreate
  2. 您的编辑数据,因此您应该使用视图模型(不要使用 编辑数据时的数据模型) - 参考What is ViewModel in MVC?, 并且视图模型应包含属性 IEnumerable<SelectListItem> DepartmentList - 典型的例子是 显示在this question/answer
  3. 您的Users表应该存储ID的{​​{1}}, 不是它的名字,应该有一个FK关系 Department表。
  4. Departments的视图模型属性应为UserID 属性和视图应包含[Required],以便您接受客户端和服务器端验证(同上@Html.ValidationMesageFor(m => m.UserID)属性)。你也应该 考虑将DepartmentID应用于RemoteAttribute属性 您获得客户端验证 - 请参阅How to: Implement Remote Validation in ASP.NET MVC
  5. 最后,几乎没有什么是你的POST方法很有意义。您调用数据库两次以检查用户是否已存在。您多次检查UserID。您的ModelState.IsValiduser_image属性建议您需要上传图片,但无处保存。您指定image_path,然后立即重定向到ViewBag.AppDataDepartment方法。您的代码应该类似于(忽略文件上载问题)

    Index()

    虽然尚不清楚为什么已归档的现有用户需要导航到[HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(UserVM model) { // Return early if (!ModelState.IsValid) { // You will enter this automatically of UserID is null model.DepartmentList = ... // assign the SelectList return View(model); } // One database call to check if the user exists User user = database.Users.Where(p => p.UserID == model.UserID).FirstOrDefault(); if (user != null && !user.active) { user.active = true; // Save and redirect } else if (user != null) { ModelState.AddModelError(string.Empty, "USER already exists!"); model.DepartmentList = ... // assign the SelectList return View(model); } user = new User { UserID = model.UserID, lastname = model.lastname, .... // set other properties of User Last_Modified = System.DateTime.Now } // Save and redirect } 方法(并且会提供一个表单来填写他们之前已输入的大量详细信息)。您应该有一个单独的方法来激活以前存档的用户。