在IIS8 Express上使用SqlRoleProvider

3

我的Web应用程序(一个WCF服务)使用SqlRoleProvider,在Visual Studio开发服务器上运行良好。但是将其切换到IIS8 Express会导致它抛出NullReferenceException

Roles.IsUserInRole(username, role) // neither of them actually null

我在IsUserInRole方法文档中没有找到这个异常的提示。切换回Visual Studio开发服务器可以解决问题。这个异常的原因是什么,如何正确地修复它?该项目的目标框架是.NET Framework 4。

以下是配置的连接字符串:

<add name="ConnectionString"
      connectionString="Data Source=.\sqlexpress;Initial Catalog=DevWeb;Integrated Security=True"
      providerName="System.Data.SqlClient" />

以下是roleManager/providers节点的内容:

<clear />
<add connectionStringName="ConnectionString" applicationName="MyApp" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider"/>

是的,你说得对,我看到这个 cookie 没有任何东西,你直接运行了函数。 - Aristos
我开始遇到同样的问题(在安装了最新的VS2013 RC之后)。你找出问题所在了吗? - Magnus Johansson
3个回答

4

弗拉基米尔所说的是对的,但实际上并没有解释发生了什么。导致NullReferenceException的是IsUserInRole和GetRolesForUser中的EtwTrace代码。Roles类中的其他代码都考虑了HttpContext.Current可能为空的情况。我通过查看Microsoft Reference Source中“NET,Version 4.5”的内容找到了这个问题,链接在http://referencesource.microsoft.com/netframework.aspx

在我尝试的所有其他测试环境中,跟踪级别不足以触发NullReferenceException。只有在安装了Visual Studio 2013后使用IIS Express 8时才会出现这个问题,而且只在IIS Express中出现。

你能做些什么呢?

一种选择是为WCF启用“ASP.Net兼容性模式”。 首先,在web.config中,将属性aspNetCompatibilityEnabled =“true”添加到节点 。然后通过向类定义添加属性[System.ServiceModel.Activation.AspNetCompatibilityRequirements(RequirementsMode = System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Allowed)]来选择服务类的行为。启用此功能后,假设您不是在像弗拉基米尔提到的后台线程上工作(在这种情况下,您需要先修补HttpContext.Current),当您去请求Roles类的角色时,HttpContext.Current将被填充。您可以在http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx上阅读有关WCF的ASP.NET兼容性模式的更多信息。
另一种选择是绕过这两种方法的Roles类。不要调用Roles.IsUserInRole,而是调用Roles.Provider.IsUserInRole。不要调用Roles.GetRolesForUser,而是调用Roles.Provider.GetRolesForUser。每种方法都有相同的可用重载。您会失去跟踪停止和本地角色缓存,但可以避免空引用异常。

1
如果您在不同的线程中调用Roles.IsUserInRole,则应检查HttpContext。在这种情况下,HttpContext将为空。因此,为了修复问题,您应该将主线程的HttpContext复制到子线程中。
        var context = HttpContext.Current;
        Thread thread = new Thread(delegate() {
            if (HttpContext.Current == null)
                HttpContext.Current = context;
        });

        thread.Start();

0

相信你的问题可能与数据库和访问它的帐户的权限有关。尝试将你的IIS帐户添加到sa priv中,看看问题是否得到解决。如果是这样,那么你缺少某些权限。


谢谢你,Mike。不过它是在我的账户下运行的,并且我有访问数据库的权限。 - Matthias Meid
有没有可能看一下你的connString和角色提供程序配置? - Maverick Mike
是的,当然。我已经将其添加到问题中了。 - Matthias Meid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接