存储链接字符串

有多种方法可存储链接字符串,每种方法具有不同程度的灵活性和安全性。尽管在源代码中对字符串进行硬编码提供了最优性能,但文件系统缓存确保了与在文凭系统外部存储字符串相关的性能损失可被忽略。实际上外部链接字符串(允许管理员进行配置)所提供的附加灵活性在任何情况下都是受欢迎的。

选择存储链接字符串的方法时,首先要考虑的两个重要因素是配置的安全性与简易性,其次是性能。

可以选择将数据库链接字符串存储在下列位置:

• 应用程序配置文件 例如用于ASP.NET Web应用程序的Web.config文件。
• 通用数据链接文件(UDL) (只被OLE DB .NET 数据供应器所支持)
• Windows 注册表
• 定制文件
• COM+ 目录 ,通过过使用构造字符串(只用于服务组件)

使用Windows认证访问SQL Server,就可以避免在链接字符串存储用户名和密码。如果 安全需求要求更严格的方式,那么就考虑以加密格式存储链接字符串。

对于ASP.NET Web应用程序,以加密格式将链接字符串存储在Web.config文件中是一种安全而可配置的解决方案。

注意,在链接字符串中将Persist Security Info命名值设置为假,就可以阻止利用SqlConnection 或OleDbConnection对象的ConnectionString属性返回对安全敏感的内容,如密码。

下面几个小节讨论了如何用这些方法存储链接字符串,并说明了相对的优点和缺点。这使你能根据特定的应用程序环境作出相应的的选择。

使用XML应用程序配置文件

可以使用元素<appSettings>将数据库链接字符串存储在应用程序配置文件的定制设置部分。该元素支持任意关键字-值对,如下面的代码片段所示:

<configuration>
 <appSettings>
  <add key="DBConnStr"
     value="server=(local);Integrated Security=SSPI;database=northwind"/>
 </appSettings>
</configuration>

注意  <appSettings>元素现在在<configuration>元素下面,并且不能直接出现在<system.web>下面。

优点
• 易于部署。通过常规.NET xcopy部署,链接字符串随配置文件一起被部署。
• 通过程序易于访问。ConfigurationSettings类的AppSettings属性使得在运行时读取数据库链接字符串更为简单。
• 支持动态更新(仅限于ASP.NET)。如果管理员更新了Web.config文件中的链接字符串,那么下次在字符串被访问时所作出的变化生效,这对一个无状态的组件来说,就象客户再次利用组件作出了数据访问请求一样。

缺点
• 安全性。尽管ASP.NET Internet 服务器应用程序编程接口(ISAPI)DLL阻止了客户直接访问带.config扩展名的文件,并且NTFS文件系统权限也用于进一步限制访问,但你可能仍希望避免以明文方式将这些内容存储在前端的Web服务器上。要增加安全性,需将链接字符串以加密格式存储在配置文件中。

更多信息
• 利用System.Configuration.ConfigurationSettings类的AppSettings静态属性,可以获取应用程序的定制设置。如下面的代码片段所示,此处假定先前示例的定置关键字为DBConnStr。

using System.Configuration;
private string GetDBaseConnectionString()
{
  return ConfigurationSettings.AppSettings["DBConnStr"];
}

• 关于配置.NET 框架应用程序的更多信息,见http://msdn.microsoft.com/library/en-us/cpguide/html/cpconconfiguringnetframeworkapplications.asp.

使用UDL文件

OLE DB .NET数据供应器支持在它的链接字符串中使用统一数据链接(UDL)文件名。可以以构建参数的形式将链接字符串传给OleDbConnection对象,或利用对象的ConnectionString属性设置链接字符串。

注意  SQL Server .NET数据供应器不支持在它的链接字符串中使用UDL文件。因此,只有使用OLE DB .NET数据供应器,此方法才有效。
对于OLE DB 供应器,要利用链接字符串引用UDL文件,使用“File Name=name.udl.”。

优点

• 标准方法。你也许已经在用UDL文件进行链接字符串的管理了。

缺点
• 性能。每次打开链接时,包含UDLs的链接字符串都被读取并被解析。
• 安全性。UDL文件以纯文本格式存储。利用NFTS文件权限可以确保这些文件的安全性,但这样做将引发与使用.config文件相同的问题。
• SqlClient对象不支持UDL文件。此方法不被 SQL Server .NET数据供应器所支持,而你要用此供应器访问 SQL Server 7.0及其以后版本。

更多信息
• 必须确保管理员拥有该文件的读/写访问权限以便进行管理,并且还要确保运行应用程序的身份拥有读权限。对于ASP.NET Web应用程序,应用程序工作者进程默认是以SYSTEM帐号运行的,但利用机器范围的配置文件(Machine.config)中的<processModel>元素可以将其覆盖掉。利用Web.config文件中的<identity>元素,及一个可选的指定帐号,可以进行冒充。
• 对于Web应用程序,要确保没有将UDL文件放在虚目录中,因为那样会使该文件可通过网络下载。
• 关于这些及其它与安全性相关的ASP.NET特性的更多信息,见http://msdn.microsoft.com/library/en-us/dnbda/html/authaspdotnet.asp.。

使用Windows注册表

可以利用定制关键字将链接字符串存储在Windows注册表中,但由于部署问题,建议不要使用。

优点
• 安全性。利用访问控制列表(ACLs),可以对所选的注册表关键字的访问进行管理。对更高级别的安全性,考虑对数据进行加密。
• 通过程序易于访问。.NET类支持从注册表中读取字符串。
缺点
• 部署。相关的注册表设置必须同应用程序一起部署,从某种程度上抵消了xcopy部署的优点。
使用定置文件
可以使用定制文件来存储链接字符串,然而这种技术没有优点,因此并不推荐使用。

优点

• 没有

缺点
• 额外编码。这种方法需要额外编码,并迫使你明确处理同时发生的问题。
• 部署。此文件必须同其它ASP.NET应用程序文件一起拷贝。避免将此文件放在ASP.NET应用程序的目录或子目录中,就可以阻止通过网络对其进行下载。

使用构建参数和COM+目录

可以将链接字符串存储在COM+目录中,并利用对象的构造字符串将它自动地传递给对象。COM+在初始化对象,提供配置构造字符串后,将立即调用对象的Construct方法。
注意  这个方法只用于服务组件。只有管理组件使用了其它服务,如分布式事务处理支持或对象池化时,才考虑使用此方法。

优点

• 管理性。利用组件服务MMC插件,管理员可以很方便地配置链接字符串。

缺点

• 安全性。COM+目录被认为是一个不安全的存储区(虽然利用COM+角色你可以限制对它的访问),并因此不能用于以明文维护链接字符串。
• 部署。COM+目录中的条目必须随.NET应用程序一同部署。如果使用了其它企业服务,如分布式事务或对象池化,那么将数据库链接字符串存储在目录中不会增加部署的额外开销,因为要支持其它服务,必须部署COM+目录。
• 必须为组件提供服务。可以只为所服务的组件使用构造字符串。要使能构造字符串,不能简单地从ServicedComponent类中派生所需组件类(这将为组件提供服务)。

更多信息

• 关于如何为对象构造配置.NET类的更多信息,见附录中的如何为.NET类使能对象构造 。
• 关于开发服务组件的更多信息,见http://msdn.microsoft.com/library/en-us/cpguide/html/cpconwritingservicedcomponents.asp

链接使用方式
不管何种.NET数据供应器,你必须总是:

• 尽可能晚地打开数据库链接。
• 以尽可能短的时间使用该链接。
• 尽可能快地关闭该链接。链接直到通过Close或Dispose方法关闭后,它才返回到池中。即使发现它处于崩溃状态,也应当关闭它。这样做确保了它能返回池中,并被标记为无效。对象池周期性地扫描池,以查找已被标记为无效的对象。

为确保在方法返回前链接已经关闭,考虑使用下面两个代码片段中演示的方法。第一个示例使用了finally块,第二个示例使用了C# using声明,此声明确保了对象的Dispose方法被调用。

下面的代码确保finally块关闭了链接。注意,此方法只用于Visual Basic .NET及C#中,因为Visual Basic .NET支持结构化例外处理。

public void DoSomeWork()
{
  SqlConnection conn = new SqlConnection(connectionString);
  SqlCommand cmd = new SqlCommand("CommandProc", conn );
  cmd.CommandType = CommandType.StoredProcedure;

  try
  {
    conn.Open();
    cmd.ExecuteNonQuery();
  }
  catch (Exception e)
  {
    // Handle and log error
  }
  finally
  {
    conn.Close();
  }
}

现在的代码显示了另外一种方法,此方法使用了C# using声明。注意,Visual Basic .NET并不支持using声明,或任何功能相同的对应语句。

public void DoSomeWork()
{
  // using guarantees that Dispose is called on conn, which will
  // close the connection.
  using (SqlConnection conn = new SqlConnection(connectionString))
  {
    SqlCommand cmd = new SqlCommand("CommandProc", conn);
    fcmd.CommandType = CommandType.StoredProcedure;
    conn.Open();
    cmd.ExecuteQuery();
  }
}

此方法也适用于其它对象,如SqlDataReader 或OleDbDataReader,在其它任何对象对当前链接进行处理前,这些对象必须被关闭。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐