在运行时更改web.config连接字符串的最佳方法是什么?

Cow*_*wer 3 database asp.net authentication web-applications

我对ASP.NET世界很陌生,所以我遇到了在运行时配置连接字符串并让整个应用程序使用该连接字符串的最佳方法.以下是我计划构建的应用程序的更多信息:

  • Application使用Forms身份验证,而不是Windows身份验证
  • 将有一个登录页面,用户提供其SQL Server登录ID和密码
  • 为简单起见,我希望所有SQLDataSource控件都指向web.config连接字符串.这将在设计时完成,而不是以编程方式设置它们.所以,他们会有这样的属性:ConnectionString ="<%$ ConnectionStrings:MyDB%>"
  • 我想找到一种方法在运行时更改"MyDB"连接字符串,以便它使用用户提供的登录ID和密码.但我不希望这个保存到web.config.它应仅对该用户的会话有效.

人们通常这样做的"标准"方式是什么?我假设一种方法是使用连接字符串创建一个Session变量,然后在页面加载期间以编程方式更改每个SQLDataSource控件的ConnectionString属性.但我希望尽可能避免这种情况.


由于很多人问我为什么要为每个用户使用一个独特的连接,并担心缺乏汇集,我想我会在这里评论,而不是评论每个单独的响应.

此应用程序的性质要求每个用户都使用自己的帐户连接到数据库.后端安全性与其用户帐户相关联,因此我们无法使用"用户"和"管理员"等通用帐户.我们还需要知道每个用户的特定身份以进行审计控制.该应用程序通常只有10到20个用户,因此缺乏池化不是问题.我们可以再次讨论这种方法的优点,但不幸的是我在这里没有选项 - 项目要求每个用户在他们自己的帐户下连接到数据库.

我很乐意要求Windows身份验证,但不幸的是,此应用程序的某些实现将需要SQL身份验证.

如果我可以在声明像这样的SQLDataSource控件时设置连接字符串,那么它将是一个快照:

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

但我得到一个错误,因为它不喜欢那里的<%%>标签.如果在声明控件时我不能这样做,那么对于应用程序中的每个SQLDataSource控件,以编程方式执行此操作的最简单方法是什么?

非常感谢大家的帮助!

Jos*_*non 5

如果您不想深入研究代码,那么还有另一种方法可以做到这一点.

首先阅读关于表达式构建器的文章.我最喜欢的东西之一,我的网络应用程序!

现在有些代码:

首先在项目中创建一个包含以下内容的类:

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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,在web.config中注册表达式生成器,如下所示

...
<compilation debug="false">
  <expressionBuilders>
    <add expressionPrefix="Code" type="MyNamespace.Web.Compilation.CodeExpressionBuilder"/>
  </expressionBuilders>
</compilation>
...
Run Code Online (Sandbox Code Playgroud)

(以上所有代码均来自此处并稍有修改)

最后将您的SqlDataSource更改为以下(C#):

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

如果你想(我建议)创建一个静态类来处理连接字符串,你会说:

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

然后你的SqlDataSource将是

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

这样,如果您需要更改获取连接字符串的方式,您可以在一个地方执行此操作!