如何在ASP.NET MVC Web API中创建角色并将用户添加到角色中

19

我有一个使用个人账户的.NET Web API项目。使用标准模板的AccountController,我可以成功注册用户。然而,我现在想设置角色,并根据用户类型将用户添加到相应的角色。

数据库中没有自动设置角色。如何设置角色以及如何将用户添加到角色中?

我能找到的唯一信息都基于旧版本的ASP.NET Membership,因此它无法正常工作,因为存储过程未为其设置。

我搜遍了MSDN上的论坛和教程,但似乎找不到Web API的示例。

2个回答

24

您可以使用RoleManager添加角色...

using (var context = new ApplicationDbContext())
{
    var roleStore = new RoleStore<IdentityRole>(context);
    var roleManager = new RoleManager<IdentityRole>(roleStore);

    await roleManager.CreateAsync(new IdentityRole { Name = "Administrator" });

    var userStore = new UserStore<ApplicationUser>(context);
    var userManager = new UserManager<ApplicationUser>(userStore);

    var user = new ApplicationUser { UserName = "admin" };
    await userManager.CreateAsync(user);
    await userManager.AddToRoleAsync(user.Id, "Administrator");
}

你说得对,目前文档有点简略。但是我发现一旦你使用RoleManager和UserManager一段时间后,API就变得相当易于发现(但有时不太直观,有时你甚至需要直接针对存储或数据库上下文运行查询)。


太好了。感谢你的帮助! - Ben Drury
@andrefadila 这段代码需要放在你想要创建新角色的任何位置。通常这些会在开发过程中设置,但也可能在你的管理代码中设置。对于将用户添加到角色中,请在创建新用户时使用该代码。 - Ben Drury
1
我不太确定这应该放在 Web API 2 中的哪里。你能详细说明一下吗?例如,展示如何在一个新的 Web API 2 项目中设置它? - allencoded

6

我花了一段时间才明白,但最终我搞懂了。安东尼,请原谅我,我要重新发布你的很多代码,这样像我这样的蠢开发人员才能理解。

在最新的WebAPI2(Visual Studio 2013 Update 2)中,注册方法将如下所示:

// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };

    IdentityResult result = await UserManager.CreateAsync(user, model.Password);


    if (!result.Succeeded)
    {
        return GetErrorResult(result);
    }

    return Ok();
}

你需要做的是将它替换为这个:
// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }


    IdentityResult result;
    using (var context = new ApplicationDbContext())
    {
        var roleStore = new RoleStore<IdentityRole>(context);
        var roleManager = new RoleManager<IdentityRole>(roleStore);

        await roleManager.CreateAsync(new IdentityRole() { Name = "Admin" });

        var userStore = new UserStore<ApplicationUser>(context);
        var userManager = new UserManager<ApplicationUser>(userStore);

        var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };

        result = await UserManager.CreateAsync(user, model.Password);
        await userManager.AddToRoleAsync(user.Id, "Admin");

    }

    if (!result.Succeeded)
    {
        return GetErrorResult(result);
    }

    return Ok();
}

现在,当您发布内容时,它应该可以正常工作,但是您可能会遇到另一个问题。在我执行此操作后,我的响应抱怨数据库出现问题。
The model backing the <Database> context has changed since the database was created

为了解决这个错误,我需要进入“包管理器控制台”并启用迁移。
Enable-Migrations –EnableAutomaticMigrations

然后:
Add Migration

最后:

Update-Database

这里有一篇关于启用迁移的好文章: http://msdn.microsoft.com/zh-cn/data/jj554735.aspx

1
在控制器方法中实例化数据库上下文并不是一个好的做法。请查看依赖反转原则。 - arnaudoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接