SqlRoleProvider на IIS8 Экспресс

Мое веб-приложение (служба 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"/>

3 ответа

То, что сказал Владимир, верно, но на самом деле не объясняет, что происходит. Исключением NullReferenceException является код EtwTrace, который находится в IsUserInRole и GetRolesForUser. Все остальное в классе Roles объясняет тот факт, что HttpContext.Current может быть нулевым. Я нашел это, посмотрев в справочном источнике Microsoft для "NET, версия 4.5" на http://referencesource.microsoft.com/netframework.aspx

В любой другой тестовой среде, которую я пробовал, уровень трассировки был недостаточен для запуска исключения NullReferenceException. Только когда я использовал IIS Express 8 после установки Visual Studio 2013, я увидел проблему и только в IIS Express.

Что вы можете с этим поделать?

Один из вариантов - включить "Режим совместимости ASP.Net" для WCF. Сначала в файле web.config добавьте атрибут aspNetCompatibilityEnabled="true" в узел . Затем выберите свой класс обслуживания в этом поведении, добавив атрибут [System.ServiceModel.Activation.AspNetCompatibilityRequirements(RequirementsMode = System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Allowed)] в определение класса. С включенной этой функциональностью HttpContext будет включен. к тому времени, когда вы будете запрашивать роли из класса Roles, предполагая, что вы не работаете с фоновым потоком, как упомянул Владимир (в этом случае вам сначала нужно будет исправить HttpContext.Current). Вы можете узнать больше о режиме совместимости ASP.NET для WCF по адресу http://blogs.msdn.com/b/wenlong/archive/2006/01/23/516041.aspx.

Другой вариант - обойти класс Roles для этих двух методов. Вместо вызова Roles.IsUserInRole, вызовите Roles.Provider.IsUserInRole. Вместо вызова Roles.GetRolesForUser, вызовите Roles.Provider.GetRolesForUser. Каждый метод имеет одинаковые доступные перегрузки. Вы теряете остановки трассировки и локальный кэш ролей, но игнорируете исключение нулевой ссылки.

Если вы вызываете Roles.IsUserInRole в другом потоке, вам следует проверить HttpContext. В этом случае будет пусто. Итак, для исправления вы должны скопировать HttpContext из основного потока в дочерний поток.

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

        thread.Start();

Уверен, что ваша проблема связана с базой данных и разрешением учетной записи, обращающейся к ней. Попробуйте добавить свою учетную запись IIS в sa priv и посмотрите, решится ли проблема. Если это так, то у вас отсутствует разрешение.

Другие вопросы по тегам