MVC如何将列表中的String项分配给变量

时间:2016-03-10 18:35:10

标签: c# asp.net-mvc entity-framework relational-database

我为我创建了一个下拉列表,可以在创建时为其分配管理员角色:

Create user form

但他们没有正确分配自己,你可以在这里看到:

User overview form

这是因为这一行Value = "Administrator LVL2"。我的问题是:我如何将它分配给我的模型,就像我为分配姓氏所做的那样:

    <div class="editor-field">
        @Html.EditorFor(model => model.LastName)
        @Html.ValidationMessageFor(model => model.LastName)
    </div>

视图\用户\ Create.cshtml

  <div class="editor-label">
        @{
                List<SelectListItem> listItems = new List<SelectListItem>();
                listItems.Add(new SelectListItem
                {
                    Text = "Administrator LVL1",
                    Value = model => model.AdminRole, <-- THIS IS WRONG
            });
            listItems.Add(new SelectListItem
            {
                Text = "Administrator LVL2",
                Value = "Administrator LVL2",
                Selected = true
            });
            listItems.Add(new SelectListItem
            {
                Text = "Administrator LVL3",
                Value = "Administrator LVL3"
            });
        }

        @Html.DropDownListFor(model => model.AdminRole, listItems, "-- Select Admin Role --")
    </div>

UserController.cs

    public class UserController : Controller
    {
        private IssueContext db = new IssueContext();

        //
        // GET: /User/

        public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
        {
            ViewBag.CurrentSort = sortOrder;
            ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
            ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

            if (searchString != null)
            {
                page = 1;
            }
            else
            {
                searchString = currentFilter;
            }

            ViewBag.CurrentFilter = searchString;

            var users = from s in db.Users
                        select s;
            if (!String.IsNullOrEmpty(searchString))
            {
                users = users.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
                                       || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
            }
            switch (sortOrder)
            {
                case "name_desc":
                    users = users.OrderByDescending(s => s.LastName);
                    break;
                case "Date":
                    users = users.OrderBy(s => s.EnrollmentDate);
                    break;
                case "date_desc":
                    users = users.OrderByDescending(s => s.EnrollmentDate);
                    break;
                default:  // Name ascending 
                    users = users.OrderBy(s => s.LastName);
                    break;
            }

            int pageSize = 5;
            int pageNumber = (page ?? 1);
            return View(users.ToPagedList(pageNumber, pageSize));
        }

        //
        // GET: /User/Details/5

        public ActionResult Details(int id = 0)
        {
            User user = db.Users.Find(id);
            if (user == null)
            {
                return HttpNotFound();
            }
            return View(user);
        }

        //
        // GET: /User/Create

        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /User/Create

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(
            [Bind(Include = "LastName, FirstMidName, EnrollmentDate, DepartmentID, DepotID")]
            User user)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    db.Users.Add(user);
                    db.SaveChanges();
                    return RedirectToAction("Index");

                }
            }
            catch (DataException /* dex */)
            {
                //Log the error (uncomment dex variable name after DataException and add a line here to write a log.
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
            }

            return View(user);
        }

        //
        // GET: /User/Edit/5

        public ActionResult Edit(int id = 0)
        {
            User user = db.Users.Find(id);
            if (user == null)
            {
                return HttpNotFound();
            }
            return View(user);
        }

        //
        // POST: /User/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(
           [Bind(Include = "UserID, LastName, FirstMidName, EnrollmentDate, DepartmentID, DepotID")]
   User user)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    db.Entry(user).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
            }
            catch (DataException /* dex */)
            {
                //Log the error (uncomment dex variable name after DataException and add a line here to write a log.
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
            }
            return View(user);
        }

        //
        // GET: /User/Delete/5

        //This code accepts an optional Boolean parameter that indicates whether it was called after a failure to save changes. 
        //This parameter is false when the HttpGet Delete method is called without a previous failure. When it is called by the 
        //HttpPost Delete method in response to a database update error, the parameter is true and an error message is passed to the view.


        public ActionResult Delete(bool? saveChangesError = false, int id = 0)
        {
            if (saveChangesError.GetValueOrDefault())
            {
                ViewBag.ErrorMessage = "Delete failed. Try again, and if the problem persists see your system administrator.";
            }
            User user = db.Users.Find(id);
            if (user == null)
            {
                return HttpNotFound();
            }
            return View(user);
        }

        //
        // POST: /User/Delete/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Delete(int id)
        {
            try
            {
                User user = db.Users.Find(id);
                db.Users.Remove(user);
                db.SaveChanges();
            }
            catch (DataException/* dex */)
            {
                // uncomment dex and log error. 
                return RedirectToAction("Delete", new { id = id, saveChangesError = true });
            }
            return RedirectToAction("Index");
        }


        //To make sure that database connections are properly closed and the resources they hold freed up, you should see to it that the context instance is disposed. 

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }

我的类如何映射:

用户到管理员是1到0..1(我可以为一些用户分配管理员状态,但我不希望每个用户都拥有它)

票证管理员是1到多人(您只能将1个管理员(以解决问题)分配给票证)

用户到故障单是1到多(一个用户可以创建多个故障单)

User.cs

public class User
{
    public int UserID { get; set; }
    [StringLength(50, MinimumLength = 1)]
    public string LastName { get; set; }
    [StringLength(50, MinimumLength = 1, ErrorMessage = "First name cannot be longer than 50 characters.")]

    [Column("FirstName")]
    public string FirstMidName { get; set; }

    public string FullName
    {
        get { return LastName + ", " + FirstMidName; }
    }
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime EnrollmentDate { get; set; }
    public int? AdministratorID { get; set; }
    [ForeignKey("AdministratorID")]
    public virtual Administrator Administrator { get; set; }
    public int DepartmentID { get; set; }
    [ForeignKey("DepartmentID")]
    public virtual Department Department { get; set; }
    public int DepotID { get; set; }
    [ForeignKey("DepotID")]
    public virtual Depot Depot { get; set; }
    public virtual ICollection<Ticket> Tickets { get; set; }
}

Ticket.cs

   public class Ticket
    {
        public int TicketID { get; set; }
        public string Issue { get; set; }
        [DisplayFormat(NullDisplayText = "No Priority")]
        public Priority? Priority { get; set; }
        [ForeignKey("CategoryID")]
        public virtual Category Category { get; set; }
        public int CategoryID { get; set; }
        public int UserID { get; set; }
        [ForeignKey("UserID")]
        public virtual User User { get; set; }


        public int AdministratorID { get; set; }
        [ForeignKey("AdministratorID")]
        public virtual Administrator Administrator { get; set; }
    }

Administrator.cs

public class Administrator
{
    public int AdministratorID { get; set; }
    public string AdministratorTitle { get; set; }
    public virtual ICollection<User> Users { get; set; }

}

2 个答案:

答案 0 :(得分:2)

以下是我的建议:

1)制作一个角色表(如果你已经完成了ASP.NET成员资格,已经提供了这个)。

Role:
   RoleId Int
   RoleName String

2)将角色添加到表中(您可以使用SQL Server [或您正在使用的任何SQL])

3)向你的用户添加一个ForeignKey或者添加一个像UsersInRoles这样的链接表(再一次,如果你使用了ASP成员资格,那么就添加了这个链接表)

1st Example:
    User:
       UserId Int
       FirstName String
       LastName string
       DepotId Int
       DepartmentId Int
       RoleId Int

2nd Example:
    UsersInRole
        UserId Int
        RoleId Int

现在,只要您GET用户,就可以恢复RoleId:

public ActionResult List()
{
    // Get Roles
    ViewBag.Roles = (from role in dbContext.Roles
                     select new SelectListItem 
                     {
                         Text = role.RoleName,
                         Value = role.RoleId
                      });
    // Get Users
    IEnumerable<User> users = (from user in dbContext.Users
                               select new User 
                               {
                                  UserId = user.UserId,
                                  FirstName = user.FirstName,
                                  LastName = user.LastName,
                                  DepotId = user.DepotId,
                                  DepartmentId = user.DepartmentId,
                                  RoleId = user.RoleId,
                                  // OR
                                  // RoleId = dbContext.Roles.Where(r => r.UserId == user.UserId).First().RoleId
                                  //
                               });
      return users;
}

在您看来:

<div>
    @Html.DropDownListFor(model => model.RoleId, (SelectList)ViewBag.Roles)
</div>

答案 1 :(得分:1)

如果您的数据库中有2个表...一个保存用户信息(为了参数,表的名称将是User),另一个保存可能的角色(表的名称是Role)..您可以在名为User(外键)的roleID表中创建一个属性,以保存Role表的主键(ID)。因此,在Role表中,假设您有2个属性,ID和文本。 ID包含表示文本的唯一值。例如ID = 1,text = Administrator ... ID = 2,text = Member ...等等......然后当你创建一个用户时,根据你上面给出的例子,你会看到这是你的用户表test 2 test2 2016-11-03 1 1 1 //if you made him an administator

Details视图中,您可以通过确保User模型中的public virtual Role role { get; set; }

来显示文字而不是ID

然后:

@Html.DisplayNameFor(model => model.Role.text)

然后在User动作下的Create控制器中,您可以在ViewBag中填充可能的角色:

public ActionResult Create()
{
    ViewBag.roleID = new SelectList(database.Role, "ID", "text");
    return View()
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID, firstName, lastName, enrollmentDate, departmentID, depotID, roleID")] User user)
{
    if(ModelState.IsValid)
    {
        ViewBag.roleID = new SelectList(database.Role, "ID", "text", user.roleID);
        return View(user);
    }
}

然后在您的Create cshtml页面中:

@Html.DropDownList("roleID", null, htmlAttributes: new { @class = "form-control" }) 

假设您使用bootstrap作为表单控件类名。