SQLMembershipProvider и перенос приложения на сервер

В этой статье я хочу рассказать о решении проблеме переноса базы данных ASP.NET приложения с машины разработчика на сервер если используется SQLMembershipProvider для разграничения доступа. Проявляется проблема в виде такого сообщения об ошибке: The user instance login flag is not supported on this version of SQL Server. The connection will be closed

Если при разработке ASP.NET приложения мы применяем стандартные средства авторизации мы можем использовать базу данных MSSQL для хранения информации о пользователях и SQLMembershipProvider для доступа к ней. По умолчанию база данных расположена в каталоге APP_DATA и называется aspnetdb.mdf. Настройки соединения с этой базой данных прописаны в глобальном файле конфигурации .NET и ничего дополнительно в нашем приложении прописывать не нужно. Все работает замечательно до тех пор, пока мы не развернули приложение и базу данных на сервере. При попытке войти в приложение мы получаем указанное выше сообщение об ошибке.

Все потому, что на машине разработчика мы использовали базу данных MSSQL Express а на сервере установлена полная версия MSSQL. В этом случае приложение не может получить доступ к базе данных в папке APP_DATA так как строка соединения по умолчанию для SQLMembershipProvider предполагает использование именно Express версии MSSQL.

Перенесем данные в базу полной версии MSSQL и настроим строку соединения в приложении на эту новую базу данных. Само приложение должно заработать нормально но авторизация осталась сломана …

Чтобы SQLMembersipProvider начал работать с нашей базой данных нужно переопределить строку соединения по умолчанию при помощи добавления такого вот кода в файл конфигурации:

  1:     <connectionStrings>
  2:         <remove name="LocalSqlServer" />
  3:         <add name="LocalSqlServer"
  4:             connectionString="<строка подключения>"
  5:             providerName="System.Data.SqlClient"/>
  6:     </connectionStrings>

Хочу обратить внимание на то, что нужно сначала удалить настройки по умолчанию (строка 2) и только потом добавлять новое соединение. Название строки соединения должно быть LocalSqlServer

Чтобы не создавать большого количества строк подключения в настройках приложения (само приложение тоже будет работать с базой данных и ему тоже нужно знать как соединяться с базой данных) я рекомендую всегда переопределять соединение по умолчанию и всегда использовать название подключения LocalSqlServer если это возможно

Иными словами сразу при создании нового ASP.NET приложения добавьте в файл конфигурации такие строки:

  1:     <connectionStrings>
  2:         <remove name="LocalSqlServer" />
  3:         <add name="LocalSqlServer"
  4:             connectionString="
  5:                 data source=.\SQLEXPRESS;Integrated Security=SSPI;
  6:                 AttachDBFilename=|DataDirectory|aspnetdb.mdf;
  7:                 User Instance=true"
  8:             providerName="System.Data.SqlClient"/>
  9:     </connectionStrings>

Это позволит позже легко перейти к использованию полной версии MSSQL и избежать проблем с ненужными настройками строк подключения с разными названиями но одними и теми же параметрами.

SQLMembershipProvider и перенос приложения на сервер: 4 комментария

  1. SanSYS

    хм… а разве это не стд подход? даже в 208-й студии в настройках приложения когда разрешаешь юзать асп аутентификацию — она автоматом создает бд в аппдате и стринги сама прописывает…

  2. dv

    Не совсем так … база данных в app_data создается стандартная (aspnetdb.mdf), строка подключения к ней указана в настройках по умолчанию. Причем предполагается, что эта база данных будет работать под MSSQL Express. Проблема возникает потом, когда мы хотим перенести такое приложение вместе с базой данных на рабочий сервер, где нет Express версии а есть только полная. В этом случае сервер не может найти базу данных, так как строка соединения с базой содержит что то, что не поддерживается полной версией сервера.
    Даже если добавить в приложение строку соединения с базой данных и указать ее название в Membership Provider и в Roles Provider ничего работать не будет, так как где то внутри эти провайдеры все равно пытаются использовать стандартное соединение с именем LocalSQLServer и возникает исключение, про которое идет речь в статье. Чтобы все заработало я предлагаю переопределить эту стандартную строку соедниения.
    Теперь то, что я имел в виду когда говорил про несколько строк соединения.
    Сценарий такой: мы создали приложение, положили базу данных в app_data. Где то на странице используем SQLDataSource, в момент его настройки Wisard предлагает нам добавить новое соединение в файл конфигурации, мы соглашаемся (LocalSQLServer в визарде не отображается, выбрать его мы не можем потому создаем новое соединение).
    Потом прикручиваем авторизацию, провайдеры используют LocalSQLServer но нигде в файле конфигурации это не указывается (так как прописано в конфигурации по умолчанию). Переносим все на сервер — авторизация не работает. Вспоминаем, что это проблемы с использованием неправильной строки соединения и переопределяем стандартное соединение LocalSQLServer таким образом, чтобы происходило подключение к той же базе, которая используется в приложении.
    В результате имеем два соединения с одинаковыми параметрами подключения но разными названиями. Я предлагаю сразу же явно переопределять LocalSQLServer и использовать это соединение во всех случаях в процессе написания приложения.
    Это позволяет избежать проблем с переносом на сервер и избавляет от необходимости прописывать второе соединение в файле конфигурации на том этапе, когда что то переделывать уже поздно.

  3. SanSYS

    Вы правы, действительно изменения потребуются

    кстати говоря, если будет использована другая БД (копия, или даже возможно просто в случае выкладывания), то идентификатор приложения изменится, и все пользователи типа "слетают", для решения этой проблемы нужно указать applicationName у мембершиппровайдера (начинающим может пригодиться)

    <membership defaultProvider="MySqlMemberShipProvider">
    <providers>
    <clear/>
    <add name="MySqlMemberShipProvider" applicationName="simplecms" …

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *