2012-09-17 7 views
26

sto usando ADO.NET per ottenere alcune informazioni dal database su un server,
quindi questo è quello che faccio:ConnectionString perde password dopo connection.Open

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(); 

ma dopo aver chiamato Apri metodo ho notato che conn.ConnectionString sta perdendo la password in modo che diventi:

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

che causa eccezione con qualsiasi SqlCommand afterwords
come risolvere questo?
Nota: La cosa strana è che ciò non accada sempre
Edit: Non credo che abbia niente a che fare con il comando è di per sé, ma in ogni caso

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

bene per i principianti hai codice effettivo dopo aver eseguito conn.Open() altrimenti lo si sta aprendo e quindi chiudendolo in base a ciò che si ha nell'esempio sopra .. – MethodMan

+0

conStr non può essere modificato da SqlConnection nel codice che si ho pubblicato. Stai cercando di guardare conn.ConnectionString (o qualche proprietà simile?). –

+0

@insta: Tha è quello che OP ha detto: _ "ho notato che conn.ConnectionString sta perdendo la password" _ –

risposta

42

Ciò è di progettazione, per motivi di sicurezza. Da MSDN:

ConnectionString è simile a una stringa di connessione OLE DB, ma non è identica. A differenza di OLE DB o ADO, la stringa di connessione restituita è uguale a ConnectionString impostata dall'utente, meno le informazioni sulla sicurezza se il valore Persist Security Info è impostato su false (impostazione predefinita). Il provider di dati .NET Framework per SQL Server non mantiene o restituisce la password in una stringa di connessione a meno che non si imposta Persist Security Info su true.

+0

grande ho letto che da qualche parte e non sapevo come usarlo, puoi dirmi come usarlo per favore? perché non vedo ** Persist Security Info ** ovunque grazie – Star

+4

@Star, c'è un esempio nel link che ti ho dato. Basta includere "Persist Security Info = True" nella stringa di connessione. Ma comunque, non dovresti farlo ... se hai bisogno della proprietà ConnectionString per conservare la password, probabilmente non la stai usando correttamente. –

+0

Vedo, quindi hai qualche idea di dove mi sarei perso? e di nuovo davvero grazie :) – Star

30

Guardate nella stringa di connessione, al fine di mantenere la password nella proprietà ConnectionString è necessario aggiungere "Persist Security Info=true;" alla stringa di connessione in sé.

Il seguente esempio eliminerà la password out:

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); 

Il seguente esempio manterrà la password nel 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); 

sua una proprietà ubicata all'interno stringa di connessione stessa non nel SqlConnection oggetto, l'ho messo all'inizio della stringa di connessione solo così non devi scorrere per vederlo, può andare ovunque nella stringa di connessione, di solito lo vedo alla fine.

Come altri hanno già detto, se è necessario eseguire questa operazione probabilmente non si sta utilizzando l'oggetto SqlConnection esattamente come previsto.

4

È possibile aggiungere la propria convalida, ma ciò richiederà un SqlConnection standard (senza protezione permanente) e l'accesso alla proprietà ConnectionOptions privata per recuperare la stringa di connessione.

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; 
} 

Si noti che questo potrebbe interrompersi se MS modifica l'implementazione sottostante, dal momento che stiamo usando la riflessione. Non sto consigliando questo come il modo migliore per farlo, ma è un modo.