如何在.Net角色提供程序中设置角色类型文本?

时间:2013-11-21 17:51:42

标签: c# asp.net-mvc asp.net-mvc-4 entity-framework-5 role-manager

在我的UserController.Login操作中,我正在为经过身份验证的用户尝试AddUserToRole(),其值为用户实体的MembershipType.MembershipName导航属性之一:

Roles.AddUserToRole(thisUser.UserName, thisUser.MembershipType.MembershipName);

我没有使用膨胀的自动生成的成员资格类型,只是想将文本值添加到用户的角色 - 而不是一系列角色。用户 - >一个角色。

在尝试解决这个问题时,我在web.config中定义了一个自定义角色提供程序:

<roleManager enabled="true" defaultProvider="CustomRoleProvider">
  <providers>
    <clear/>
    <add name="CustomRoleProvider" 
       type="MyWebsite.CustomRoleProvider, 
             CustomMembershipEF, Version=1.0.0.0, Culture=neutral" 
       connectionStringName="MyDbContext"
       enablePasswordRetrieval="false" enablePasswordReset="true" 
       requiresQuestionAndAnswer="false" writeExceptionsToEventLog="false" />
  </providers>
</roleManager>   

因此调用Roles.AddUserToRole()会调用我的自定义提供程序中的方法,但我不确定该方法中该怎么做。

之前我只是将enabled="true"添加到了web.config中的rolemanager部分,但收到了以下错误:

  

无法找到请求的.Net Framework数据提供程序。它可能不会   安装。

这是我的自定义角色提供程序(虽然我不知道为什么我需要这个,因为我只想添加角色名称):

public class CustomRoleProvider : RoleProvider
{
    public override bool IsUserInRole(string username, string roleName)
    {
        using (var db = new MyApp.DAL.MyAppDbContext())
        {
            var user = db.Users.SingleOrDefault(u => u.UserName == username);
            if (user == null)
                return false;

            if (user.MembershipType != null && user.MembershipType.MembershipName == roleName)
            {
                return true;
            }
        }
        return false;
    }

    public override string[] GetRolesForUser(string username)
    {
        using (var db = new MyApp.DAL.MyAppDbContext())
        {
            var user = db.Users.SingleOrDefault(u => u.UserName == username);
            if (user == null)
                return new string[] { };

            return db.MembershipTypes == null ? new string[] { } :
              db.MembershipTypes.Select(u => u.MembershipName).ToArray();
        }
    }

    // -- Snip --

    public override string[] GetAllRoles()
    {
        using (var db = new MyApp.DAL.MyAppDbContext())
        {
            return db.MembershipTypes.Select(r => r.MembershipName).ToArray();
        }
    }

    // -- Snip --

    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    {
        throw new NotImplementedException();
    }

我认为这应该很容易实现 - 只需设置用户的角色名称......协助赞赏。

- 更新 -

我注释掉了自定义AddUserToRole()方法的内容,用户可以登录。但是,在调用操作方法时,未执行角色检查 - 即。应该失败,因为角色名称实际上不存在:

    [HttpGet]
    [AllowAnonymous]
    [Authorize(Roles="WaitConfirmationxxx")]
    public ActionResult WaitConfirmation()
    {

我还注意到IsInRole()调用了自定义GetRolesForUser()方法,该方法在其中执行db调用。不完全是最佳的,并且想知道这实际上是不是应该如何?

                if(User.IsInRole("WaitConfirmation"))
                {
                    // email address has not yet been confirmed
                    return RedirectToAction("WaitConfirmation", "User");
                }

- 更新 -

我的错误是认为我需要使用Roles.AddUserToRole()(除非有人另有说法)。

我还在web.config中的cacheRolesInCookie定义中添加了roleManager参数:

<roleManager enabled="true" defaultProvider="CustomRoleProvider" cacheRolesInCookie="true">

现在,当我致电if(User.IsInRole("WaitConfirmation"))时,系统会调用我的自定义GetRolesForUser(string username)

现在的问题是Authorization属性都不起作用。建议?

1 个答案:

答案 0 :(得分:0)

您需要删除[AllowAnonymous]属性,将其更改为:

[HttpGet]
[Authorize(Roles="WaitConfirmationxxx")]
public ActionResult WaitConfirmation()
{

如果您的RoleProvider配置正确,则在尝试从上述方法的属性进行授权时,应该使用此方法。

public override string[] GetRolesForUser(string username)
        {