HttpContext.Current.User.IsInRole()
calls RolePrincipal.IsInRole()
for a user authenticated via FormsAuthentication. Internally RolePrincipal.IsInRole()
calls SqlRoleProvider.GetRolesForUser()
, which creates and destroys the SqlConnection
object within the method.
There may be other solutions on SQL Server to get around this problem, but from the .NET side of the fence I only see the following options:
- Implement your own role provider so that you can manage connections to the database yourself.
- Implement your own
IPrincipal
object so that you can manage connections to the database yourself.
- Pre-fetch the roles before starting your SubSonic transaction and check the list for the relevant role as needed.
- You may not even need to store the roles, since
RolePrincipal.IsInRole()
caches the roles when it is called and only goes out to the database if the cache is empty or invalidated. Calling IsInRole()
prior to starting your transaction will pre-populate the RolePrincipal
object's cache which means subsequent calls in the middle of the SubSonic transaction will pull the roles from the cache instead of connecting to the database to get them.
I'm really not convinced that the last idea is a good one, as I'm sure there are plenty of ways this can go wrong. I think the easiest solution is to pre-fetch the roles prior to beginning the SubSonic transaction.
I hope that helps.
EDIT: For completeness, here is the implementation of RolePrincipal.IsInRole()
as seen in 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);
}