连接后,ConnectionString丢失密码.打开

Sta*_*tar 44 c# ado.net

我正在使用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();
Run Code Online (Sandbox Code Playgroud)

但在调用Open方法后,我注意到conn.ConnectionString正在丢失密码,因此它变为:

"Data Source=myServer\SQLEXPRESS;Initial Catalog=DBName;User ID=myUser;"
Run Code Online (Sandbox Code Playgroud)

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

SqlCommand command = new SqlCommand("select GetDate()", conn);
SqlDataReader reader = command.ExecuteReader();
Run Code Online (Sandbox Code Playgroud)

Tho*_*que 72

出于安全原因,这是设计的.来自MSDN:

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

  • @Star,我给你的链接有一个例子.只需在连接字符串中包含"Persist Security Info = True"即可.但无论如何,你不应该这样做......如果你需要ConnectionString属性来保留密码,你可能没有正确使用它. (6认同)
  • 静默删除部分连接字符串。默认情况下!并且只有在第一次使用之后......这是确保开发人员浪费时间调试奇怪问题的好方法。就像代码随意抛出 `SqlException: Login failed for user ...` 因为你在错误的时间检查了一个连接字符串。这是一种奇怪的安全方式。他们至少可以让它抛出异常而不是返回虚假数据! (4认同)
  • @Star,我最好的猜测是你在关闭后重新使用SqlConnection; 你应该创建一个新的.如果没有看到更多代码,这是我能做的最好的...... (3认同)

Ada*_*oni 46

查看连接字符串,为了将密码保存在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);
Run Code Online (Sandbox Code Playgroud)

以下示例将密码保存在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);
Run Code Online (Sandbox Code Playgroud)

它的一个属性设置在连接字符串本身不在SqlConnection对象中,我把它放在连接字符串的开头只是为了你不必滚动查看它,它可以去连接字符串中的任何地方,我通常看到它在末尾.

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


Joh*_*ica 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;
}
Run Code Online (Sandbox Code Playgroud)

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