ASP.NETカスタムメンバーシッププロバイダPart.3(インプリメンテーションプロバイダクラス:XmlRoleProvider)

14976 ワード

ロール・プロバイダの実装は、ロールを管理するための構造が簡単であるため、メンバーシップ・プロバイダの実装よりも容易です.新しい概念はありません.RoleStoreクラスの対応するメソッドを呼び出してロールを作成したり、ロールを削除したり、ロールにユーザーを割り当てたり、ロールからユーザーを削除したりするだけです.
ロールプロバイダの完全なインタフェースは次のとおりです.
public class XmlRoleProvider : RoleProvider
{
    public override void Initialize(string name, NameValueCollection config)
    public override string ApplicationName { get; set; }
 
    public override void CreateRole(string roleName)
    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
    public override bool RoleExists(string roleName)
    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
    public override string[] GetAllRoles()
    public override string[] GetRolesForUser(string username)
    public override string[] GetUsersInRole(string roleName)
    public override bool IsUserInRole(string username, string roleName)
    public override string[] FindUsersInRole(string roleName, string usernameToMatch)
}

 
このクラスはRoleProviderから継承されています.カスタム属性を初期化するInitializeメソッドを再上書きしますが、今回はキャラクタプロバイダが属性の一部しかサポートしていないため、簡単です.ベースクラスが提供する唯一の属性はApplicationNameで、その他はあなたが決めます.
public override void Initialize(string name, NameValueCollection config)
{
    if (config == null)
    {
        throw new ArgumentException("config");
    }
    if (string.IsNullOrEmpty(name))
    {
        name = "XmlRoleProvider";
    }
    if (string.IsNullOrEmpty(config["description"]))
    {
        config.Remove("description");
        config.Add("description", "XML Role Provider");
    }
 
    base.Initialize(name, config);
 
    applicationName = "DefaultApp";
    foreach (string key in config.Keys)
    {
        if (key.ToLower().Equals("applicationname"))
        {
            applicationName = config[key];
        }
        else if (key.ToLower().Equals("filename"))
        {
            fileName = config[key];
        }
    }
}

名前と説明構成パラメータを再確認し、構成されていない場合はデフォルト値を使用して初期化します.ベースクラスのInitializeを呼び出すことを忘れないでください.そうしないと、ベースクラスが管理するデフォルトの構成値は初期化されません.FileNameプロパティは、ロール情報を格納するXMLファイル名を指定します.
 
次に、このクラスはロールを管理する方法を提供し、最下位のRoleStoreメソッドにアクセスする必要があります.たとえば、ロールを作成します.
public override void CreateRole(string roleName)
{
    SimpleRole newRole = new SimpleRole();
    newRole.RoleName = roleName;
    newRole.AssignedUsers = new StringCollection();
 
    CurrentStore.Roles.Add(newRole);
    currentStore.Save();
}

 
RoleExists()入力されたロール名がリストにあるかどうかを確認します.
public override bool RoleExists(string roleName)
{
    try
    {
        return CurrentStore.GetRole(roleName) != null;
    }
    catch
    {
        throw;
    }
}

 
DeleteRole()は、下位ストレージのロールを削除しようとします.
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
    try
    {
        SimpleRole role = CurrentStore.GetRole(roleName);
        if (role == null)
        {
            return false;
        }
        else
        {
            CurrentStore.Roles.Remove(role);
            CurrentStore.Save();
            return true;
        }
    }
    catch
    {                
        throw;
    }
}

 
AddUsersToRoles()は、ユーザーをロールに追加します.この方法は比較的複雑である.まず、ロール配列を巡回し、各ロールインスタンスをそれぞれ取得し、ロールのユーザーリストと受信したユーザーリストを比較してユーザーの追加を行います.
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
    try
    {
        foreach (string roleName in roleNames)
        {
            SimpleRole role = CurrentStore.GetRole(roleName);
            if (role != null)
            {
                foreach (string username in usernames)
                {
                    if (!role.AssignedUsers.Contains(username))
                    {
                        role.AssignedUsers.Add(username);
                    }
                }
            }
        }
        CurrentStore.Save();
    }
    catch
    {
        throw;
    }
}

 
RemoveUsersFromRoles()の機能は、上記とは逆です.
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
    try
    {
        foreach (string roleName in roleNames)
        {
            SimpleRole role = CurrentStore.GetRole(roleName);
            if (role!=null)
            {
                foreach (string username in usernames)
                {
                    if (role.AssignedUsers.Contains(username))
                    {
                        role.AssignedUsers.Remove(username);
                    }
                }
            }
        }
        CurrentStore.Save();
    }
    catch
    {
        throw;
    }
}

 
カスタムロールプロバイダの残りの方法は簡単です.ほとんどの場合、これらの方法はストレージ内のロールを巡り、いくつかの情報を返すだけです.ほとんどの場合、ユーザー名またはロール名の文字列配列です.次のようになります.
public override string[] GetAllRoles()
{
    try
    {
        return CurrentStore.Roles.Select(p => p.RoleName).ToArray();
    }
    catch
    {
        throw;
    }
}
 
public override string[] GetRolesForUser(string username)
{
    try
    {
        return CurrentStore.GetRolesForUser(username).Select(p => p.RoleName).ToArray();
    }
    catch
    {
        throw;
    }
}
 
public override string[] GetUsersInRole(string roleName)
{
    try
    {
        return CurrentStore.GetUsersInRole(roleName);
    }
    catch
    {
        throw;
    }
}
 
public override bool IsUserInRole(string username, string roleName)
{
    try
    {
        SimpleRole role = CurrentStore.GetRole(roleName);
        if (role != null)
        {
            return role.AssignedUsers.Contains(username);
        }
        else
        {
            throw new ProviderException("Role does not exist!");
        }
    }
    catch
    {
        throw;
    }
}

 
FindUsersInRole()は、roleNameパラメータを使用してパターンマッチングによってユーザーを検索してみます.SQLメンバーシッププロバイダは、モードマッチングのために%記号を使用しますが、正規表現では%記号はプレースホルダとして使用されません.したがって、正規表現で識別可能な表現で置き換える必要があります.つまり、w*です.
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
    try
    {
        SimpleRole role = CurrentStore.GetRole(roleName);
        if (role != null)
        {
            List<string> results = new List<string>();
            Regex expression = new Regex(usernameToMatch.Replace("%", @"\w*"));
            foreach (string userName in role.AssignedUsers)
            {
                if (expression.IsMatch(userName))
                {
                    results.Add(userName);
                }
            }
            return results.ToArray();
        }
        else
        {
            throw new ProviderException("Role does not exist!");
        }
    }
    catch
    {
        throw;
    }
}

 
通常、1つのプロバイダを実装する方法を知っていれば、別のプロバイダを実装する方法がわかります.このプロセスには新しい概念はありませんが、コード量と注意深い作業が必要です.