Каков наилучший способ изменения строки подключения web.config во время выполнения? - PullRequest
3 голосов
/ 09 марта 2009

Я довольно новичок в мире ASP.NET, поэтому у меня возникли небольшие проблемы с поиском наилучшего способа настройки строки подключения во время выполнения, чтобы все приложение использовало эту строку подключения. Вот еще немного информации о приложении, которое я планирую построить:

  • Приложение использует проверку подлинности с помощью форм, а не проверку подлинности Windows
  • Будет страница входа в систему, где пользователь вводит свой логин и пароль для входа на SQL Server
  • Для простоты я хотел бы, чтобы все элементы управления SQLDataSource указывали на строку подключения web.config. Это будет сделано во время разработки, а не для их программной настройки. Таким образом, они будут иметь свойство, подобное этому: ConnectionString = "<% $ ConnectionStrings: MyDB%>"
  • Я бы хотел найти способ изменить строку подключения «MyDB» во время выполнения, чтобы она использовала идентификатор входа и пароль, предоставленные пользователем. Но я НЕ хочу, чтобы это сохранялось в web.config. Он должен быть активным только для сеанса этого пользователя.

Каков "стандартный" способ, которым люди обычно делают это? Я предполагаю, что один из методов - создать переменную Session со строкой соединения, а затем программно изменить свойство ConnectionString каждого элемента управления SQLDataSource во время загрузки страницы. Но я надеялся избежать этого, если это возможно.


Поскольку несколько человек спрашивали, почему я хотел бы использовать уникальное соединение для каждого пользователя, и были обеспокоены отсутствием объединения, я решил прокомментировать это здесь, а не комментировать каждый отдельный ответ.

Характер этого приложения требует, чтобы каждый пользователь подключался к базе данных под своей учетной записью. Внутренняя безопасность связана с их учетной записью, поэтому мы не можем использовать общие учетные записи, такие как «пользователь» и «администратор». Нам также нужно знать конкретную личность каждого пользователя для контроля контроля. В приложении обычно всего от 10 до 20 пользователей, поэтому отсутствие объединения не является проблемой. Мы могли бы обсудить достоинства этого подхода в другой раз, но, к сожалению, у меня нет выбора здесь - проект требует, чтобы каждый пользователь подключался к базе данных под своей учетной записью.

Я хотел бы потребовать аутентификацию Windows, но, к сожалению, некоторые реализации этого приложения потребуют аутентификацию SQL.

Если бы я мог просто установить строку подключения при объявлении элементов управления SQLDataSource следующим образом, это было бы несложно:

  <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString = "<%= Session("MyConnectionString") %>"
    SelectCommand="SELECT * FROM [Customers]">
  </asp:SqlDataSource>

Но я получаю сообщение об ошибке, потому что ему не нравятся теги <%%>. Если я не могу сделать это при объявлении элемента управления, какой самый простой способ сделать это программно для каждого элемента управления SQLDataSource в приложении?

Большое спасибо всем за помощь!

Ответы [ 9 ]

5 голосов
/ 10 марта 2009

Если вы не хотите углубляться в код позади, есть другой способ сделать это.

Сначала прочитайте эту статью о строителях выражений . Одна из моих любимых вещей, которую я могу использовать в своих веб-приложениях!

Теперь немного кода:

Сначала создайте в своем проекте класс, содержащий следующее:

using System;
using System.CodeDom;
using System.Web.UI;
using System.Web.Compilation;

namespace MyNamespace.Web.Compilation
{
    [ExpressionPrefix("code")]
    public class CodeExpressionBuilder : ExpressionBuilder
    {
        public override CodeExpression GetCodeExpression(BoundPropertyEntry entry,
           object parsedData, ExpressionBuilderContext context)
        {
            return new CodeSnippetExpression(entry.Expression);
        }
    }

}

Затем в web.config зарегистрируйте построитель выражений следующим образом

...
<compilation debug="false">
  <expressionBuilders>
    <add expressionPrefix="Code" type="MyNamespace.Web.Compilation.CodeExpressionBuilder"/>
  </expressionBuilders>
</compilation>
...

(весь код выше взят из здесь и слегка изменен)

Наконец, измените ваш SqlDataSource на следующий (C #):

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString='<%$ code: (string)Session["MyConnectionString"] ?? ConfigurationManageer.ConnectionStrings["myDefaultConn"].ConnectionString %>'
    SelectCommand="SELECT * FROM [Customers]">
</asp:SqlDataSource>

Если вы хотите (и я бы порекомендовал) создать статический класс, который будет обрабатывать для вас строку подключения, скажите что-то вроде:

public static ConnectionManager
{
   public static string GetConnectionString()
   {
      return HttpContext.Current.Session["MyConnectionString"] as string ??
             ConfigurationManager.ConnectionStrings["DefaultConnectionStr"].ConnectionString;
   }
}

Тогда ваш SqlDataSource будет

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString='<%$ code: ConnectionManager.GetConnectionString() %>'
    SelectCommand="SELECT * FROM [Customers]">
</asp:SqlDataSource>

Таким образом, если вам когда-нибудь понадобится изменить способ получения строки подключения, вы можете сделать это в одном месте!

1 голос
/ 10 марта 2009

Я не рекомендую вам делать это, потому что у вас будут проблемы с масштабируемостью. Веб-приложение не сможет использовать пул соединений и откроет столько соединений, сколько у вас есть пользователей, обращающихся к нему. У вас также будет много реальных соединений для открытия / закрытия.

Если вы решили продолжить:

  • Если вы можете использовать проверку подлинности Windows, используйте олицетворение + интегрированный режим для подключения SQL. Используйте группы Windows для настройки разрешений на сервере SQL.
  • Вы можете рекурсивно получить доступ ко всем элементам на странице в поисках sqldatasources и применить соединение к каждому из них. Вы можете прикрепить к oninit страницы из global.asax, чтобы применить его ко всем страницам.

Почему вы хотите сделать это таким образом? Какие ограничения связаны? (обычно в веб-приложениях используется модель доверенной подсистемы, т.е. аутентификация / авторизация выполняется на уровне веб-приложения / или на отдельном бизнес-уровне)

1 голос
/ 09 марта 2009

Я бы сказал, что у вас есть несколько вариантов, некоторые работают с тем, что у вас есть, другие требуют, чтобы вы что-то изменили.

  1. Сохраните подключение по умолчанию в файле web.config, загрузите его в сеанс, используйте его до тех пор, пока пользователь не войдет в систему, а затем обновите значение в сеансе.

  2. Реализация проверки подлинности Windows и олицетворения личности и настройка учетных записей Windows с доступом к блоку SQL Server.

Если вы выберете элемент номер один, создайте общую вспомогательную функцию, которая будет устанавливать соединение, сначала проверьте сеанс, а затем загрузите его из web.config. Таким образом, все ваши источники данных могут быть связаны во время разработки.

ПРИМЕЧАНИЕ: это НЕ типичная ситуация, и существуют последствия для производительности использования нескольких учетных записей SQL Server для подключения, такие как отсутствие возможности использовать пул соединений среди других элементов.

1 голос
/ 09 марта 2009

Загрузить строку подключения Web.config в переменную сеанса в Session_Start. Если пользователь предоставил свои учетные данные, обновите их в переменной сеанса. В противном случае будут действовать значения по умолчанию (web.config значения).

0 голосов
/ 24 сентября 2009

Я использую метод (я забыл, где я узнал об этом), чтобы добавить обработчик SettingsLoaded во время запуска приложения, а затем установить новую строку подключения в обработчике. Я не пробовал это в ASP.NET, просто в локальном приложении, поэтому ваш пробег может варьироваться:

Settings.Default.SettingsLoaded += new System.Configuration.SettingsLoadedEventHandler(Default_SettingsLoaded);

void Default_SettingsLoaded(object sender, System.Configuration.SettingsLoadedEventArgs e)
{
    Settings.Default["ConnectionString"] = "my new connection string";
}
0 голосов
/ 10 марта 2009

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

0 голосов
/ 10 марта 2009

У меня похожая ситуация. Я установил строку подключения в строку подключения по умолчанию из web.config. Затем в коде позади вы можете установить для строки подключения другое значение. Вы должны сделать это в Page_Load до того, как источник данных выберет событие, например так ...

SqlDataSource1.ConnectionString = ConnectionString;

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

0 голосов
/ 10 марта 2009

Как говорит Митч, вы теряете пул соединений, если у вас есть пользователи, которые входят в систему с разными учетными данными (если это вызывает разные строки соединения).

Если вы просто беспокоитесь о том, чтобы отделить пользователей-администраторов от обычных пользователей, просто используйте 2 строки подключения, одну для администраторов и одну для обычных пользователей. Используйте поставщиков ролей asp.net для предоставления соответствующих разрешений пользователям.

0 голосов
/ 09 марта 2009

Без сохранения в web.config нет способа сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...