63

我正在使用 ADO.NET 从服务器上的数据库中获取一些信息,
所以这就是我所做的:

string conStr = "Data Source=myServer\SQLEXPRESS;Initial Catalog=DBName;User ID=myUser;Password=myPassword";

SqlConnection conn = new SqlConnection(conStr);

conn.Open();
// do stuff
conn.Close();

但是在调用Open方法后,我注意到conn.ConnectionString正在丢失密码,所以它变成:

"Data Source=myServer\SQLEXPRESS;Initial Catalog=DBName;User ID=myUser;"

这会导致任何 SqlCommand 后记出现异常
如何解决这个问题?
注意:奇怪的是并不总是发生
编辑:我认为它与它自己的命令没有任何关系,但无论如何

SqlCommand command = new SqlCommand("select GetDate()", conn);
SqlDataReader reader = command.ExecuteReader();
4

3 回答 3

90

出于安全原因,这是设计使然。来自MSDN

ConnectionString 类似于 OLE DB 连接字符串,但不相同。与 OLE DB 或 ADO 不同,返回的连接字符串与用户设置的 ConnectionString 相同,如果 Persist Security Info 值设置为 false(默认值),则减去安全信息。除非将 Persist Security Info 设置为 true,否则用于 SQL Server 的 .NET Framework 数据提供程序不会在连接字符串中保留或返回密码。

于 2012-09-17T22:32:05.703 回答
61

查看连接字符串,为了将密码保留在 ConnectionString 属性中,您必须将密码添加"Persist Security Info=true;"到连接字符串本身

以下示例将删除密码:

string conStr = "Data Source=localhost;Initial Catalog=MyDatabase;User Id=MyUser;Password=MyPassword";
SqlConnection conn = new SqlConnection(conStr);
conn.Open();
conn.Close();
Console.WriteLine(conn.ConnectionString);

以下示例将密码保存在conn.ConnectionString

string conStr = "Persist Security Info=True;Data Source=localhost;Initial Catalog=MyDatabase;User Id=MyUser;Password=MyPassword";
SqlConnection conn = new SqlConnection(conStr);
conn.Open();
conn.Close();
Console.WriteLine(conn.ConnectionString);

它是在连接字符串本身而不是在SqlConnection对象中设置的属性,我将它放在连接字符串的开头,这样您就不必滚动查看它,它可以在连接字符串中的任何位置,我通常会看到它在末尾。

就像其他人所说的那样,如果您需要这样做,您很可能没有完全按照预期使用 SqlConnection 对象。

于 2013-01-29T16:42:26.357 回答
7

您可能想要添加自己的验证,但这将采用标准 SqlConnection(没有持久安全性)并访问私有 ConnectionOptions 属性以检索连接字符串。

public static string SqlConnectionToConnectionString(SqlConnection conn)
{
    System.Reflection.PropertyInfo property = conn.GetType().GetProperty("ConnectionOptions", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
    object optionsObject = property.GetValue(conn, null);
    System.Reflection.MethodInfo method = optionsObject.GetType().GetMethod("UsersConnectionString");
    string connStr = method.Invoke(optionsObject, new object[] { false }) as string; // argument is "hidePassword" so we set it to false
    return connStr;
}

请注意,如果 MS 更改底层实现,这可能会中断,因为我们正在使用反射。我不建议这是最好的方法,但这是一种方法。

于 2014-02-14T22:32:19.607 回答