I try create method for get the connection string value but without value for password, or show password like * character. I need used it in logging.
I use ConnectionStringBuilder for Oracle, SqlServer.
Anyway, another way -better- to implement it ? Maybe more generic . And what it happens it ProviderName is empty...
public static string GetConnectionStringWithouPassword(this ConnectionStringSettings cs)
{
if (cs == null || string.IsNullOrEmpty(cs.ConnectionString)) return null;
if (cs.ProviderName.ToLower().Equals("Oracle.DataAccess.Client".ToLower()))
{
var builderOra = new Oracle.DataAccess.Client.OracleConnectionStringBuilder(cs.ConnectionString);
return "";
}
if (cs.ProviderName.ToLower().Equals("System.Data.SqlClient".ToLower()))
{
var builderSql = new SqlConnectionStringBuilder(cs.ConnectionString);
return "";
}
return null;
}
//
public static string ObtenerCadenasConexion()
{
var sb = new StringBuilder();
ConnectionStringSettingsCollection settings = ConfigurationManager.ConnectionStrings;
if (settings != null)
{
foreach (ConnectionStringSettings cs in settings)
{
sb.AppendLine("Name: " + cs.Name);
sb.AppendLine("ProviderName: " + cs.ProviderName);
sb.AppendLine("ConnectionString: " + cs.GetConnectionStringWithouPassword() + Environment.NewLine);
}
}
return sb.ToString();
}
check this one: DbConnectionStringBuilder Class
you can use the Remove method, no magic parsing required:
for example, from that MSDN page:
static void Main()
{
DbConnectionStringBuilder builder = new
DbConnectionStringBuilder();
builder.ConnectionString =
#"Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=C:\Demo.mdb;" +
"Jet OLEDB:System Database=system.mdw;";
// Try to remove an existing item.
TryRemove(builder, "Provider");
// Try to remove a nonexistent item.
TryRemove(builder, "User ID");
// Try to remove an existing item,
// demonstrating that the search isn't
// case sensitive.
TryRemove(builder, "DATA SOURCE");
Console.ReadLine();
}
static void TryRemove(DbConnectionStringBuilder builder, string itemToRemove)
{
if (builder.Remove(itemToRemove))
{
Console.WriteLine(#"Removed '{0}'", itemToRemove);
}
else
{
Console.WriteLine(#"Unable to remove '{0}'", itemToRemove);
}
Console.WriteLine(builder.ConnectionString);
}
Check the Connection.PersistSecurityInfo property, you may drop this information as soon as the connection is created automatically.
Related
I am newbie to fix protocol and quick fix programming. I am seeking a help on getting Trade Capture report from ICE. I have googled for the sample/ tutorial to use quick fix/n to get the trade report but I am not being able to get sufficient output of it.
My problem is to get Trade Capture report or deal information for this I tried using TradeCaptureReportRequest, TradeCaptureReportRequestAck, TradeCaptureReport classes but somehow its now working.
A simple how to extract information would be a great help.
thanking everyone out there in advance.
Ok I am posting as an answer because it's going to be way too long for a comment. Please keep in mind that I have written custom constants, message types, etc (I wrote my acceptor server as well, so I'm not restricted by ICE constants/enums). You will need to determine what fields are required by ICE and make changes - this will not be easy to copy/paste...
First, you need to make sure you have all required files in and referenced. I create a folder called "fix" in my project, and copy all fix files into it. These need to be (at least 1) FixXXX.xml file, if you're using FIX50SP1 or 2, you need to also have FIXT11.xml. Along with the .xml files, you need to have an initiator.cfg file (assuming you're making an initiator, no a server, otherwise this will need to be "acceptor.cfg" but again, it sounds like you're trying to connect to ICE, so initiator is the correct usage. Finally, you will need to have a QuickFix.dll. My tree looks as below:
I am not going to go through the XML files - you will need to just learn that - it is very confusing and takes time.. especially if using FIXT11.XML along with SP1 or 2.
Your initiator.cfg should be similar to below:
# default settings for sessions
[DEFAULT]
FileStorePath=store
FileLogPath=log
ConnectionType=initiator
ReconnectInterval=60
SenderCompID=[Enter yours]
ResetOnLogon=Y
ResetOnLogout=Y
ResetOnDisconnect=Y
[SESSION]
BeginString=FIXT.1.1
TargetCompID=[Enter ICE Acceptor]
DefaultApplVerID=FIX.5.0
StartTime=12:30:00
EndTime=21:30:00
# overide default setting for RecconnectInterval
ReconnectInterval=30
HeartBtInt=30
SocketConnectPort=[From ICE]
# (optional) only listen for incoming connections on a specific host
#SocketConnectHost=127.0.0.1
SocketConnectHost=[ICE Ip Address- from your documentation/registration]
DataDictionary=..\..\fix\FIX50.xml
TransportDataDictionary=..\..\fix\FIXT11.xml
Ok, assuming that you have QuickFix.dll imported and referenced, and your initiator.cfg properly connected, it's actually fairly simple:
Create a Class that handles everything. Ignore AddToLB, that is a testing function.
public class TCT_Fix : Control, IApplication
{
private readonly string username = [removed]
private readonly string password = [removed]
public string InitiatorID;
SessionID sessionID;
public bool running;
SessionSettings settings;
IMessageStoreFactory storeFactory;
ILogFactory logFactory;
SocketInitiator initiator;
public event EventHandler AddToLB;
public event EventHandler AddToAdmin;
public void StopIt()
{
if (sessionID == null) return;
try
{
Session.LookupSession(sessionID).Disconnect("Stopping");
settings.Remove(sessionID);
settings = null;
initiator.Dispose();
settings = new SessionSettings(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fix", "initiator.cfg"));
storeFactory = new FileStoreFactory(settings);
logFactory = new FileLogFactory(settings);
initiator = new SocketInitiator(
this,
storeFactory,
settings,
logFactory);
}
catch { }
}
public void FromApp(QuickFix.Message msg, SessionID sessionID)
{
var sMsg = "FROM APP: " + msg.ToString();
AddToLB(sMsg, null);
if (msg.Header.GetField(35) == "TC") //Cash
{
DateTime dtTdate;
float fPrice;
int Qty;
int OrdType;
bool BPisBuyer;
DateTime.TryParse(msg.GetField(CustomConstants.TDATE),out dtTdate);
string BPSide = msg.GetField(CustomConstants.BP_SIDE);
float.TryParse(msg.GetField(CustomConstants.F_PRICE), out fPrice);
int.TryParse(msg.GetField(CustomConstants.QTY), out Qty);
string TCTReference = msg.GetField(CustomConstants.TCT_REF);
string BPAcct = msg.GetField(CustomConstants.BP_COMPANY);
int.TryParse(msg.GetField(CustomConstants.ORDER_TYPE), out OrdType);
string ExecBkr = msg.GetField(CustomConstants.EXEC_BKR);
string CounterParty = msg.GetField(CustomConstants.COUNTER_PARTY);
BPisBuyer = msg.GetField(CustomConstants.IS_BUYER) == "Y";
string BPTrader = msg.GetField(CustomConstants.BP_TRADER);
string CounterTrader = msg.GetField(CustomConstants.COUNTER_TRADER);
string Grade = msg.GetField(CustomConstants.GRADE);
string Location = msg.GetField(CustomConstants.LOCATION);
string CycDt = msg.GetField(CustomConstants.CYCLE_DATE);
string DelMo = msg.GetField(CustomConstants.DELIVER_MONTH);
string Terms = msg.GetField(CustomConstants.TERMS);
string Payment = msg.GetField(CustomConstants.PAYMENT);
string Origin = msg.GetField(CustomConstants.ORIGIN);
string NumOfCyc = msg.GetField(CustomConstants.NUM_OF_CYCLES);
string Via = msg.GetField(CustomConstants.VIA);
string MoveMo = msg.GetField(CustomConstants.MOVE_MONTH);
string Comment = msg.GetField(CustomConstants.COMMENT);
}
else if (msg.Header.GetField(35) == "TE") //EFP
{
DateTime dtTdate;
float fPrice;
int Qty;
int OrdType;
bool BPisBuyer;
bool IsWater;
DateTime.TryParse(msg.GetField(CustomConstants.TDATE), out dtTdate);
string BPSide = msg.GetField(CustomConstants.BP_SIDE);
float.TryParse(msg.GetField(CustomConstants.F_PRICE), out fPrice);
int.TryParse(msg.GetField(CustomConstants.QTY), out Qty);
string TCTReference = msg.GetField(CustomConstants.TCT_REF);
string BPAcct = msg.GetField(CustomConstants.BP_COMPANY);
int.TryParse(msg.GetField(CustomConstants.ORDER_TYPE), out OrdType);
string ExecBkr = msg.GetField(CustomConstants.EXEC_BKR);
string CounterParty = msg.GetField(CustomConstants.COUNTER_PARTY);
BPisBuyer = msg.GetField(CustomConstants.IS_BUYER) == "Y";
string BPTrader = msg.GetField(CustomConstants.BP_TRADER);
string CounterTrader = msg.GetField(CustomConstants.COUNTER_TRADER);
string Grade = msg.GetField(CustomConstants.GRADE);
string Location = msg.GetField(CustomConstants.LOCATION);
string CycDt = msg.GetField(CustomConstants.CYCLE_DATE);
string DelMo = msg.GetField(CustomConstants.DELIVER_MONTH);
string Terms = msg.GetField(CustomConstants.TERMS);
string Payment = msg.GetField(CustomConstants.PAYMENT);
string Origin = msg.GetField(CustomConstants.ORIGIN);
string NumOfCyc = msg.GetField(CustomConstants.NUM_OF_CYCLES);
string Via = msg.GetField(CustomConstants.VIA);
string MoveMo = msg.GetField(CustomConstants.MOVE_MONTH);
string Comment = msg.GetField(CustomConstants.COMMENT);
IsWater = msg.GetField(CustomConstants.ISWATER) == "Y";
string BPFloorBkr = msg.GetField(CustomConstants.BP_FLOOR_BKR);
string CounterFloorBkr = msg.GetField(CustomConstants.COUNTER_FLOOR_BKR);
string Diff = msg.GetField(CustomConstants.DIFFERENCE);
string MercMo = msg.GetField(CustomConstants.MERC_MO);
string MercPr = msg.GetField(CustomConstants.MERC_PRICE);
}
else if (msg.Header.GetField(35) == "TI") //Index
{
DateTime dtTdate;
float fPrice;
int Qty;
int OrdType;
bool BPisBuyer;
bool IsWater;
DateTime.TryParse(msg.GetField(CustomConstants.TDATE), out dtTdate);
string BPSide = msg.GetField(CustomConstants.BP_SIDE);
float.TryParse(msg.GetField(CustomConstants.F_PRICE), out fPrice);
int.TryParse(msg.GetField(CustomConstants.QTY), out Qty);
string TCTReference = msg.GetField(CustomConstants.TCT_REF);
string BPAcct = msg.GetField(CustomConstants.BP_COMPANY);
int.TryParse(msg.GetField(CustomConstants.ORDER_TYPE), out OrdType);
string ExecBkr = msg.GetField(CustomConstants.EXEC_BKR);
string CounterParty = msg.GetField(CustomConstants.COUNTER_PARTY);
BPisBuyer = msg.GetField(CustomConstants.IS_BUYER) == "Y";
string BPTrader = msg.GetField(CustomConstants.BP_TRADER);
string CounterTrader = msg.GetField(CustomConstants.COUNTER_TRADER);
string Grade = msg.GetField(CustomConstants.GRADE);
string Location = msg.GetField(CustomConstants.LOCATION);
string CycDt = msg.GetField(CustomConstants.CYCLE_DATE);
string DelMo = msg.GetField(CustomConstants.DELIVER_MONTH);
string Terms = msg.GetField(CustomConstants.TERMS);
string Payment = msg.GetField(CustomConstants.PAYMENT);
string Origin = msg.GetField(CustomConstants.ORIGIN);
string NumOfCyc = msg.GetField(CustomConstants.NUM_OF_CYCLES);
string Via = msg.GetField(CustomConstants.VIA);
string MoveMo = msg.GetField(CustomConstants.MOVE_MONTH);
string Comment = msg.GetField(CustomConstants.COMMENT);
IsWater = msg.GetField(CustomConstants.ISWATER) == "Y";
string BPFloorBkr = msg.GetField(CustomConstants.BP_FLOOR_BKR);
string CounterFloorBkr = msg.GetField(CustomConstants.COUNTER_FLOOR_BKR);
string Diff = msg.GetField(CustomConstants.DIFFERENCE);
string MercMo = msg.GetField(CustomConstants.MERC_MO);
string MercPr = msg.GetField(CustomConstants.MERC_PRICE);
}
}
public void OnCreate(SessionID sessionID)
{
AddToAdmin("SESSION CREATED: " + sessionID.ToString(), null);
}
public void OnLogout(SessionID sessionID)
{
AddToAdmin("LOGOUT: " + this.sessionID.ToString(), null);
}
public void OnLogon(SessionID sessionID)
{
this.sessionID = sessionID;
AddToAdmin("LOG ON: " + this.sessionID.ToString(),null);
}
public void FromAdmin(QuickFix.Message msg, SessionID sessionID)
{
AddToAdmin("FROM ADMIN: " + msg.ToString(), null);
}
public void ToAdmin(QuickFix.Message msg, SessionID sessionID)
{
if (msg.Header.GetField(35).ToString() == "A")
{
msg.SetField(new QuickFix.Fields.Username(username));
msg.SetField(new QuickFix.Fields.Password(password));
}
AddToAdmin("TO ADMIN: " + msg.ToString(), null);
}
public void ToApp(QuickFix.Message msg, SessionID sessionID)
{
AddToLB("TO APP: " + msg.ToString(), null);
}
public void GetTestMessage(string msgType)
{
if (sessionID == null) return;
QuickFix.FIX50.TestMessage msg = new QuickFix.FIX50.TestMessage();
msg.TestType = msgType;
msg.Header.SetField(new QuickFix.Fields.MsgType("TEST"));
msg.SetField(new QuickFix.Fields.StringField(CustomConstants.TEST_TYPE, msgType));
Session.SendToTarget(msg, sessionID);
}
public TCT_Fix()
{
settings = new SessionSettings(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fix", "initiator.cfg"));
storeFactory = new FileStoreFactory(settings);
logFactory = new FileLogFactory(settings);
initiator = new SocketInitiator(
this,
storeFactory,
settings,
logFactory);
}
public TCT_Fix(ref string initID)
{
InitiatorID = initID;
settings = new SessionSettings(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fix", "initiator.cfg"));
storeFactory = new FileStoreFactory(settings);
logFactory = new FileLogFactory(settings);
initiator = new SocketInitiator(
this,
storeFactory,
settings,
logFactory);
}
public void RunIt()
{
if (running) return;
if(initiator.IsStopped)
{
try
{
initiator.Start(); //This can throw an error due to current set up. I would recommend making the connection,
//pulling data, and then closing the connection (polling) to ensure the initiator clears the
//log files
//reference http://lists.quickfixn.com/pipermail/quickfixn-quickfixn.com/2013q1/000747.html
//2013 issue, still unresolved... Restart app
}
catch(Exception ex)
{
if (MessageBox.Show("Error restarting initiator. Program will close due to file access. This is a Quickfix bug, not an issue with this program. Please restart." + Environment.NewLine + Environment.NewLine +
"Reference: http://lists.quickfixn.com/pipermail/quickfixn-quickfixn.com/2013q1/000747.html for more information. Click ok to copy link to clipboard. Click \"X\" to ignore.") == DialogResult.OK)
{
Clipboard.SetText("http://lists.quickfixn.com/pipermail/quickfixn-quickfixn.com/2013q1/000747.html");
}
throw new Exception(ex.ToString());
}
}
running = true;
}
}
Finally, to make it stand out (this is actually in the block above as well), you construct a message similar to below, keeping in mind that your ICE Message will have certain required fields that my "TestMessage" does not. I cannot give code from production though - sorry.
public void GetTestMessage(string msgType)
{
if (sessionID == null) return;
QuickFix.FIX50.TestMessage msg = new QuickFix.FIX50.TestMessage();
msg.TestType = msgType;
msg.Header.SetField(new QuickFix.Fields.MsgType("TEST"));
msg.SetField(new QuickFix.Fields.StringField(CustomConstants.TEST_TYPE, msgType));
Session.SendToTarget(msg, sessionID);
}
The learning curve is substantial. You will just need to keep playing around until you get it. Once you get it down though, it makes sense. Stick with it. Let me know if you need anything else.
I am using C# 4.0. (Winform Application)
I have a code like this:
private bool ChangeEFConnectionString(string connStringName, string newValue)
{
try
{
//CreateXDocument and load configuration file
XDocument doc = XDocument.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
//Find all connection strings
var query1 = from p in doc.Descendants("connectionStrings").Descendants()
select p;
//Go throught each connection string elements find atribute specified by argument and replace its value with newVAlue
foreach (var child in query1)
{
foreach (var atr in child.Attributes())
{
if (atr.Name.LocalName == "name" && atr.Value == connStringName)
if (atr.NextAttribute != null && atr.NextAttribute.Name == "connectionString")
{
// Create the EF connection string from existing
EntityConnectionStringBuilder entityBuilder =
new EntityConnectionStringBuilder(atr.NextAttribute.Value);
//change hte provide conn string
entityBuilder.ProviderConnectionString = newValue;
//back the full connection string to the configuration fiel
atr.NextAttribute.Value = entityBuilder.ToString();
}
}
}
doc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
It works well, but somehow it not work any more.
As I debug it : entityBuilder.ProviderConnectionString = newValue; had the right value
but it still not change the connectionstring.
Use ConfigurationManager for reading and updating connection strings:
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings[connStringName].ConnectionString = newValue;
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("connectionStrings");
I think all you need is, after the Save, a:
ConfigurationManager.RefreshSection("connectionStrings");
Have you considered giving EF the whole connection string instead of the name? That would keep you from having to modify what the name means at run time.
I am new to MySQL database, I am using Visual Studio C# to connect to my database. I have got a following select method. How can I run it to check if it is working?
EDITED The open and close connection methods
//Open connection to database
private bool OpenConnection()
{
try
{
// connection.open();
return true;
}
catch (MySqlException ex)
{
//When handling errors, your application's response based
//on the error number.
//The two most common error numbers when connecting are as follows:
//0: Cannot connect to server.
//1045: Invalid user name and/or password.
switch (ex.Number)
{
case 0:
MessageBox.Show("Cannot connect to server.");
break;
case 1045:
MessageBox.Show("Invalid username/password, please try again");
break;
}
return false;
}
}
//Close connection
private bool CloseConnection()
{
try
{
connection.Close();
return true;
}
catch (MySqlException ex)
{
MessageBox.Show(ex.Message);
return false;
}
}
Select method which is in the same class as the close and open connection as shown above
public List<string>[] Select()
{
string query = "SELECT * FROM Questions";
//Create a list to store the result
List<string>[] list = new List<string>[3];
list[0] = new List<string>();
list[1] = new List<string>();
list[2] = new List<string>();
list[3] = new List<string>();
list[4] = new List<string>();
list[5] = new List<string>();
list[6] = new List<string>();
list[7] = new List<string>();
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data and store them in the list
while (dataReader.Read())
{
list[0].Add(dataReader["id"] + "");
list[1].Add(dataReader["difficulty"] + "");
list[2].Add(dataReader["qustions"] + "");
list[3].Add(dataReader["c_answer"] + "");
list[4].Add(dataReader["choiceA"] + "");
list[5].Add(dataReader["choiceB"] + "");
list[6].Add(dataReader["choiceC"] + "");
list[7].Add(dataReader["choiceD"] + "");
}
//close Data Reader
dataReader.Close();
//close Connection
this.CloseConnection();
//return list to be displayed
return list;
}
else
{
return list;
}
}
This method is in a separate class which has got all the database connection settings. Now that I want to call this method from my main class to test it to see if it's working, how can I do this?
You should create an object instance of that DB class and then call the Select() method.
So, supposing that this DB class is named QuestionsDB you should write something like this:
QuestionDB questionDAL = new QuestionDB();
List<string>[] questions = questionDAL.Select();
However, before this, please correct this line
List<string>[] list = new List<string>[8]; // you need 8 lists for your db query
You could check if you have any record testing if the first list in your array list has more than zero elements.
if(questions[0].Count > 0)
... // you have read records.
However, said that, I will change your code adding a specific class for questions and using a list(of Question) instead of an array of list
So, for example, create a class like this
public class Question
{
public string ID;
public string Difficulty;
public string Question;
public string RightAnswer;
public string AnswerA;
public string AnswerB;
public string AnswerC;
public string AnswerD;
}
and change your select to return a List(of Question)
List<Question> list = new List<Question>;
......
while (dataReader.Read())
{
Question qst = new Question();
qst.ID = dataReader["id"] + "";
qst.Difficulty = dataReader["difficulty"] + "";
qst.Question = dataReader["qustions"] + "";
qst.RightAnswer = dataReader["c_answer"] + "";
qst.AnswerA = dataReader["choiceA"] + "";
qst.AnswerB = dataReader["choiceB"] + "";
qst.AnswerC = dataReader["choiceC"] + "";
qst.AnswerD = dataReader["choiceD"] + "";
list.Add(qst);
}
return list;
You can test whether the method works by writing a unit test for it. A good unit testing frame work is Nunit. Before you call this you must create and open a connection to the DB:
//Open connection
if (this.OpenConnection() == true)
{
as the other person said, you will want to fix the lists up.
I want to get a ConnectionString from an instance of SqlConnectionStringBuilder as a String.
This seems simple, and should be as easy as this:
String conString = builder.ConnectionString;
However the String that SqlConnectionStringBuilder gives up doesn't include the Password field/value. I'm guessing this is some sort of security feature, is there a way to force Password to be included in the String?
Looking at this further I'm thinking this may have something to do with ConnectionManager. What I am trying to do is modify the ConnectionString for a Package, changing the Initial Catalog.
Below is my code, the point that builder's connection string is passed back into connectionManager's the Password is lost...
public void DataTransfer(String sourceConnection, String destConnection, String pkgLocation)
{
Package pkg;
Application app;
DTSExecResult pkgResults;
try
{
app = new Application();
pkg = app.LoadPackage(pkgLocation, null);
foreach (ConnectionManager connectionManager in pkg.Connections)
{
SqlConnectionStringBuilder builder;
switch (connectionManager.Name)
{
case "SourceConnection":
builder = new SqlConnectionStringBuilder(sourceConnection) { PersistSecurityInfo = true };
builder.Remove("Initial Catalog");
builder.Add("Initial Catalog", "StagingArea");
connectionManager.ConnectionString = builder.ConnectionString.ToString();
connectionManager.ConnectionString += ";Provider=SQLNCLI;Auto Translate=false;";
Debug.WriteLine(connectionManager.ConnectionString.ToString());
break;
case "DestinationConnection":
builder = new SqlConnectionStringBuilder(sourceConnection) { PersistSecurityInfo = true };
builder.Remove("Initial Catalog");
builder.Add("Initial Catalog", "StagingArea");
connectionManager.ConnectionString = builder.ConnectionString.ToString();
connectionManager.ConnectionString += ";Provider=SQLNCLI;Auto Translate=false;";
Debug.WriteLine(connectionManager.ConnectionString.ToString());
break;
}
}
pkgResults = pkg.Execute();
}
catch (Exception e)
{
throw;
}
Console.WriteLine(pkgResults.ToString());
}
Set PersistSecurityInfo to True before setting other properties in the SqlConnectionStringBuilder : D
I need to rename this a little maybe, as the question is different now, but here is my solution:
The first part of this question was answered correctly by #madd0. The ConnectionString does contain the Password field.
The second part was solved with formatting code is below:
public void DataTransfer(String sourceConnection, String destConnection, String pkgLocation)
{
Package pkg;
Application app;
DTSExecResult pkgResults;
try
{
app = new Application();
pkg = app.LoadPackage(pkgLocation, null);
foreach (ConnectionManager connectionManager in pkg.Connections)
{
SqlConnectionStringBuilder builder;
switch (connectionManager.Name)
{
case "SourceConnection":
builder = new SqlConnectionStringBuilder(sourceConnection) { PersistSecurityInfo = true };
builder.Remove("Initial Catalog");
builder.Add("Initial Catalog", "StagingArea");
var sourceCon = builder.ConnectionString + ";Provider=SQLNCLI;Auto Translate=false;";
//Added spaces to retain password!!!
sourceCon = sourceCon.Replace(";", "; ");
connectionManager.ConnectionString = sourceCon;
Debug.WriteLine(connectionManager.ConnectionString.ToString());
break;
case "DestinationConnection":
builder = new SqlConnectionStringBuilder(sourceConnection) { PersistSecurityInfo = true };
builder.Remove("Initial Catalog");
builder.Add("Initial Catalog", "StagingArea");
var destCon = builder.ConnectionString + ";Provider=SQLNCLI;Auto Translate=false;";
//Added spaces to retain password!!!
destCon = destCon.Replace(";", "; ");
connectionManager.ConnectionString = destCon;
Debug.WriteLine(connectionManager.ConnectionString.ToString());
break;
}
}
pkgResults = pkg.Execute();
}
catch (Exception e)
{
throw;
}
Console.WriteLine(pkgResults.ToString());
}
I played about with the ConnectionStrings and noticed after a while that the original String had spaces between each property.
Running 2 tests I found that without spaces the Password was lost...
connectionManager.ConnectionString = destCon;
Test 1: No Spaces:
When destCon = Data Source=xxx.xxx.xxx.xxx;Initial Catalog=StagingArea;User ID=*****;Password=*****;Provider=SQLNCLI;Auto Translate=false;
Then connectionManager.ConnectionString = Data Source=xxx.xxx.xxx.xxx;User ID=*****;Initial Catalog=StagingArea;Provider=SQLNCLI;Auto Translate=false;
Test 2: Spaces:
When destCon = Data Source=xxx.xxx.xxx.xxx; Initial Catalog=StagingArea; User ID=*****; Password=*****; Provider=SQLNCLI; Auto Translate=false;
Then connectionManager.ConnectionString = Data Source=xxx.xxx.xxx.xxx; Initial Catalog=StagingArea; User ID=*****; Password=*****; Provider=SQLNCLI; Auto Translate=false;
No idea why this happens, but without spaces the ordering is adjusted and the Password field is lost.
How can I get the user and password from such a connectionString in the app.config with a .NET function?
Of course I could read that string and get the value after the ID= and Password=.
<connectionStrings>
<add name="MyConString" connectionString="Data Source=(local);Initial Catalog=MyDatabase;Persist Security Info=True;User ID=MyUsername Password=MyPassword;Connect providerName="System.Data.SqlClient"/>
</connectionStrings>
use the ConnectionBuilderClass
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder("Your connection string");
string password = builder.Password;
together with the
string connString = ConfigurationManager.ConnectionStrings["MyConString"].ConnectionString;
to achieve this.
If you need a more generic approach for parsing the connection string (one that doesn't deal with the specifics of one database provider) you can also use
System.Data.Common.DbConnectionStringBuilder
which is a base class for other classes like SqlConnectionStringBuilder etc.
You can create an instance of DbConnectionStringBuilder and in my case I needed to have one configurable connection string that I could get information from -- regardless of the database provider type. A few options if you need this flexibility -- you could create the appropriate ConnectionStringBuilder for your provider as others have suggested -- this would likely be required for most cases where provider-specific properties are needed.
Or if you want to read just a couple generic properties, you could use DbConnectionStringBuilder if you just need the user id and password for example.
This sample should work for ANY connection string that includes user id and password.
DbConnectionStringBuilder db = new DbConnectionStringBuilder();
db.ConnectionString = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
var username = db["User Id"].ToString();
var password = db["Password"].ToString();
SqlConnectionStringBuilder con = new SqlConnectionStringBuilder(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
string myUser = con.UserID;
string myPass = con.Password;
var builder = new SqlConnectionStringBuilder(ConfigurationManager.ConnectionStrings["MyConString"].ConnectionString)
var user = builder.UserID;
var password = builder.Password;
You can get the connection string from the following
SqlConnectionStringBuilder yourconn = new SqlConnectionStringBuilder(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
string password = yourconn.Password;
You can then get the substring you are looking for .
Just to add a bit to Tomas Walek's answer.
This approach would work only if "User ID" in the connection string is capitalized correctly. Oracle provider accepted "User Id" OK, but SqlConnectionStringBuilder did not work.
public static class DbConnectionFactory
{
public static ConnectionStringSettings AppConnectionSettings = ConfigurationManager.ConnectionStrings["{A connection string name}"];
public static SqlConnectionStringBuilder AppConnBuilder = new SqlConnectionStringBuilder(AppConnectionSettings.ConnectionString);
public static string DbUserID
{
get
{
return AppConnBuilder.UserID;
}
set { }
}
}
add a reference to System.Configuration and then use:
using System.Configuration;
string MyDBConnection = ConfigurationManager.ConnectionStrings["MyDBConnection"].ConnectionString;
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(MyDBConnection);
string UserID = builder.UserID;
string Password = builder.Password;
string ServerName = builder.DataSource;
string DatabaseName = builder.InitialCatalog;
public static string GetConnectionSettings(string searchSetting )
{
var con = ConfigurationManager.ConnectionStrings["yourConnectionHere"].ConnectionString;
String[] myString = con.Split(';');
Dictionary<string, string> dict = new Dictionary<string, string>();
for (int i = 0; i < myString.Count(); i++)
{
String[] con3 = myString[i].Split('='); dict.Add(con3[0], con3[1]);
}
return dict[searchSetting];
}
for searchSetting you can use what you want "User Is" or password.
another way is to use regular expression (which I did), with a more forgiving pattern, to handle different ways a user id could be provided on the connection string:
public static string GetUserIdFromConnectionString(string connectionString)
{
return new Regex("USER\\s+ID\\=\\s*?(?<UserId>\\w+)",
RegexOptions.IgnoreCase)
.Match(connectionString)
.Groups["UserId"]
?.Value;
}
Extension method to get "User Id" from connectionString in DbConnection:
using System;
using System.Data.Common;
using System.Text.RegularExpressions;
namespace DemoProject.Helpers
{
public static class DbConnectionExtensions
{
public static string GetUserId(this DbConnection connection)
{
const string userIdPattern1 = "User[ ]*Id";
const string userIdPattern2 = "UID";
var connectionString = connection.ConnectionString;
foreach (var item in connectionString.Split(';'))
{
var index = item.IndexOf('=');
if (index == -1)
continue;
var property = item.Substring(0, index).Trim();
if (Regex.IsMatch(property, userIdPattern1, RegexOptions.IgnoreCase) ||
Regex.IsMatch(property, userIdPattern2, RegexOptions.IgnoreCase))
{
var userId = item.Substring(index + 1).Trim();
return userId;
}
}
throw new Exception("Couldn't find \"User Id\" in connectionString");
}
}
}
Example #1 of using:
using DemoProject.Helpers;
using Oracle.ManagedDataAccess.Client;
namespace DemoProject
{
class Program
{
static void Main(string[] args)
{
const string connectionString = "Data Source=(DESCRIPTION=" +
"(ADDRESS=(PROTOCOL=TCP)(HOST=oracle19c-vm)(PORT=1521))" +
"(CONNECT_DATA=(SERVICE_NAME=ORCLPDB1)));" +
"User Id=JOHN;" +
"Password=pwd123";
var connection = new OracleConnection(connectionString);
var userId = connection.GetUserId();
}
}
}
Example #2 of using:
using DemoProject.Helpers;
using Npgsql;
namespace DemoProject
{
class Program
{
static void Main(string[] args)
{
const string connectionString = "Server=postgre-vm;" +
"User Id=JOHN;" +
"Password=pwd123;" +
"Database=DEV1";
var connection = new NpgsqlConnection(connectionString);
var userId = connection.GetUserId();
}
}
}
Also you can add the 2nd extension method to get the password
var connString = ConfigurationManager.ConnectionStrings["MyConString"].ConnectionString;
var tokens = connString.Split(';');
string userId;
string password;
for(var i = 0; i < tokens.Length; i++) {
var token = tokens[i];
if(token.StartsWith("User ID"))
userId = token.Substring(token.IndexOf("=") + 1);
if(token.StartsWith("Password"))
password = token.Substring(token.IndexOf("=") + 1);
}
string connectionString = ConfigurationManager.ConnectionStrings["MyConString"].ConnectionString;
var tokens = connectionString.Split(';').Select(n => n.Split('=');
string userId = tokens.First(n => n[0].Equals("User ID").Select(n => n[1]);
string password = tokens.First(n => n[0].Equals("Password").Select(n => n[1]);