ASP.NET modify connectionstring at runtime - asp.net

I need to change dataset connectionstrings to point to different DBs at run time.
I've looked at a number of solutions however they all seem to be related to WinForms or web application projects or other technology slightly different than what I'm using, so I haven't figured out how apply them.
The application is like a discussion. It's a web site project based on code originally written under VS2005, and there's no budget (or personal talent!) for major changes at this time. The app is written in vb.net; I can understand answers in c#. I'm working in VS2013.
The app has three typed datasets pointing to one MDF, call it "MainDB.mdf". There are dozens of tableadapters among the three datasets.
I'm going to deploy the app it as an "alpha/demo" version. I would like to use the same code base for all users, and a separate physical version of MainDB for each user, to reduce chances that the users crash each other.
The initial demo access URL will contain query string information that I can use to connect the user with the right physical database file. I should be able to identify the database name and thus the connection string parameters from the query string information (probably using replace on a generic connection string). If necessary I could use appsettings to store fully formed connection strings, however, I would like to avoid that.
I would like to be able to change the connection strings for all the datasets at the time that the entry point pages for the app are accessed.
Changing the tableadapter connection strings at each instantiation of the tableapters would require too much code change (at least a couple of hundred instantiations); I'd just make complete separate sites instead of doing that. That's the fall back position if I can't dynamically change the connectionstrings at runtime (or learn some other way to make this general scheme work).
Any suggestions on how to approach this would be appreciated.
Thanks!
UPDATE: Per comments, here is a sample instantiation of tableadapter
Public Shared Sub ClearOperCntrlIfHasThisStaff( _
varSesnID As Integer, varWrkprID As Integer)
Dim TA As GSD_DataSetTableAdapters.OPER_CNTRLTableAdapter
Dim DR As GSD_DataSet.OPER_CNTRLRow
DR = DB.GetOperCntrlRowBySesnID(varSesnID)
If IsNothing(DR) Then
Exit Sub
End If
If DR.AField = varWrkprID Then
DR.AField = -1
TA.Update(DR)
DR.AcceptChanges()
End If
End Sub
UPDATE: Below is the test code I tried in a test site to modify the connectionString in a single instantiation of a tableadapter. It feeds a simple gridview. I tried calling this from Page_Load, Page_PreLoad, ObjectDataSource_Init, and Gridview_Databind. At the concluding response.writes, the wrkNewConnString looks changed to TestDB2, and the TA.Connection.ConnectionString value looks changed to TestDB2, but the displayed gridview data is still from TestDB1. Maybe it needs to be called from somewhere else?
Sub ChangeTableAdapter()
Dim wrkNewConnStr As String = ""
Dim wrkSel As Integer
wrkSel = 2
wrkNewConnStr = wrkNewConnStr & "Data Source=.\SQLEXPRESS;"
wrkNewConnStr = wrkNewConnStr & "AttachDbFilename=D:\9000_TestSite\App_Data\TESTDB1.MDF;Integrated Security=True;User Instance=True"
Select Case wrkSel
Case 1
wrkNewConnStr = wrkNewConnStr.Replace("TESTDB1", "TESTDB1")
Case 2
wrkNewConnStr = wrkNewConnStr.Replace("TESTDB1", "TESTDB2")
Case 3
wrkNewConnStr = "Data Source=localhost; Initial Catalog=test01;"
wrkNewConnStr = wrkNewConnStr & " User ID=testuser1; Password=testuserpw1"
End Select
Try
Dim TA As New DataSetTableAdapters.NamesTableAdapter
TA.Connection.ConnectionString = wrkNewConnStr
Response.Write("1 - " & wrkNewConnStr)
Response.Write("<br/>")
Response.Write("2 - " & TA.Connection.ConnectionString)
Catch ex As Exception
Dim exmsg As String = ex.Message
Response.Write(exmsg)
End Try
End Sub
The connection string:
<add name="TestDB1ConnectionString"
connectionString="Data Source=.\SQLEXPRESS;
AttachDbFilename=D:\9000_TestSite\App_Data\TESTDB1.MDF;Integrated Security=True;User Instance=True"
providerName="System.Data.SqlClient" />
UPDATE: the following post has lots of solutions, however, they seem to focus on web application projects, that have a project file with settings, which this web site project does not.
link with possible solutions
UPDATE: this next link was brought to my attention, and in working on it I did get it to work, however, it still relies either on having a web application project (with project file) or modifying each table adapter as they are instantiated. So, while I'm not going to implement it, I believe that is the technical answer.
modifying connection strings

sorry if this answer is too late, but I have exactly the same problem and eventually came up with a solution using Reflection.
My solution was to "save" a new default value for the connection string in the settings at run time, which means any further use of the table adapter uses the the new connection string.
It should be noted the term "save" is misleading as the new value is lost when the application closes.
Have tested and worked perfectly.
public void ChangeDefaultSetting(string name, string value)
{
if (name == null)
throw new ArgumentNullException("name");
if (value == null)
throw new ArgumentNullException("value");
Assembly a = typeof({Put the name of a class in the same assembly as your settings class here}).Assembly;
Type t = a.GetType("{Put the full name of your settings class here}");
PropertyInfo propertyInfo = t.GetProperty("Default");
System.Configuration.ApplicationSettingsBase def = propertyInfo.GetValue(null) as System.Configuration.ApplicationSettingsBase;
//change the "defalt" value and save it to memory
def[name] = value;
def.Save();
}

Related

Finding Client Printer ASP.Net

From what I have read its not possible to find a clients local printer using modern browsers for security reasons. I have a few conditions that might make that answer different.
I am trying to get clients local printers from within a company network. So this isnt published 'outside'
I thought several years ago Microsoft released a small version of .Net that could be run from the clients browser. If so and its still around I wonder if that could inspect clients local printer.
Thanks
One way to give the appearance of retrieving the clients printers is to run a server side application in the same network with the same access permissions. Silverlight may be able to do it. I have no experience with it unfortunately.
Check here: Get list of network printers silverlight
This ended up being a lot of work with little information because nearly all my searches on the internet for a solution assumed we want to get the printers of the client from the browser. We want to find such information it via the Network.
The solution ended up being with DirectorySearch and the like. here is the code with some privacy stuff removed. Its in a POF state so it might have some not so great syntax
Dim list As New List(Of String)
Dim listtemp As New List(Of String)
Dim resultCollection As SearchResultCollection
Dim computer_name As String = System.Net.Dns.GetHostEntry(Request.ServerVariables("remote_addr")).HostName.Replace(".ourcompany.com", "").ToLower 'clients machine name
Dim dirEntry As New DirectoryEntry("LDAP://DC=OURCOMPANY, DC=com")
Dim dirSearcher As New DirectorySearcher(dirEntry)
dirSearcher.Filter = "objectCategory=printQueue"
dirSearcher.PropertyNamesOnly = True
dirSearcher.PropertiesToLoad.Add("Name")
dirSearcher.SearchScope = SearchScope.Subtree
resultCollection = dirSearcher.FindAll()
For Each sresult As SearchResult In resultCollection
If sresult.GetDirectoryEntry.Name.ToLower.Contains(computer_name) Then
list.Add(sresult.GetDirectoryEntry.Name.ToLower.Substring(3).Replace(computer_name + "-", ""))
End If
Next

Best way to distinguish between Test and Production with Classic ASP

I have inherited a classic ASP application. There are various things that need tidying-up but I am forced to do things gradually (I can't do a wholesale change of every script).
There are places in the system with hard-coded urls. Some scripts have to be changed before promoting to live so that the test web root name is changed to the live web root name. I am looking at ways to avoid this (essentially working out the server programmatically).
It isn't difficult. A simple check on Request("SERVER_NAME") and this sort of thing:
appName = Request.ServerVariables("SCRIPT_NAME")
i = InStr(2, appName, "/") 'keep initial "/"
If i > 0 Then
appName = Left(appName, i)
End If
This in an "everywhere-included" script will do the trick. Then just set up a global variable to hold the full "http(s)://server/app/" or a function to MakeUrlAbsolute() and off you go.
However, this smells a bit suspect to me. Wouldn't this be better stored at application level? This suggests setting it up in Global.asa, something like:
Sub Application_OnStart()
Application("WebRoot") = ...
End Sub
But now I can't get hold of the SERVER_NAME so I'm reduced to having 2 different Global.asa files (one per environment).
Is this my only choice? Work it out on every request or hard-code in Application_OnStart?
Perhaps using Session_OnStart would be a compromise. Or is there some clever trick to access information in Application_OnStart? Perhaps people go with the hard-coding because Global.asa doesn't change often.
my method for ADO Connection looks like this.
'Servername for Application Root Drive
Select Case Left(Request.ServerVariables("PATH_TRANSLATED"), 1)
Case "c" strSrvr = "80.212.207.211" 'my remote server ip
Case Else strSrvr = "(local)" 'local Sql instance (my project on D: drive)
End Select
strConn = "Driver={SQL Server};Server="& strSrvr &";uid=DBUSER;pwd=MYPASS;database=MYDATABASE"
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open(strConn)

'instance failure' error while connection string is correct

I have following code on page load event:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
con = New SqlConnection("Data Source=14GRAFICALI\\SQLEXPRESS;Initial Catalog=sagar;Integrated Security=True")
'-----------------------fill name ddl------------------------------'
Try
da = New SqlDataAdapter("select EmpName from empMaster_VB", con)
ds = New DataSet()
da.Fill(ds)
For i As Integer = 0 To ds.Tables(0).Rows.Count
ddlName.Items.Add(ds.Tables(0).Rows(i)(0).ToString())
Next
Catch ex As Exception
End Try
'--------------------------------------------------------------------'
'----------------fill expence-------------------------------------'
Try
da = New SqlDataAdapter("select ExpName from expenceType_VB", con)
ds = New DataSet()
da.Fill(ds)
For i As Integer = 0 To ds.Tables(0).Rows.Count
ddlExpence.Items.Add(ds.Tables(0).Rows(i)(0).ToString())
Next
Catch ex As Exception
End Try
'---------------------------------------------------------------'
End Sub
This code is to fill drop downs with names and expence values in database tables.
I am getting 'instance failure' error while executing the code.
I checked one of the answers on stack and checked my connection string. But, my connection string is also correct.
Please help me if anything else is missing in this code.
As you got the error "instance failure", that might be the error with your SQL Server instance..
Make sure your SQL Server instance(MSSQLSERVER) is running, where you can check in: Services list. TO get into services list: open run dialog box and type: "services.msc" (without quotes) and hit Enter. That takes you to services management console, where you can check whether your instance in running or not..
If the problem still persists, then try using: Data Source=.\SQLEXPRESS instead.. :)
Happy Coding... :)
I have connection:
Data Source=MyComputerName\SQL2012ENTERPRS;Initial Catalog=RESTFUL; User Id=myuser; Password=mypass123;
My server is : MyComputerName\SQL2012ENTERPRS
But since I use string, I add more \ so, at my code It will be:
public string connectionString = "Data Source=DAFWKN409C67Q\\SQL2012ENTERPRS;Initial Catalog=RESTFUL; User Id=rest_user; Password=rest_pwd_01;";
I have forgoten that I must remove one of \ since I am not use default string block, I use XML file to save my connection string. Then everything is ok. So, my suggestion is your instance name is not correct.
This is my connection string sample it I use local pc using SQL express:
string servername = #"Data Source=.\SQLExpress;Initial Catalog=Workshop;Integrated Security=True";
You should modify with your server name, and instance name by yourself, make sure it correct.
I had this issue because I got the connection string from appsettings.Development.json:
"Server=msi\\DataBaseName;Database=Super25;Trusted_Connection=True;"
but when I changed to
"Data Source=msi\DataBaseName;Initial Catalog=Super25;Integrated Security=True;"
solved!
in my case just kick up the double \\ to one slush \
:=)
The root cause is Regular literal ("Backslash: \") and Verbatim literal ("#"Backslash: \"") .
Reference https://csharpindepth.com/Articles/Strings
Use the wildcard "#" before "Data Source" declaration. someting like this:
connetionString = #"Data Source=...
So you'll be able to use only a back slash. Like this: #"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\jcabarros...
I know this is an old thread, but perhaps a good update. I couldn't find a good answer on the web search.
I got the same 'Instance Failed' error when trying to reference a DbContext from another project in the same solution. The 1st project had a DbContext and the connection string, and the 2nd project in the solution was trying to reference it. The 1st app ran ok on its own, issue only occurred when running the 2nd app.
The issue was that the app.config file that had the connection string from the 1st project was not in view/scope of the 2nd project. So the connection string wasn't assembled.
My solution was to copy the app.config from the first project to the second project.
This was on VS 2019.
Hope this helps
Your answer lies in the connected services. edit provider and select the three dots once you find your database select advanced in the advanced you will see your connection string which looks like below.
Data Source=Server\ServerInstance;Initial Catalog=yourDatabaseName;Integrated Security=True
You can add more services and configure more there.

Dynamic connString (now stored in session, bad)

I working on a project where the connString is stored in a session variable. The problem is that the session runs out when the user is not around for a while (makes sense), thereby making the user having to log in again to create a new connection.
The user selects his database from a list of ODBC connection configured on the web server, therefore the different connStrings the user can chose from cannot be stored in the web.config as the user can add new ones as they wish.
I was wondering how to fix this problem. Should I just tell the user not to leave his computer for 20mins+ or can I perhaps store the connString someplace else? Ive seen websites making a pop-up saying "your session will expire in 5 mins, press ok to continue using the site", or something like that.
Furthermore it is not a possbility to make a static varible as the website is shared between many users, so if user1 choses "connString1" and user2 choses "connString2" afterwards, then user1 will unfortunatly be running on "connString2" aswell.
Hope you can help :)
**
Can this be a solution?:
I create a "BasePage" which my pages inherit from. In this basepage i create a hiddenfield and add the connString to the value property on load. Furthermore I will encrypt the connString so the user cannot see the value in the source code.
Then, if the session has a timeout, i will restore the session by using the value in the hiddenfield and the site will not crash.
Can you store the user's connection string preference in their Profile and then persist their profile? http://odetocode.com/articles/440.aspx
You should also be able to do this for anonymous users.
As an aside, I don't know how secure the Profile APIs are, they should be fine, but just in case, you might want to store an Enum value and then map that to a Connection string in your code.
You could use the app.config to get and set config files. Take a look at this to see implementation of storing files. Its just as easy to get settings.
ConfigurationManager doesn't save settings
//Edit: If you don't want the user to be able to see your connectionstring name then you can provice an another in hidden_html or cookie or session cookie. In this example I use a cookie. THis should solve your problem.
To set cookie:
HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie["ConnectionString"] = "MyCOnnectionValue";
myCookie.Expires = DateTime.Now.AddDays(1d);//For one day.
Response.Cookies.Add(myCookie);//Will store the cookie within the users browser so your code can read from it at every request.
then:
if (Request.Cookies["UserSettings"] != null)
{
string userSettings;
if (Request.Cookies["UserSettings"]["ConString"] != null)
{ userSettings = Request.Cookies["UserSettings"]["ConString"]; }
}
string connectionStringNameToUse;
if(userSettings =="Connection1"){
connectionStringNameToUse = "here you can have your name of connectionsstring";
}etc with ypur other connectionsstrings here.
//Then use your connectionsstring here:
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings[connectionStringNameToUse ].ToString()))
{
cn.Open();
using (SqlCommand command = new SqlCommand
("delete TBL from RatingListObjects TBL where ( TBL.TradeObject1Id = #MY_ID ) or ( TBL.TradeObject2Id = #My_ID ) ", cn))
{
command.Parameters.Add(new SqlParameter("#MY_ID", customerToRemove.TradeObjectId));
command.ExecuteNonQuery();
}
}
On the other hand. I would go for saving the users database of choice in with the other user data in the db. But this is doable if you only want the user to have a chosen connectionsstring a certain time, set by the program. It wont allow them to see the connections string name. Hopes this helps, good luck!

ASP.Net Cart - Duplicate Session IDs

Can anyone tell me what is happenning here? I am getting duplicated session ID's across 2 seperate machines, 2 different browsers in a shopping cart website?
I've gone so far as generating a new session id with a 300 character random string, and still they get duplicated
This is the new code... just take out the SyncLock stuff for the old code:
Dim _key As String = String.Empty
SyncLock _locker
_key = Guid.NewGuid().ToString()
Session("Identifier") = Validations.GeneratePassword(150, 300)
Session("SessionID") = _key
Session("SiteID") = "F2630237-E355-4C8A-947E-BBAC97ECA550"
Session("HomePage") = 13
End SyncLock
yes I know Session("SessionID") is not the session ID, however, we used to use Session.SessionID for the "Identifier", and it was getting duplicated
Why would you generate your own SessionID?
ASP.NET and the browser do this out of the box and probably better that you or I.
I recommend you use this instead:
HttpSessionState.SessionID
I am rather doing a different approach
I created a table with identity, every time when needed a session id , an insertion is made and stored in session variable
I think random generators cannot be trusted
I found the solution to this.
if i set the session manager in web.config to be my class, and it worked
<sessionState mode="InProc" cookieless="false" timeout="20" sessionIDManagerType="o7th.Projects.Core.SessionManager"/>

Resources