This is my syntax, but it is not being passed to my connection string, it is being omitted, which of course is causing an error as the database doesn't exist. Is it possible to do this?
namespace bottomsup
{
class onetwothree
{
private static string databaseName = null;
private static string ServerConnectionString = "Data Source=BradJohnson;Initial Catalog=" + databaseName + "DB;User ID = pmartin;Integrated Security=True;MultipleActiveResultSets=True"";
Form1()
{
InitializeComponents();
}
private void ConnectToServerClick()
{
databaseName = textbox1.Text;
using (SqlConnection connection = new SqlConnection(ServerConnectionString))
{
connection.Open();
//more stuff
}
}
}
}
No, if you change the value of databaseName later on, it doesn't automatically change the value of ServerConnectionString.
You have to set the value of ServerConnectionString again yourself.
ServerConnectionString =
string.Format("Data Source=BradJohnson;Initial Catalog={0}DB;User ID = pmartin;Integrated Security=True;MultipleActiveResultSets=True", textbox1.Text);
I'd avoid the static variable, as it can lead to bugs if you try to reuse it, and especially if you overwrite it, in multiple places. One place sets it, then another, and now one or the other is going to grab an incorrect value when it tries to retrieve it.
Perhaps something like this instead, where you always have to pass the database name in:
private static string GetServerConnectionString(string databaseName)
{
return string.Format("Data Source=BradJohnson;Initial Catalog={0}DB;User ID = pmartin;Integrated Security=True;MultipleActiveResultSets=True", databaseName);
}
To use it with your existing code:
using (var connection = new SqlConnection(GetServerConnectionString(textbox1.Text)))
{
connection.Open();
//more stuff
}
I doubt if statics are justified in this case.
Nevertheless, it will not work with variable ServerConnectionString, but you could use a property instead:
private static string ServerConnectionString
{
get
{
return "Data Source=BradJohnson;Initial Catalog=" + databaseName +
"DB;User ID = pmartin;Integrated Security=True;MultipleActiveResultSets=True";
}
}
Often when you try to add a null value to something which has a value, it will fall over. In the DB Name you should use String.Empty as opposed to null.
Also I think you have an extra quote on the end of the string.
When you set the connection string, it is not going to dynamically update if you ever change the other property anyway.
Related
I am getting one High veracode scan issue in the below code. What changes do i need to make to resolve it.
private OleDbConnection importFileConnection;
private OleDbConnection ImportFileConnection
{
get
{
if (importFileConnection == null)
{ importFileConnection = new OleDbConnection(this.ConnectionString);
//getting scan issue in this line. }
//importFileConnection.Open();
return importFileConnection;
}
}
private string ConnectionString
{
get { return string.Format(ImportExportData.Default.ConnectionString, this.ServerFileName); }
}
String.format is the issue. declare connection with out connection string, then mention the connection property.
I'm working on a method that is static, and returns a value off a WinForm, it spawns the new form on a button click, and upon hitting the submit or cancel buttons it throws back its value.
The issue is, I cant refer to a combobox control on my form to populate it with the results of my sqlreader.
I have read suggestions that I use a wrapper that looks akin to
public ComboBox comboHolder { get return this.foo }
however I can't seem to refer to it either. Any suggestions to remedy this ?
Full code
public ComboBox comboboxWrapper
{
get { return this.comboUsernames; }
}
public static string SelectProfile()
{
Form selectProfile = new Select_Profile();
selectProfile.ShowDialog();
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Users.mdf;Integrated Security=True;Connect Timeout=30");
connection.Open();
SqlCommand command = new SqlCommand("SelectAllUsers", connection);
SqlDataReader usersReader = command.ExecuteReader();
List<string> accountNames = new List<string>();
while (usersReader.Read())
{
accountNames.Add((string)usersReader["Username"]);
}
//populate the combo box
foreach (string s in accountNames)
{
//I'd like to call comboboxWrapper here.
}
//set the combo box to have a default item
// combo.SelectedIndex = 0;
}
Also, this is a work in progress, I realize I should have some try, catch and a finally statement, other than that i'm open to any suggestions for code improvement.
Thanks!
I would suggest just not making the method static. But if you really need to for some reason, you could pass a reference to the form into your static method, e.g.:
SelectProfile(Form myForm)
Then you would be able to use it inside the method like this:
foreach (string s in accountNames)
{
// e.g myForm.comboboxWrapper
}
your static method need object of class for that you have to pass object of class where comboboxwrapper defined
public static string SelectProfile(ClassobjectofCoboboxWrapper obj)
{
obj.comboboxWrapper;
}
Call to this method from outside
SelectProfile(new ClassobjectofCoboboxWrapper())
Note:
As static method are not related to instace of object its related to class. So to refer element in static method which are not static you either need to create object of refering class or you need to pass object of class your want to refer.
This is your form instance:
Form selectProfile = new Select_Profile();
So you'd call comboboxWrapper on that instance:
selectProfile.comboboxWrapper
Though first you'll need to change its type, since Form doesn't have a member called comboboxWrapper. Declare it like this instead:
Select_Profile selectProfile = new Select_Profile();
or simply:
var selectProfile = new Select_Profile();
Even though the comboboxWrapper member is defined outside the static method, it's inside the form instance. A static member has no default notion of a particular instance and needs to be provided with one. Or, in this case, internally creates one.
First, decompose your solution: just don't cram database and UI into single method. Next think over what your method is supposed to return as a String:
public static IEnumerable<String> AccountNames() {
//TODO: Move it into Settings/Config...
String connectionString = #"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Users.mdf;Integrated Security=True;Connect Timeout=30";
// Dispose (via using) all Disposable...
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
// Dispose: prevent resource leakage...
using (SqlCommand command = new SqlCommand("SelectAllUsers", connection)) {
using (SqlDataReader usersReader = command.ExecuteReader()) {
while (usersReader.Read())
yield return (string)usersReader["Username"];
}
}
}
}
// returns selected profile
// or null if no profile was seelcted
public static string SelectProfile() {
// var: You need Select_Profile, not just a Form, right?
// again (using): don't forget to clear up the resources
using (var selectProfile = new Select_Profile()) {
// Providing that comboboxWrapper is public (bad practice)
// or SelectProfile() is implemented within Select_Profile class (good one)
selectProfile.comboboxWrapper.Items.AddRange(AccountNames());
if (selectProfile.comboboxWrapper.Items.Count > 0)
selectProfile.comboboxWrapper.SelectedIndex = 0;
if (selectProfile.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
if (selectProfile.comboboxWrapper.SelectedIndex < 0)
return null; // No item to select
else
selectProfile.comboboxWrapper.SelectedItem.ToString();
}
else
return null; // Just closed
}
}
How can I set the value of connectionTimeout (not commandTimeout) of context by coding (not in connection string) ?
This is readonly:
DbContext.Database.Connection.ConnectionTimeout = 10;
Thanks
Udpate:
My probleme is to test if my context is available quickly and the default time is to long ?
I tried this :
int? oldTimeOut = RepositoryDbContext.Database.CommandTimeout;
try
{
RepositoryDbContext.Database.Connection.ConnectionTimeout = 10; //readonly
RepositoryDbContext.Database.CommandTimeout = 10; // doesn't work, the value stay the same
RepositoryDbContext.Database.Connection.Open();
RepositoryDbContext.Database.Connection.Close();
return true;
}
catch
{
return false;
}
finally
{
RepositoryDbContext.Database.CommandTimeout = oldTimeOut;
}
But I can't change the connectionTimeout is readOnly and the commandTimeout doesn't set the value...
I'm not aware of any option to change the connection timeout via the EF API. You can however change the connection string at runtime. You could parse the configured connection string and change the timeout parameter, or add one if it does not exist.
If you are working with SQL Server only, I would suggest using SqlConnectionStringBuilder. Use the constructor that takes an existing connection string, change the ConnectTimeout, get the modified connection string, and use that connection string when constructing your DbContext.
Depending on what you are actually trying to solve, one alternative might be to use SlowCheetah to easily generate the web.config, with different configuration strings, for different build types.
http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5
UPDATE
Based on your comment...
Try something like
string normalConnectionString = RepositoryDbContext.Database.Connection.ConnectionString;
var connectionBuilder = new SqlConnectionStringBuilder(normalConnectionString);
connectionBuilder.ConnectTimeout = 10;
string testConnectionString = connectionBuilder.ConnectionString;
using (var testRepositoryDbContext = new RepositoryDbContextType(testConnectionString))
{
try
{
testRepositoryDbContext.Database.Connection.Open();
testRepositoryDbContext.Database.Connection.Close();
return true;
}
catch
{
return false;
}
}
Like the title. How can I do it?
I tried something, but it doesn't work like I was expecting.
I'm using an Entity Framework model. I need to pass my connection string like parameter, so, in another file, I've written
namespace MyNamespace.Model
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class MyEntities: DbContext
{
public MyEntities(string nameOrConnectionString) : base(nameOrConnectionString)
{
}
}
}
When I startup the app, I call this constructor in this way, so I can refer to this from anyway in the app:
public static MyEntities dbContext = new MyEntities(mdlImpostazioni.SetConnectionString());
where mdlImpostazioni.SetConnectionString() returns a string (the data are correct):
server=192.168.1.100\SVILUPPO;database=MyDB;uid=myName;pwd=111111;
When I execute this code, it seems to be all ok, but when I try to make a query like:
var query = (from r in MainWindow.dbContext.TabTipoSistema select r);
it throws an exception from here:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException(); //exception here
}
So, this is a bad way... which is the right one? (using only code C#, not from xaml)
Your approach is correct, but you need to remember the connection string for EF requires the metadata and so on. So use the EntityConnectionStringBuilder. For example:
// the model name in the app.config connection string (any model name - Model1?)
private static string GetConnectionString(string model, YourSettings settings)
{
// Build the provider connection string with configurable settings
var providerSB = new SqlConnectionStringBuilder
{
// You can also pass the sql connection string as a parameter instead of settings
InitialCatalog = settings.InitialCatalog,
DataSource = settings.DataSource,
UserID = settings.User,
Password = settings.Password
};
var efConnection = new EntityConnectionStringBuilder();
// or the config file based connection without provider connection string
// var efConnection = new EntityConnectionStringBuilder(#"metadata=res://*/model1.csdl|res://*/model1.ssdl|res://*/model1.msl;provider=System.Data.SqlClient;");
efConnection.Provider = "System.Data.SqlClient";
efConnection.ProviderConnectionString = providerSB.ConnectionString;
// based on whether you choose to supply the app.config connection string to the constructor
efConnection.Metadata = string.Format("res://*/Model.{0}.csdl|res://*/Model.{0}.ssdl|res://*/Model.{0}.msl", model); ;
return efConnection.ToString();
}
// Or just pass the connection string
private static string GetConnectionString(string model, string providerConnectionString)
{
var efConnection = new EntityConnectionStringBuilder();
// or the config file based connection without provider connection string
// var efConnection = new EntityConnectionStringBuilder(#"metadata=res://*/model1.csdl|res://*/model1.ssdl|res://*/model1.msl;provider=System.Data.SqlClient;");
efConnection.Provider = "System.Data.SqlClient";
efConnection.ProviderConnectionString = providerConnectionString;
// based on whether you choose to supply the app.config connection string to the constructor
efConnection.Metadata = string.Format("res://*/Model.{0}.csdl|res://*/Model.{0}.ssdl|res://*/Model.{0}.msl", model);
// Make sure the "res://*/..." matches what's already in your config file.
return efConnection.ToString();
}
EDIT
The exception you get is because when you pass a pure SQL connection string, it assumes you are working with Code first, so it calls the OnModelCreation event. When you include the MetaData section as shown above, that tells EF it's a complete EF connection string.
I believe the problem lies on the Datasource you specify. You need to add the port of the connection, e.g if your SQL Server is configured on Port 1433, try:
server=192.168.1.100,1433\SVILUPPO;database=MyDB;uid=myName;pwd=111111;
more details about connection strings you can find Here
Also I am not sure if uid and pwd are valid, better try User ID and Password:
Server=192.168.1.100,1433\SVILUPPO;Database=MyDB;User ID=myName;Password=111111;
Finally mind the case sensitivity.
For security reasons, I don't want specific method to receive non-programmer or non-compiler time strings, how could I do this?
readonly String OK_STR = "some text";
String BAD_STR = "another text";
public void SetSecureStr(String str)
{
//Use the string for security purpose
}
//Somewhere in the code
SetSecureStr(OK_STR); //Accepted
SetSecureStr(OK_STR + "Programmer passed this staticlly!"); //Accepted (If not possible to implement, forget about it)
SetSecureStr(BAD_STR); //Throw exception, BAD_STR is modifiable
SetSecureStr(OK_STR + untrustedVar); //Throw exception, concatenation with modifiable
SetSecureStr(String.Format("{0}", OK_STR)); //Throw exception, not const
It may be better to whitelist against things inside your ability to control, such as enums or local constants (or a local whitelist from configuration data if the list isn't fixed ahead of time).
As a rough check, you could check whether it is interned, since all literals will be interned automatically via ldstr; but note you can explicitly intern too, so this isn't 100% safe.
And of course, in any event with the question as asked, if that string happens somewhere else as a literal (unconnected to this code) it would still be trusted. I suggest a whitelist is safer...
A whitelist could be as simple as:
private static readonly HashSet<string> whiteList = new HashSet<string> {
"good", "more good"
};
... check via whiteList.Contains(s)
but note that this is still mutable at runtime (via reflection if necessary).
Instead of accepting string values, number all your strings, and pass the number:
string[] good_strings = {"some text"};
public void SetSecureStr(int stringno)
{
string s = good_strings[stringno];
}
Computed strings won't be supported with that approach.
I came finally with a solution which is hybrid between the two previously proposed answers:
public class SqlQuery
{
private SqlQuery() { }
private static UInt32 sqlQueriesCount = 0;
public static UInt32 INBOUND_UPDATE_CALLBACK_NUM = sqlQueriesCount++;
public static UInt32 INBOUND_UPDATE_DEST_ADDR_SUBUNIT = sqlQueriesCount++;
public static UInt32 INBOUND_UPDATE_DEST_BEARER_TYPE = sqlQueriesCount++;
//...etc
private static readonly Dictionary<UInt32, String> queries = new Dictionary<UInt32, String>
{
{SqlQuery.INBOUND_UPDATE_CALLBACK_NUM, "UPDATE inbound SET callbackNum = ? WHERE id = ?"},
{SqlQuery.INBOUND_UPDATE_DEST_ADDR_SUBUNIT, "UPDATE inbound SET destAddrSubunit = ? WHERE id = ?"},
{SqlQuery.INBOUND_UPDATE_DEST_BEARER_TYPE, "UPDATE inbound SET destBearerType = ? WHERE id = ?"},
//...etc
};
public static String GetQueryText(UInt32 queryKey)
{
String query = null;
if (SqlQuery.queries.TryGetValue(queryKey, out query) == false)
{
throw new ArgumentOutOfRangeException(String.Format("Query must be paramerized query stored within SqlQuery class, provided queryKey: {0}", queryKey));
}
return query;
}
}
Usage:
OdbcCommand cmd = new OdbcCommand(SqlQuery.GetQueryText(SqlQuery.INBOUND_UPDATE_CALLBACK_NUM), con);