ASP.NET Connection String - asp.net

I am having some trouble with one of my ASP.NET 2.0 application's connection string. There are instances that I would get a ConnectionString Property Has not Been Initialized problem which occurs randomly and intermittently and without any reason.
My Connection string is actually coming from a webservice, because different kinds of users are provided with different sets of connection string depending on their user level.
What I have done so far goes like this:
I have a master page (mstr.page) and the corresponding code behind (mstr.page.vb).
In my master page, I retrieve initially the connection string and store the same into a session variable, i.e.
Session("ConnString") = "RetrievedConnectionString"
Now in one of my pages, let us say page1.aspx.vb, I use public shared functions from a class (named MyClass.vb) and use it in my page1.aspx.vb.
Some codes for reference:
[MyClass.vb]
Imports System.Web
NameSpace ClassNameSpace
Public Class Admin
Protected Shared da as New DataAccess()
Public Shared Function MYFunction() as String
'Execute some sql statements here, using the DataAccess
stringToReturn = Ctype(da.ExecuteScalar("SQLCommand"), String)
Return stringToReturn
End Function
End Class
End NameSpace
[DataAccessClass.vb]
Public Class DataAccess()
Private m_ConStr As String = ""
Public Sub New()
m_ConStr = HttpContext.Current.Session("ConnString")
End Sub
'Some methods for SQL statement execution (ExecuteQuery, ExecuteScalar)
End Class
[Page1.aspx.vb]
Imports ClassNameSpace
Protected Sub Page_Load(....) Handles Me.Load
Dim strValue as String = Admin.MyFunction()
End Sub
I have placed the code above to show you some rough idea of how things are going.
Basically, the function Admin.MyFunction() at times fails, because in the data access class, the connection string seems to have lost it's value (either blank or Nothing).
This has troubled me for quite some time already.
I hope someone can point me in the right direction to resolve this. Basically, I want my connection string which is retrieved by each user visiting the web application be maintained across all the time and be used anywhere. Session variable does not seem to be the best fit since when the ASP.NET recycles its process, the session is lost.
By the way, I am retrieving the connectionstring initially via the master page from a web service. I tried to place the same retrieve function in the Data Access class when conditions is that the session variable is lost, but I think my application cannot connect to the Web Service during the recycle process.
Any advice would be greatly appreciated on this.
Update on this:
I tried to use Session Variable and set the mode to State Server, but apparently some DLLs which I am using cannot be serialized, thus I am back to square one.
Is there a better way to do this?

One thing to check is if your Session is getting clobbered. If your using the (default) in-memory Session, then sessions die anytime an ASP.NET worker process is recycled. If this is causing your issue, you might have to look into using the ASP.NET SessionServer in IIS, or SQL Server as your Session storage.

I'd try to limit your use of the Session for this type of thing as much as possible. If you utilize the Web.Config for storing your connection strings, you can access it at anytime and it will not expire on you like the session.
You may also consider having a static data access class if it is the same for all users for the applications instance...

This is the exact same problem I was experiencing, and it turned out to be the session variables dying so the connection string couldn't be initialized properly.

Why cant your app use just one connection string? and why does the connection string need to come in through a webservice? that adds a huge amount of latency to the entire process. I assume it probably has to do something with data security in your database.
If you have to do this, I'd say, can't you have a fall back / default connectionstring? Wrap your code that attempts to pull it out of the session with some error handeling and if it fails revert to your default?

I would place your web service and web app in different app pools. Then increase the timeout length of your web apps pool.

Related

Create Database If Not Exist Without Restarting Application

I am creating dynamic connection strings in my project. They're created on the fly with the information provided specifically for every user. When the application first fires off, if a database doesn't exist (first time user logs on), a new database is created without problems with this initializer:
public DataContext() : base()
{
// ProxyCreation and LazyLoading doesn't affect the situation so
// comments may be removed
//this.Configuration.LazyLoadingEnabled = false;
//this.Configuration.ProxyCreationEnabled = false;
string conStr = GetDb();
this.Database.Connection.ConnectionString = conStr;
}
The problem is, with this method, I have to restart the application pool on the server and the new user should be the first accessor to the application.
I need the same thing without a requirement of restarting the app. Is that possible?
(This is a SPA using AngularJS on MVC views and WebApi as data provider - May be relevant somehow, so thought I should mention)
I already tried this, but this creates an error for EF and the application doesn't start at all...
You could try a little bit different approach to connect directly (and create) the right database.
public class DataContext : DbContext
{
public DataContext(DbConnection connection) : base(connection, true) { }
}
Here you create the DbContext already with the right connection.
Take also care because you need to specify to migrations that the right connection should be used (not the Web.Config connection but the connection that raised the database creation).
See the second overload here https://msdn.microsoft.com/en-US/library/hh829099(v=vs.113).aspx#M:System.Data.Entity.MigrateDatabaseToLatestVersion.

Asp.net static object appears sometimes as non global

I have an android application as client and ASP.Net + ADO.Net hosted on GoDaddy server. The asp.net has static data structure which stores (among other) the android locations, this data structure is persist also to SQL server 2008 data base. each time the android client change position it send its location to the server which update the data structure and data base. each time the applicaton start the data structure is filled according to the persist data from the data base.
The Problems : altough the data structure is static thus should be global it looks like sometimes there are more then one instances of this static data structure.
Is anyone aware of this issue ?
How can i prevent this from hapening ?
Nathan
This object is has actually a dictionary with name as key and info as
value. This object is updated according to android client which access
the asp.net via HTTP thorugh aspx Page_Load :
HttpContext.Current.Application.Lock() .
The first error is that you use that kind of lock and not the correct one.
The Application.Lock() and Application.Unlock() are designed as lock mechanism only for the Application variables.
To correct lock your static Dictionary you need to use the lock(){} as:
private static readonly object syncLock = new object();
public static Dictionary<int, int> DictMem = new Dictionary<int, int>();
... inside some function....
lock (syncLock)
{
// actions with your dictionary
DictMem[2]=3;
}
Also I like to tell you that the static is not guaranty that you have only one on your program. If the provider use web garden you have more than one, and when the pool recycles then you loose them.

Utilize a 3rd Party API in VB.NET

I know this may be a simple answer or at least to most people but I'm not getting anywhere when attempting this on my own or through the various resources I have looked up. I'm pretty sure I'm just physically searching the wrong terminology or phrases to get my answers.
Here is my issue:
I am using ASP/VB.NET to build this integration. Visual Studio 2008. I previously had asked a question on API Integration on here and utilized that information to successfully perform the next steps. As this API is written differently I may not be grasping the appropriate functions correctly.
A company has given me several addresses for .ASMX portals. I add these into my service references. I can successfully see objects in my object browser and see all the procedures, etc., but further from here I'm unable to correctly use any objects. I attempted to replicate the integration based on my last API question and advice: Connecting to an API offered by a Company. When I'm attempting to use an object or simply relate a field to something on my script I continually get an error.
For example:
Dim A as New API.AddFunction
A.AccountNo = "123"
When running the page:
Object reference not set to an instance of an object.
Here is only one .ASMX I was given. I cannot release any more, until I receive permission to do so from the provider, I apologize.
http://cert1.tpayment.com:14935/Terminal.asmx
Anyhow, the root of my question is really how do I correctly interface with this API? What information do responders require so I can clarify this question more? Understandably you cannot guess at the problems until more information is shared. Is there a primer I can read through online?
The word you are looking for is XML web service or SOAP web service. This will help you with getting further with finding information on how to use such API. Specifically, your task is to "consume an XML web service using ASP.NET".
By having a quick look at the sample web service you provided it looks more than manageable. However, one thing you have to always remember that a web service operates on a "request - response" basis even though it is somewhat concealed when you add it as service reference to your project and it starts to look like just ordinary classes with methods and properties.
Here's a quick example to get you started. Let's assume you have a button "Button1" and a label "Label1" on your aspx page and that you added your example service as service reference with the namespace "Terminal". Here's a little server-side code for the click event of the button:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim SoapClient As New Terminal.TerminalSoapClient
Dim Credentials As New Terminal.OnBoardCredentials
Dim DataStructure As New Terminal.TerminalDataStructure
Dim ErrorMessages() As Terminal.OBAErrorMessage
Dim result As Boolean
Credentials.UserName = "username"
Credentials.PassWord = "password"
DataStructure.AccountNo = "123"
DataStructure.TerminalID = "123"
result = SoapClient.Add(Credentials, DataStructure, ErrorMessages)
Label1.Text = result.ToString & "; " & ErrorMessages(0).ErrorCode & " : " & ErrorMessages(0).ErrorMessage
End Sub
As you can see to start working with the web service you need a SOAP client. The client will expose the methods of the service such as "AddTerminal" in the example service.
Then you need to put together the arguments for that operation, which in the case of AddTerminal are "OnBoardCredentials", "terminal" (represented by the generic TerminalDataStructure class) and "ErrorMessage). Also note that this particular operation requires an array of ErrorMessages since the web service can return more than one in a single response.
Once you have specified the properties of each argument you are ready to call the operation (i.e. send the request) and use the returned value(s) (i.e. the response).
Technically, the response of this particular operation contains an overall result of the Add operation as boolean as well as error messages if any. However, only the overall result is returned by the TerminalSoapClient.Add operation whilst the error messages are added back to your array of OBAErrorMessage.
Lastly, for demo purposes I present the results back to label on the page. When I try it I get
False; 13000 : Error during Login
since I don't have valid credentials to log in to the service.
Though very crude I hope this example helps to get you started.

Problem with Unit testing of ASP.NET project (NullReferenceException when running the test)

I'm trying to create a bunch of MS visual studio unit tests for my n-tiered web app but for some reason I can't run those tests and I get the following error -
"Object reference not set to an
instance of an object"
What I'm trying to do is testing of my data access layer where I use LINQ data context class to execute a certain function and return a result,however during the debugging process I found out that all the tests fail as soon as they get to the LINQ data context class and it has something to do with the connection string but I cant figure out what is the problem.
The debugging of tests fails here(the second line):
public EICDataClassesDataContext() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["EICDatabaseConnectionString"].ConnectionString, mappingSource)
{
OnCreated();
}
And my test is as follows:
TestMethod()]
public void OnGetCustomerIDTest()
{
FrontLineStaffDataAccess target = new FrontLineStaffDataAccess(); // TODO: Initialize to an appropriate value
string regNo = "jonh"; // TODO: Initialize to an appropriate value
int expected = 10; // TODO: Initialize to an appropriate value
int actual;
actual = target.OnGetCustomerID(regNo);
Assert.AreEqual(expected, actual);
}
The method which I call from DAL is:
public int OnGetCustomerID(string regNo)
{
using (LINQDataAccess.EICDataClassesDataContext dataContext = new LINQDataAccess.EICDataClassesDataContext())
{
IEnumerable<LINQDataAccess.GetCustomerIDResult> sProcCustomerIDResult = dataContext.GetCustomerID(regNo);
int customerID = sProcCustomerIDResult.First().CustomerID;
return customerID;
}
}
So basically everything fails after it reaches the 1st line of DA layer method and when it tries to instantiate the LINQ data access class...
I've spent around 10 hours trying to troubleshoot the problem but no result...I would really appreciate any help!
UPDATE:
Finally I've fixed this!!!!:) I dont know why but for some reasons in the app.config file the connection to my database was as follows:
AttachDbFilename=|DataDirectory|\EICDatabase.MDF
So what I did is I just changed the path and instead of |DataDirectory| I put the actual path where my MDF file sits,i.e
C:\Users\1\Documents\Visual Studio 2008\Projects\EICWebSystem\EICWebSystem\App_Data\EICDatabase.mdf
After I had done that it worked out!But still it's a bit not clear what was the problem...probably incorrect path to the database?My web.config of ASP.NET project contains the |DataDirectory|\EICDatabase.MDF path though..
Is LINQDataAccess.EICDataClassesDataContext looking to the web.config or some other outside source of data for its setup?
I can tell you for a fact that you must jump thru hoops to get web.config accessible to your test code.
Update
Ah, yes. I see that you're using ConfigurationManager on the line where your test fails... ConfigurationManager looks to web.config for configuration. This has been a sticking point for me when I write my tests.
You need to either change the code so that the class can be instantiated without web.config, or you need to make it so that your tests can access web.config.
Does your test project have it's own configuration file? This type of behavior usually means the app can't find the connection string. Test projects require their own file since they are not running in the context of the client app.
UPDATE The error you describe after adding an app.config is common when testing web applications built on SQLExpress and attaching an .mdf. SQLExpress cannot be run in more than one process at a time. So if you have previously run your web application it may still be active and will conflict with the attempt to attach the database.
You can use SQL Management Studio to attach the database permanently and then use a more traditional connection string like:
Server=myServer;Database=EICDatabase;Trusted_Connection=True;
For me it seems like your problem is the connection string, which is not set.
I assume your unit test is in a different project than the DAL.
You call the 'new' command on the datacontext constructor without a connection string. So it should usually use its default, when set. But since this setting normally is stored in the web.config of the other project there is no connection string set and you get the error.
If its right, what i assume, you have to get the settings from the DAL project into the unit-testing project. Simplest solution should be to copy web.config connection string to app.config of unit test project.
There are other possibilities for sure, but i think its not easy to get the web.config configuration into your unit-testing project.

Is it possible to change an ASP.NET Web.Config value at runtime without reloading the application domain?

Is it possible to change a database connection string value in the Web.Config at runtime without reloading the application domain? The reason for doing this is that:
I am building a multi-tenanted application which uses the one code instance and multiple databases instances approach, so the database connection string in the web.config must be able to be changed at runtime for different tenant users.
ADO.NET always injecst the database connection string in the web.config when you are using entity framework/LINQ to SQL etc, dataset etc.
So I may have to do something weird like this. Hope it is clear enough. Thanks a lot!
Yes it is possible.
try this
System.Configuration.Configuration conf = WebConfigurationManager.OpenWebConfiguration(Server.MapPath);
conf.ConnectionStrings.ConnectionStrings["comp1"].ConnectionString = _connection_comp1;
conf.ConnectionStrings.ConnectionStrings["comp2"].ConnectionString = _connection_comp2;
conf.AppSettings.Settings["CompanyCode"].Value = _company_code;
conf.Save();
Use configuration sections.
http://www.kodyaz.com/articles/add-connection-string-to-web-configuration-file.aspx

Resources