C# ConnectionString在连接后丢失密码。打开

C# ConnectionString在连接后丢失密码。打开,c#,ado.net,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(); 但是调用Open方法后,我

我正在使用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();

这是出于安全考虑而设计的。发件人:

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


查看连接字符串,为了将密码保留在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对象。

您可能希望添加自己的验证,但这将采用标准的SqlConnection(无持久安全性)并访问private 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更改底层实现,这可能会中断,因为我们使用的是反射。我并不建议这样做,但这是一种方法。

对于初学者来说,在执行conn.Open()之后是否有实际的代码,否则您将根据上面示例中的内容打开它,然后关闭它。.在您发布的代码中,SqlConnection无法修改conStr。你是想看看conn.ConnectionString(或类似的属性?)@insta:OP是这么说的:“我注意到conn.ConnectionString正在丢失密码”出于安全原因SqlConnection会删除密码是不合理的吗?@Star:那么我必须同意DJ_KRAZE的说法,那是毫无意义的。为什么要使用只返回当前时间(以db为单位)的查询<代码>日期时间。现在会更有效率。太好了,我在某个地方读过,不知道如何使用它,你能告诉我如何使用它吗?因为我在任何地方都看不到持久性安全信息thanks@Star,我给你的链接中有一个例子。只需在连接字符串中包含“Persist Security Info=True”。但无论如何,你不应该这么做。。。如果您需要ConnectionString属性来保留密码,您可能没有正确使用它。我明白了,那么您知道我可能错过了什么吗?再次非常感谢:)@Star,我的猜测是您在关闭SqlConnection后重新使用它;你应该创建一个新的。这是我在没有看到更多代码的情况下所能做的最好的事情…默默地删除连接字符串的一部分。默认情况下!只有在它第一次被使用之后。。。这是一种确保开发人员浪费时间调试奇怪问题的好方法。像代码一样,任意抛出
SqlException:用户登录失败…
,因为您在错误的时间检查了连接字符串。这是一种奇怪的安全保护方式。他们至少可以让它抛出一个异常,而不是返回虚假数据!