【问题标题】:Transaction and ASP.NET Membership API事务和 ASP.NET 成员资格 API
【发布时间】:2011-04-28 17:47:12
【问题描述】:

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

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

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

【问题讨论】:

    标签: .net asp.net-membership subsonic3 transactionscope msdtc


    【解决方案1】:
    • 您可以配置成员资格/角色提供者以使用您需要的连接字符串。

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

    【讨论】:

    • 使用连接字符串配置它们对用于连接数据库的 SqlConnection 对象没有任何影响。 SubSonic 和 Membership API 正在创建不同的 SqlConnection 对象。
    • inheritance route 是一种方式,但是我必须做额外的工作:D 目前我正在使用存储过程,但会编写一组类来包装提供程序调用以供将来使用.
    【解决方案2】:

    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() 的实现,如 Reflector 中所示:

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      相关资源
      最近更新 更多