复选框不保留其状态

时间:2012-03-23 16:48:55

标签: asp.net-mvc-3 entity-framework-4.1 checkbox dbcontext

我是asp mvc 3的初学者,我开发了一个应用程序, 我首先要描述我的应用程序 所以我在我的数据库,一个表帐户和一个表角色和帐户和角色之间的关系是多对多的,所以我有一个关联表account_role, 我首先使用Entity Framework数据库,然后使用EF DbContext Generator生成我的POCO, 我想要编辑帐户页面显示一个角色的chekbox 这是我的代码  控制器账户

 public ActionResult Edit(int id)
        {
            accounts accounts = db.accounts
                .Include(i => i.roles_accounts)
                .Where(i => i.id_account == id)
                .Single();
            PopulateAssignedRoleData(accounts);
            return View(accounts);
        }

        // populate Assigned RoleDATA pour afficher les checkbox
        private void PopulateAssignedRoleData(accounts account)
        {
             //Get all role
          var allRole =db.roles;
           //For each role, the code checks if the role exists in the property of accountRole
            // To create effective search when checking if a role is assigned to the account,
            // assigned roles in are put into a collection HashSet
          var accountRoles = new HashSet<int>(account.roles_accounts.Select(r => r.id_account_role));
          var viewModel = new List<AssignedRoleData>();
           // Property Assigned role of which is allocated account is set to true.
           //The view will use this property to determine
           //what check boxes to be displayed as selected.
           //Finally, the list is passed to the view in a ViewBag
          foreach (var role in allRole)
          {
              viewModel.Add(new AssignedRoleData
              {
                  RoleId = role.id_role,
                  Name = role.name,
                  Assigned = accountRoles.Contains(role.id_role)
              });
          }
          ViewBag.roles = viewModel;
        }

        //
        // POST: /Account/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, FormCollection formCollection, string [] selectedRoles)
        {


            var accountsToUpdate = db.accounts
                .Include(i => i.roles_accounts)
                .Where(i => i.id_account == id)
                .Single();
            if (TryUpdateModel(accountsToUpdate, "", null, new string[] { "roles_accounts" }))
            {
                try
                {
                    if (String.IsNullOrWhiteSpace(accountsToUpdate.login))
                    {
                        accountsToUpdate.roles_accounts = null;
                    }
                    UpdateAccountRole(selectedRoles, accountsToUpdate);
                    db.Entry(accountsToUpdate).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }

                catch (DataException)
                {
                    ModelState.AddModelError("", "Unable to save change");
                }
        }
            PopulateAssignedRoleData(accountsToUpdate);
            return View(accountsToUpdate);
    }

        // update AccountRole (liste of checkbox)
        private void UpdateAccountRole(string[] selectedRoles, accounts accountToUpdate)
        {
            if (selectedRoles == null)
            {

                accountToUpdate.roles_accounts=new List<roles_accounts>();
                return;
            }
            var selectedRolesHS = new HashSet<string>(selectedRoles);
            var accountsRoles = new HashSet<int>
            (accountToUpdate.roles_accounts.Select(r => r.id_account_role));

            foreach(var role in db.roles_accounts)
            {
                if( selectedRolesHS.Contains(role.id_account_role.ToString()))
                {
                    if(!accountsRoles.Contains(role.id_account_role))
                    {
                        accountToUpdate.roles_accounts.Add(role);
                    }
                }
                else
                {
                    if (accountsRoles.Contains(role.id_account_role))
                    {
                        accountToUpdate.roles_accounts.Remove(role);
                    }
                }
            } 
        }

我创建一个文件夹nammed ViewModels,并在此文件夹中创建一个classe AssignedRoleData为视图提供数据复选框列表, 这是AssignedRoleData

 public class AssignedRoleData
    {
        public int RoleId { get; set; }
        public string Name { get; set; }
        public bool Assigned { get; set; }

并在Edit.schtml中 我把这段代码

<div class="editor-field">
    <table>
        <tr>
            @{
                int cnt = 0;

                List<App_ERP1.ViewModels.AssignedRoleData> roles=ViewBag.roles;

                foreach (var role in roles) {
                    if (cnt++ % 3 == 0) {
                        @:  </tr> <tr> 
                    }
                    @: <td>  
                        <input type="checkbox" 
                               name="selectedRoles" 
                               value="@role.RoleId" 
                               @(Html.Raw(role.Assigned ? "checked=\"checked\"" : "")) /> 
                        @role.RoleId @:  @role.Name
                    @:</td>
                }
                @: </tr>
            }

    }
}

我的问题是复选框没有保留其状态,每次单击保存按钮时它都会删除添加的角色(选择)

感谢帮助我

2 个答案:

答案 0 :(得分:0)

你需要在视图上使用“for”而不是“foreach”,你的属性“name”可能需要像name =“selectedRoles [i]”。提示:不要直接在控制器上访问数据库。创建一个中间层,其中有AccountRoleService类,这里放置逻辑,然后创建另一个层来访问名为repository的数据库(例如AccountRoleRepository),在那里实际执行LINQ to SQL。如果要重用方法会容易得多。所以控制器做的很少,并且调用服务类。服务类执行逻辑并调用存储库类来访问数据库。因此,如果您想对服务进行单元测试,那么您将走上正确的道路。

答案 1 :(得分:0)

for (i = 0; i< roles.Count, i++) {
                    if (cnt++ % 3 == 0) {
                        @:  </tr> <tr> 
                    }
                    @: <td>  
                        <input type="checkbox" 
                               name="selectedRoles[" + i + "]" 
                               value="@role.RoleId" 
                               @(Html.Raw(role.Assigned ? "checked=\"checked\"" : "")) /> 
                        @role.RoleId @:  @role.Name
                    @:</td>
                }
                @: </tr>