user1088259
user1088259

Reputation: 355

How rename Asp.net Identity Role

I add 3 roles to database. "Admin","Moderator" and "User". I want simply rename "Admin" to "Administrator". I use this code, but its not correct work. Its return me error {"Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions."}

Edit.cshtml

@model Microsoft.AspNet.Identity.EntityFramework.IdentityRole
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.Id)
        <div>
            Role name
        </div>
        <p>
            @Html.TextBoxFor(model => model.Name)
        </p>
        <input type="submit" value="Save" />
    }

RoleController

  [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(IdentityRole role) //IdentityRole role
    {
        try
        {

            context.Entry(role).State = EntityState.Modified;
            context.SaveChanges();

            return RedirectToAction("Index");
        }
        catch (Exception ex)
        {
            return View();
        }
    }

Upvotes: 0

Views: 3293

Answers (2)

Cooler
Cooler

Reputation: 1

Here's how I did it. This part of my Admin page, option: "Add/Edit Roles"

  [HttpPut]
    public string UpdateRole(RoleModel roleModel)
    {
        string success = "";
        using (var context = new ApplicationDbContext())
        {
            var roleStore = new RoleStore<IdentityRole>(context);
            var storeManager = new RoleManager<IdentityRole>(roleStore);
            IdentityRole thisRole = roleStore.Roles.Where(r => r.Id == roleModel.Id).FirstOrDefault();
            if (thisRole != null)
            {
                thisRole.Name = roleModel.Name;
                IdentityResult result = storeManager.Update(thisRole);
                if(result.Succeeded)
                success = "ok";
                else
                {
                    success = "ERROR";
                    foreach (string error in result.Errors)
                    {
                        success += " :" + error;
                    }
                }
            }
        }
        return success;
    }

You have to use a special RoleManager I call storeManager built in a using block for ApplicationDbContext to return a list of all Roles. Then I use a linq where clause to find the role I want. Then you modify the role by changing its name and call .Update which is also exposed by the roleStore StoreManager object. Trying edit the AspNet user files directly can be done in EntityFramework and has no effect except to mess things up if done in SQL.

Upvotes: 0

RickL
RickL

Reputation: 3393

Use the Role Manager provided by Identity.

In Startup.Auth, make sure the RoleManager is referenced like this:

public void ConfigureAuth(IAppBuilder app)
{
    // Add this reference
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
}

Make sure your Controller includes this constructor:

private ApplicationRoleManager _roleManager;
public ApplicationRoleManager RoleManager { get { return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>(); } private set { _roleManager = value; } }

Then you can use this instead of the code in the question (given as async):

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(IdentityRole role)
{
    try
    {
        IdentityRole thisRole = await RoleManager.FindByIdAsync(role.Id);
        thisRole.Name = role.Name;
        await RoleManager.UpdateAsync(thisRole);
        return RedirectToAction("Index");
    }
    catch (Exception ex)
    {
        return View();
    }
}

And finally make sure you dispose of the Role Manager like this:

protected override void Dispose(bool disposing)
{
    if (disposing && RoleManager != null)
    {
        RoleManager.Dispose();
        RoleManager = null;
    }
    if (disposing)
    {
        context.Dispose();
    }
    base.Dispose(disposing);
}

Hopefully this should do the trick.

Upvotes: 4

Related Questions