vendredi 11 septembre 2015

Entity Framework is not providing me IDs when calling back

I'm using a ViewModel (RoleVM) with a collection of ViewModels (RolePermissionVM) for this particular edit view. The view displays the RoleVM fields, and a checkbox list of RolePermissionVM. Each row in the checkbox list has a hiddenFor for the ID of the RolePermission.

When I save the form, my controller correctly writes the data to the database, adding or updating records. However, I would like the user to remain on the page, so I call the View again, but trying to get an updated model so that I have the IDs for any newly created RolePermissionVM objects. I am not getting the new IDs into the HiddenFor fields.

Here's my class:

public class RolePermissionVM
{
    public int? RolePermissionId { get; set; }
    public int RoleId { get; set; }
    public int PermissionId { get; set; }
    public string PermissionName { get; set; }

    public bool IsActive { get; set; }
}

My controller code:

    private RoleVM GetRoleVm(int id)
    {
        var thisRoleVm = (from r in db.Role
            where r.RoleId == id
            select new RoleVM
            {
                RoleId = r.RoleId,
                RoleName = r.RoleName,
                RoleDescription = r.RoleDescription,
                OwnerId = r.OwnerId,
                IsActive = r.IsActive
            }).FirstOrDefault();
        thisRoleVm.RolePermission = (from p in db.Permission
                                     join rPerm in
                                         (from rp in db.RolePermission
                                          where rp.RoleId == id
                                          select rp)
                                         on p.PermissionId equals rPerm.PermissionId into pp
                                     from rps in pp.DefaultIfEmpty()
                                     select new RolePermissionVM
                                     {
                                         RolePermissionId = (int?)rps.RolePermissionId,
                                         RoleId = id,
                                         PermissionId = p.PermissionId,
                                         PermissionName = p.PermissionName,
                                         IsActive = (rps.IsActive == null ? false : rps.IsActive)
                                     })
                                     .OrderBy(p => p.PermissionName).ToList();
        return thisRoleVm;
    }

    [HttpPost, ActionName("_roleedit")]
    [ValidateAntiForgeryToken]
    public ActionResult _RoleEdit(RoleVM editedRole)
    {
        //...

        if (ModelState.IsValid)
        {
            var dbRole = db.Role.Find(editedRole.RoleId);
            dbRole.RoleName = editedRole.RoleName;
            dbRole.RoleDescription = editedRole.RoleDescription;
            dbRole.OwnerId = editedRole.OwnerId;

            foreach (var thisPerm in editedRole.RolePermission) // RolePermission here is the ViewModel, not the actual model
            {
                if (thisPerm.RolePermissionId != null && thisPerm.RolePermissionId > 0)
                {
                    // We have a record for this, let's just update it
                    var thisRolePerm =
                        dbRole.RolePermission.FirstOrDefault(rp => rp.RolePermissionId == thisPerm.RolePermissionId);
                    thisRolePerm.IsActive = thisPerm.IsActive;
                    db.Entry(thisRolePerm).State = EntityState.Modified;
                }
                else
                {
                    if (thisPerm.IsActive)
                    {
                        // New and active, so we add it
                        dbRole.RolePermission.Add(new RolePermission
                        {
                            RoleId = editedRole.RoleId,
                            PermissionId = thisPerm.PermissionId,
                            IsActive = true
                        });
                    }
                }
            }

            db.Entry(dbRole).State = EntityState.Modified;
            db.SaveChanges(User.ProfileId);

            var newEditedRole = GetRoleVm(editedRole.RoleId); // We don't get the new IDs here, but I would like to
            newEditedRole.ResponseMessage = "Saved Successfully";

            return View(newEditedRole); // This should have the new RolePermissionId values, but it doesn't.
        }
    editedRole.ResponseMessage = "Error Saving";
        return View(editedRole);
    }

The partial view used for each row of the CheckBox list:

@using PublicationSystem.Tools
@model PublicationSystem.Areas.Admin.Models.RolePermissionVM

<li class="editorRow ui-state-default removable-row">
    @using (Html.BeginCollectionItem("RolePermission"))
    {
        <div class="row">
            @Html.HiddenFor(model => model.RolePermissionId)
            @Html.HiddenFor(model => model.RoleId)
            @Html.HiddenFor(model => model.PermissionId)
            @Html.HiddenFor(model => model.PermissionName)

            <div class="col-md-7">
                @Html.DisplayFor(model => model.PermissionName, new {htmlAttributes = new {@class = "form-control"}})
            </div>
            <div class="col-md-3">
                @Html.CheckBoxFor(model => model.IsActive, new { htmlAttributes = new { @class = "form-control" } })
            </div>
    </div>
    }
</li>

So, why do the new database generated IDs not get pulled back? How can I fix that? Is there a more efficient way to do this?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire