我正在使用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();
但在调用打开方法后,我注意到 conn.ConnectionString 正在丢失密码,因此它变为:
"Data Source=myServer\SQLEXPRESS;Initial Catalog=DBName;User ID=myUser;"
导致任何SqlCommand后的异常 如何解决这个问题? 注意:奇怪的是,总是不会发生这种情况 编辑:我认为它与自己的命令没有任何关系,但无论如何
SqlCommand command = new SqlCommand("select GetDate()", conn);
SqlDataReader reader = command.ExecuteReader();
答案 0 :(得分:61)
出于安全原因,这是设计使然。来自MSDN:
ConnectionString类似于OLE DB连接字符串,但不完全相同。与OLE DB或ADO不同,返回的连接字符串与用户设置的ConnectionString相同,如果Persist Security Info值设置为false(默认值),则减去安全信息。 除非将Persist Security Info设置为true,否则SQL Server的.NET Framework数据提供程序不会在连接字符串中保留或返回密码。
答案 1 :(得分:44)
查看连接字符串,为了将密码保存在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对象。
答案 2 :(得分:6)
您可能希望添加自己的验证,但这将采用标准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更改了底层实现,这可能会中断,因为我们正在使用反射。我并不是说这是最好的方法,但这是一种方式。