事务和 ASP.NET 成员资格 API



希望你们中的某个人去过那里。我需要做一些涉及多个表的数据库工作。我正在使用SubSonic 3 SimpleRepository来更新/访问记录。现在,在更新表的调用之间,我调用System.Web.Security.Roles方法来执行一些查找。我正在使用单个存储库对象对 DAO 进行所有更新,但是当我的代码命中User.IsInRole("blahblah")时它会抛出异常MSDTC is not available on the server

我知道它正在发生,因为SimpleRepository正在使用不同的连接,而Membership API对象正在使用另一个连接。

有没有办法绕过它,或者我必须将Membership API对象包装在我自己的类中?

  • 可以将成员身份/角色提供程序配置为使用所需的连接字符串。

  • 您可以从任何此提供程序继承,并将每个方法的调用包装为事务范围,从外部控制。

HttpContext.Current.User.IsInRole()

通过 FormsAuthentication 进行身份验证的用户进行RolePrincipal.IsInRole()调用。在内部RolePrincipal.IsInRole()调用 SqlRoleProvider.GetRolesForUser() ,这会在方法中创建和销毁SqlConnection对象。

SQL Server 上可能还有其他解决方案可以解决此问题,但从围栏的 .NET 端,我只看到以下选项:

  • 实现您自己的角色提供程序,以便您可以自己管理与数据库的连接。
  • 实现您自己的 IPrincipal 对象,以便您可以自己管理与数据库的连接。
  • 在开始 SubSonic 事务之前预获取角色,并根据需要检查相关角色的列表。
  • 您甚至可能不需要存储角色,因为RolePrincipal.IsInRole()在调用角色时缓存角色,并且仅在缓存为空或无效时才发送到数据库。在开始事务之前调用IsInRole()将预填充RolePrincipal对象的缓存,这意味着SubSonic 事务中间的后续调用将从缓存中提取角色,而不是连接到数据库以获取它们。

我真的不相信最后一个想法是一个好主意,因为我确信有很多方法可能会出错。我认为最简单的解决方案是在开始 SubSonic 事务之前预获取角色。

我希望这有所帮助。

编辑:为了完整起见,以下是反射器中看到的RolePrincipal.IsInRole()的实现:

public bool IsInRole(string role)
{
    if (this._Identity == null)
    {
        throw new ProviderException(SR.GetString("Role_Principal_not_fully_constructed"));
    }
    if (!this._Identity.IsAuthenticated || (role == null))
    {
        return false;
    }
    role = role.Trim();
    if (!this.IsRoleListCached)
    {
        this._Roles.Clear();
        foreach (string str in Roles.Providers[this._ProviderName].GetRolesForUser(this.Identity.Name))
        {
            if (this._Roles[str] == null)
            {
                this._Roles.Add(str, string.Empty);
            }
        }
        this._IsRoleListCached = true;
        this._CachedListChanged = true;
    }
    return (this._Roles[role] != null);
}

相关内容

  • 没有找到相关文章

最新更新