When trying to read a .dbf file with the Control Panel -> Region -> Administrative -> Region Settings = "English (UK)" system settings, Russian characters are read in an unknown encoding. But if this option is switched Region Settings = "Russian (Russia)", then the characters are read correctly. The options I tried are:
Modified connection options with a private constant string SOURCE_CONNECTION_STRING = "Provider = Microsoft.Jet.OLEDB.4.0; Advanced properties = dBASE; Data source = {0};"; to a private constant string SOURCE_CONNECTION_STRING = "Provider = Microsoft.Jet.OLEDB.4.0; Advanced properties = 'dBASE IV; character set = 1251; HDR = Yes; FMT = delimited"; Data Source = {0}; ";, but it did not help.
Use solution method:
private string Decode(string input)
{
Encoding fromEncoding = Encoding.GetEncoding("cp850");
Encoding toEncoding = Encoding.GetEncoding(866);
string returnValue = toEncoding.GetString(fromEncoding.GetBytes(input));
return returnValue;
}
Method 2, using explicit decoding, helped me. I would like to know if I can somehow set the encoding I expect explicitly in the settings of the "OleDbConnection" class or in some other way?
Here is an example of a received line from a .dbf file - ÇóÔ«¡«¼¡Ù®
«¬ÓÒú.
DBF File
Class Example:
class DbfReader
{
private const string COUNT_ATTRIBUTE_NAME = "count";
private const string ROW_ELEMENT_NAME = "r";
private const string MappedTableName = "SOCRBASE";
private const string SOURCE_CONNECTION_STRING = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Extended Properties='dBASE IV;characterset=1251;HDR=Yes;FMT=Delimited'; " +
"Data Source={0};";
private static readonly string TableName = "socrbase";
private static readonly string GetCountQuery = $"select count(1) from [{TableName}]";
private static readonly List<string> Columns = new List<string> { "level", "scname", "socrname", "kod_t_st" };
private static string SelectQuery => $"select [level], [scname], [socrname], [kod_t_st] from [{TableName}]";
public void Convert(string dataSourceFolder)
{
using (var srcConn = new OleDbConnection(string.Format(SOURCE_CONNECTION_STRING, dataSourceFolder)))
{
srcConn.Open();
Exception exception = null;
try
{
var xmlFilePath = GetTableFileName(dataSourceFolder, TableName);
Directory.CreateDirectory(Path.GetDirectoryName(xmlFilePath));
var xml = new XmlTextWriter(xmlFilePath, Encoding.UTF8);
xml.WriteStartDocument();
var reader = new OleDbCommand(SelectQuery, srcConn).ExecuteReader();
xml.WriteStartElement(MappedTableName);
xml.WriteAttributeString(COUNT_ATTRIBUTE_NAME, ((int)new OleDbCommand(GetCountQuery, srcConn).ExecuteScalar()).ToString());
while (reader.Read())
{
xml.WriteStartElement(ROW_ELEMENT_NAME);
foreach (var column in Columns)
{
xml.WriteStartElement(column);
var value = reader[column].ToString();
var decodeValue = Decode(value);
xml.WriteCData(value);
xml.WriteEndElement();
}
xml.WriteEndElement();
}
xml.WriteEndElement();
xml.WriteEndDocument();
xml.Close();
Console.WriteLine("XML has been created");
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
private string Decode(string input)
{
Encoding fromEncoding = Encoding.GetEncoding("cp850");
Encoding toEncoding = Encoding.GetEncoding(866);
string returnValue = toEncoding.GetString(fromEncoding.GetBytes(input));
return returnValue;
}
private string GetTableFileName(string dataSourceFolder, string tableName)
{
return Path.Combine(dataSourceFolder, "xml", $"{tableName}.xml");
}
}
Related
Below is my Connectionstring and sucessfully read the data. It will return total rows of my data.
private static async Task<List<OperatorErrorTransaction>> GetDevIndex()
{
try
{
var currentConnectionDev = new CurrentConnection(Configuration["ConnectionStrings:Default"], currentRequest);
Console.WriteLine("\nPress the Enter key to exit the application...\n");
var response = await currentConnectionDev.DbConnection.QuerySafeAsync<OperatorErrorTransaction>(GenerateGetDatabaseIndexQuery());
return response.ToList();
}
catch (Exception ex)
{
return new List<OperatorErrorTransaction>();
}
}
private static string GenerateGetDatabaseIndexQuery()
{
return #"SELECT * FROM test.operator_error_transaction";
}
Below is the csv CreateFile function. Right now i looking a way how to implement mysql data into the csv file.
public static void CreateFile(List<OperatorErrorTransaction> result)
{
string myFileName = String.Format("{0:yyyy-MM-dd-HHmm}{1}", DateTime.Now, ".csv");
string myFullPath = Path.Combine("D:\\", myFileName);
using (var mem = new MemoryStream())
using (StreamWriter writer = File.CreateText(myFullPath))
using (var csvWriter = new CsvWriter(writer))
{
csvWriter.Configuration.Delimiter = ";";
csvWriter.WriteField(result);
csvWriter.NextRecord();
writer.Flush();
var result1 = Encoding.UTF8.GetString(mem.ToArray());
Console.WriteLine(result1);
}
}
I have created a class for the variables as well such as public string BetId { get; set; } etc...
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'm writing a RTSP client module and for this, I need to parse an very variable URI. But I'm completely stuck about which method I should use (most-failsafe) and how to accomplish this.
An example URI could look like this:
rtsp://192.168.1.100:554/videocam/media/1/video/1
\_/ \_______________/\_______/\______________/
| | | |
scheme authority [sub] [mediacontrol]
But also other possibilities:
192.168.1.100/videocam/media/1/video/1
192.168.1.100:6000/media/1/video/1
192.168.1.100:6000/videocam
I need the following information:
IP | how can I recognise this pattern [num].[num].[num].[num]?
Port | easy if the string contains rtsp://, but what about just a number? 1-65555
Sub | Optional subpath, can completely vary!
MediaLevel | Optional MediaLevel (indicator for stream/track),
not to be confused with the path. MediaLevel can be also just like this: track1 or m1s3 or media1/video1.. see?
I can't go for the slash, also the path also can contain multiple slashes
Maybe there's a library for such tasks?
Thank you.
var uri = new Uri("rtsp://192.168.1.100:554/videocam/media/1/video/1");
var host = uri.Host;
var port = uri.Port;
var sub = uri.Segments[1];
var mlevel = uri.Segments.Skip(2).ToArray();
Here is a quick example of how to use the UriBuilder class. It is a bit verbose because it is an example and is not ready for production. If more subs are to be identified then they can be added to the Sub List as shown in the example.
class Program
{
private static string _scheme = string.Empty;
private static string _host = string.Empty;
private static string _sub = string.Empty;
static void Main(string[] args)
{
ParseUri("rtsp://192.168.1.100:554/videocam/media/1/video/1");
ParseUri("192.168.1.100/videocam/media/1/video/1");
ParseUri("192.168.1.100:6000/media/1/video/1");
ParseUri("192.168.1.100:6000/videocam");
// example of adding a new sub
Sub.Add("sample");
ParseUri("192.168.1.100:6000/sample/");
Console.ReadLine();
}
private static void ParseUri(string URI)
{
UriBuilder uri = new UriBuilder(URI);
_scheme = uri.Scheme;
_host = uri.Host;
_sub = string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string s in uri.Uri.Segments)
{
if (Sub.Contains(s.Replace("/","")))
{_sub = s;}
else
{ sb.Append(s); }
}
Console.Out.WriteLine("+++++++++++++");
Console.Out.WriteLine("URI: {0}",URI);
Console.Out.WriteLine("Scheme: {0}", _scheme);
Console.Out.WriteLine("sub: {0}",_sub);
Console.Out.WriteLine("mediaControl: {0}", sb.ToString());
}
private static List<string> Sub
{
get
{
List<string> sub = new List<string>();
sub.Add("videocam");
return sub;
}
}
}
trace("Url : {0}", turl.Text);
var uri = new Uri(turl.Text);
string host = uri.Host;
int port = uri.Port;
string userInfo = uri.UserInfo;
string subStream = "";
string userName = "";
string password = "";
if (uri.Segments?.Any() == true)
{
subStream = string.Join("", uri.Segments);
}
if (!string.IsNullOrEmpty(userInfo))
{
if (userInfo.Contains(":"))
{
string[] data = userInfo.Split(':');
userName = data[0];
password = data[1];
}
else
{
userName = userInfo;
}
}
trace("host : {0}", host);
trace("port : {0}", port);
trace("userName : {0}", userName);
trace("password : {0}", password);
trace("subStream: {0}", subStream);
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.
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]);