December 1, 2009

How can I customize my user model in my ASP.NET MVC web site? Part 4

Extending the RoleProvider

Related Posts

In my previous blog post, I described the method for integrating a custom user model into the .NET Framework’s implementation of the MembershipModel. In this blog post I’ll discuss using a custom RoleProvider. The role provider handles whether or not your user has access to certain resources within your site. This is different than the MembershipProvider in that the MembershipProvider is used primarly to allow the user to log into your site.

This works in a very similar manner to the MembershipProvider we discussed previously. We hook it up in the web.config in exactly the same way.

I’ve created a class called MySiteRoleProvider which derives from the RoleProvider abstract base class.

using System;
using System.Web.Security;
public class MySiteRoleProvider : RoleProvider
{
}

…and I’ve hooked it into my application in the section of the web.config.

<roleManager enabled="true" defaultProvider="MySiteRoleProvider">
 <providers>
  <clear />
  <add  name="MySiteRoleProvider"
     type="UserModel.MySiteRoleProvider" 
    connectionString="MySiteDatabase" />
 </providers>
</roleManager>

I’ve got considerably less properties specified in my custom role provider than I do in my membership provider – in fact the only one of any relevance that I’ve kept from the AspNetSqlRoleProvider is connectionString. Once again, the MVC framework will do the heavy lifting and automatically use MySiteRoleProvider as the role provider for this site. We don’t need to do any more heavy lifting to get things working.

I’ll start off with the Initialize() method again to hook my configuration up to my provider… I'll condense my code somewhat to keep it brief. If you don't understand how to implement the Initialize method, please review my previous post

private string _connectionString;
private ConnectionStringSettings _connectionStringSettings;

public override void Initialize(string name, NameValueCollection config)
{
 base.Initialize(name, config);

 _connectionString = (string)config["connectionString"];
 _connectionStringSettings = 
 ConfigurationManager.ConnectionStrings[_connectionString];
}

As you’ll notice, it’s quite a bit simpler than the initialize for the membership provider, but it does the same thing. It’s just parsing the configuration and configuring our private members.

Next I’ll move on to the GetUsersInRole and IsUserInRole methods:

public override string[] GetUsersInRole(string roleName)
{
    using (IDbConnection con = InitConnection())
    using (IDbCommand cmd = con.CreateCommand("dbo.GetUsersInRole", CommandType.StoredProcedure))
    {
        cmd.AddParameters(
            cmd.CreateParameter("@RoleName", DbType.String, roleName),
            cmd.CreateParameter("@ReturnValue", DbType.Int32, ParameterDirection.ReturnValue));

        using (IDataReader rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            List roles = new List();
            while (rdr.Read())
            {
                roles.Add(rdr.GetString(0));
            }
            return roles.ToArray();
        }
    }
}

public override bool IsUserInRole(string username, string roleName)
{
 return Array.Exists(GetRolesForUser(username), role =>
 {
  role.Equals(roleName));
 }
}

As you can see, these two methods are the crux of the RoleProvider from your website’s perspective. The GetUsersInRole method grabs a list of all the users that are part of the role specified by the roleName parameter using the stored proc, which could easily hook up to a custom table in your database rather than the provided AspNet model. The IsUserInRole method looks for the existence of the username in the resulting array produced by the GetUsersInRole method. In the next post I’ll discuss the ProfileProvider which is the key to including user profile information like a custom display name, reputation and a host of other bits of useful and interesting data about your users.

No comments:

Post a Comment