3

我的 Web 应用程序(一个 WCF 服务)使用SqlRoleProvider,它在Visual Studio Development Server上运行良好。将其切换到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"/>
4

3 回答 3

4

弗拉基米尔说的是真的,但实际上并没有解释发生了什么。引发 NullReferenceException 的是 IsUserInRole 和 GetRolesForUser 中的 EtwTrace 代码。Roles 类中的所有其他内容都说明了 HttpContext.Current 可以为 null 的事实。我通过在http://referencesource.microsoft.com/netframework.aspx中查看“NET,版本 4.5”的 Microsoft 参考源发现了这一点

在我尝试过的所有其他测试环境中,跟踪级别都不足以触发 NullReferenceException。只有在安装 Visual Studio 2013 后使用 IIS Express 8 时,我才看到问题,并且仅在 IIS Express 中。

你能为这个做什么?

一种选择是为 WCF 启用“ASP.Net 兼容模式”。首先,在 web.config 中,将属性 aspNetCompatibilityEnabled="true" 添加到节点 <configuration><system.serviceModel><serviceHostingEnvironment>。然后通过将属性 [System.ServiceModel.Activation.AspNetCompatibilityRequirements(RequirementsMode = System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Allowed)] 添加到类定义中来选择您的服务类。启用此功能后,将填充 HttpContext.Current当您从 Roles 类请求角色时,假设您没有在 Vladimir 提到的后台线程上工作(在这种情况下,您需要先修补 HttpContext.Current)。您可以在以下位置阅读有关 WCF 的 ASP.NET 兼容模式的更多信息http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx

另一种选择是为这两种方法绕过 Roles 类。不要调用 Roles.IsUserInRole,而是调用 Roles.Provider.IsUserInRole。不要调用 Roles.GetRolesForUser,而是调用 Roles.Provider.GetRolesForUser。每个方法都有相同的重载可用。您丢失了跟踪停止和本地角色缓存,但您绕过了空引用异常。

于 2013-11-27T23:23:56.090 回答
1

如果您在不同的线程中调用 Roles.IsUserInRole,那么您应该检查 HttpContext。在这种情况下将为空。因此,为了修复,您应该将 HttpContext 从主线程复制到子线程。

        var context = HttpContext.Current;
        Thread thread = new Thread(delegate() {
            if (HttpContext.Current == null)
                HttpContext.Current = context;
        });

        thread.Start();
于 2013-05-22T13:47:31.720 回答
0

相当确定您的问题将与数据库和访问它的帐户的权限有关。尝试将您的 IIS 帐户添加到 sa priv 并查看问题是否解决。如果是这样,那么您缺少权限。

于 2012-10-22T12:24:25.723 回答