I am writing an application using ASP.NET webforms with login dialog. After successfull authentication the connection is opened, but connection object is not visible from other webforms. Is there any way to make it persistent and accessible (in some server session objects), or is it commonly done in another way ? Any tips appreciated.
The best way is to open/close the connection where you want to use it. Don't share it and never use a static connection in ASP.NET which is a multi-threading environment. You should use the using statement for all objects implementing IDisposable which ensures that all unmanaged resources are disposed. This will also close the connection, even on error:
using(var con = new SqlConnection("connection string here"))
{
// do something ...
}
You don't need to be afraid that the physical connection must be opened/closed everytime. The .NET connection pool will handle that for you. Related
A simple example.
Set up a class to handle the SqlConnection object (or whatever DB you're using):
DbConnectionProvider.cs
using System.Data.SqlClient
public class DbConnectionProvider
{
public static SqlConnection GetDbConnection()
{
return new SqlConnection("MyConnectionString");
}
}
Then from all classes that needs to use the database
ApplicationClass.cs
using System.Data.SqlClient
public class ApplicationClass
{
private void GetSomeDbWorkDone()
{
using(SqlConnection Conn = DbConnectionProvider.GetDbConnection())
{
//Do some fancy database operations here
}
}
}
This way, if you need to change your Connection details or do something else regarding the SqlConnection object, you only need to do it once and not everywhere in your code.
Related
I have an ASP.NET application with NHibernate, for some reason few developers forgot to close the sessions in some pages (like 20 I think), I know that the best solution is to go through each page and make sure the sessions are closed properly, but I can't do that kind of movement because the code is already on production. So I was trying to find a way to get all the opened sessions in the session factory and then close it using the master page or using an additional process but I can't find a way to do that.
So, is there a way to get all the opened sessions? or maybe set the session idle timeout or something, what do you suggest?. Thanks in advice.
As far as I know, there is no support for getting a list of open sessions from the session factory. I have my own method to keep an eye on open sessions and I use this construction:
Create a class with a weak reference to a ISession. This way you won't interupt the garbage collector if sessions are being garbage collected:
public class SessionInfo
{
private readonly WeakReference _session;
public SessionInfo(ISession session)
{
_session = new WeakReference(session);
}
public ISession Session
{
get { return (ISession)_session.Target; }
}
}
create a list for storing your open sessions:
List<SessionInfo> OpenSessions = new List<SessionInfo>();
and in the DAL (data access layer) I have this method:
public ISession GetNewSession()
{
if (_sessionFactory == null)
_sessionFactory = createSessionFactory();
ISession session = _sessionFactory.OpenSession();
OpenSessions.Add(new SessionInfo(session));
return session;
}
This way I maintain a list of open sessions I can query when needed. Perhaps this meets your needs?
We may never know why Microsoft decided to limit developers by making HealthVault applications constrained to a single web/app.config entry for a HealthVault application. However I need to be able to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
I won’t go into the details of the reasoning behind 2 different HealthVault applications, but other than to say we need it to work. I still cannot login correctly with MSDN Forums (think infinite redirection sign in loop) so I am hoping for a post here that will help me.
I did contact a HealthVault developer on how to achieve this however the developer gave a suggestion that I don’t believe would be reliable (if I’m wrong let me know).
The developer’s suggestion was to do the following in code when you needed to connect to HealthVault, but prior to connecting:
ConfigurationSettings.AppSettings[“ApplicationId”] = “[YOUR APP ID]”;
The problem is that this is a static property and I do see this as an issue as our web application will have different users accessing both HealthVault applications at the same time.
Does anyone have any suggestions to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
There is a way to dynamically switch app ids on runtime. Both applications must be created, both certificates must be installed. Few things to keep in mind. For every authenticated connection, user will be granted a token (aka wctoken). This token is consumed when user is redirect back from Live ID (in case live id is used...) by your redirect.aspx page (assuming your redirect page inherits from HealthServiceActionPage.This means that everytime you switch applications, you must redirect user back to Live ID with new app id to receive new token.
Here is code sample that can be user to dynamically change settings:
public class ConfigurationManager : HealthWebApplicationConfiguration
{
private string appid;
public ConfigurationManager(string appid)
{
this.appid = appid;
}
public override Guid ApplicationId
{
get
{
return AppManager.Current.GetCurrentAppId(this.appid);
}
}
}
public class AppManager
{
private static readonly Object lck = new Object();
public Guid? App;
public static AppManager Current
{
get
{
AppManager mgr = null;
if (_current == null)
{
lock (lck)
{
mgr = new AppManager();
}
}
return mgr;
}
}
private static AppManager _current;
public Guid GetCurrentAppId(string id)
{
return new Guid(id);
}
}
Usage:
ConfigurationManager cm = new ConfigurationManager(your-app-id-here);
HealthWebApplicationConfiguration.Current = cm;
I have an ASP.NET website that uses mysql as it's database. I notice there are a lot of connections "sleeping" when I show a full process list. Today we had some errors "The timeout period elapsed prior to obtaining a connection from the pool.". If the processes are "sleeping" then are they still open from the code? All MySQL connections in the code are in using statements. Can I rely on the using statement to properly close connections?
Edit Code:
I am using this class to create my connection:
public class DbAccess
{
public static MySqlConnection OpenConnection(string connectionStringName)
{
string connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
if (string.IsNullOrEmpty(connectionString))
{
throw new ArgumentException("Connection string " + connectionStringName + " does not exist.");
}
MySqlConnection connection = new MySqlConnection(connectionString);
connection.Open();
return connection;
}
}
Then I am calling it like this:
using (MySqlConnection connection = DbAccess.OpenConnection(connectionString))
{
//Code Here
}
Some additional info: Resetting MySql did not make the errors go away, but resetting my app pool did..
C# using blocks are guaranteed to call the .Dispose() method of the object, even if an exception is thrown. That means it's safe, as long as your provider uses the .Dispose() method to close the connection. Looking in the documentation for that type, I see this excerpt (down in section 25.2.3.3.5):
From Open to Closed, using either the Close method or the Dispose method of the connection object.
This tells me you can close the connection via the Dispose method, and so a using block should be all you need.
hope this could be of any help: MySqlConnection really not close
and
Using MySQLConnection in C# does not close properly
and this one
http://social.msdn.microsoft.com/Forums/en/adodotnetdataproviders/thread/c57c0432-c27b-45ab-81ca-b2df76c911ef
yes, absolutely.
using (MySqlConnection connection = DbAccess.OpenConnection(connectionString))
{
//Code Here
}
is exactly the same as
MySqlConnection connection = null
try
{
connection = DbAccess.OpenConnection(connectionString)
//Code Here
}
finally
{
if (connection is IDisposable)
connection.Dispose
}
provided the MySqlConnection class implements IDisposable, then it'll get cleaned up properly. If you need to call another methos, such as close instead of or as well as, then consider the more verbose syntax above and add the method in the finally.
I'm wondering whether it's possible to use built in ASP.NET application services (aspnet_user, aspnet_role etc table) without specifying a connection string in a web.config.
At the moment I store connection strings externally, but I keep finding hard-coded connection strings all over the web.config xml, various providers etc. It's driving me crazy.
Thank you
You can write your own provider via overriding already existed, built-in class so it will read it's connection string from somewhere else:
public class MyMembershiProvider : SqlMembershiProvider
{
public override void Initialize(string name, NameValueCollection config)
{
config["connectionString"] = "what ever you want";
base.Initialize(name, config);
}
}
I want to seperate the data module of a site into an assembly ( a single dll file ) ,
What is the best way to get-store and pass the ConnectionString of the site in dealing with the web application .
Inside the data assembly I made a static class named ConnectionManager . It has a property named DatabaseConnectionName , that I want to pass and store the connection namewhich is inside Web.Config file .
In this strategy I decided to get the name and make the connection in the load time of the website at the Global.asax file and stroe that in the property I mentioned earlier ( DatabaseConnectionName ) .
But , This is just the strategy that I used , I dont know what is the common pattern for doing this job .
Parts of code : =====================================
[ ------------ Global.asax ------------ ]
the code in the site that makes the Data module accessible for the site
void Application_Start(object sender, EventArgs e)
{
OurCompany.Data.ConnectionManager.DatabaseConnectionName = "MasterConnection";
}
[ ------------ ConnectionManager Class ------------ ]
this is in the data module apart from the site
public static class ConnectionManager
{
public static SqlConnection GetMasterConnection()
{
string connectionString = ConfigurationManager.ConnectionStrings[**DatabaseConnectionName**].ConnectionString;
SqlConnection conn;
//conn.Open();
conn = new SqlConnection(connectionString);
return conn;
}
private static string **databaseConnectionName**;
public static string DatabaseConnectionName
{
get
{
return databaseConnectionName;
}
set
{
databaseConnectionName = value;
}
}
== END ===========================================================
--- Questions are : ---
Where to store the connection ?
( here was a property inside the ConnectionManager Class ,
theCompany.Data.ConnectionManager.DatabaseConnectionName )
When make this connection ?
( here was at Global.asax Application Load time )
Which method is best for storing such information
: SessionState or ViewState or a simple property
Is this strategy good ? Do you know any better way or
the common pattern for this ?
Thanks for any information
- MHM -
A few thoughts...
You shouldn't be storing and hanging onto an open database connection. Open the connection, do your database operations, then close immediately. Apply the rule of acquire late, release early.
See point 1.
Don't store database connections in session state. See point 1 again. If you mean the connection string, then just read it from the configuration manager when you need it. It's already cached for you, don't re-invent or wrap the wheel.
I suggest you take a look at the patterns and practices enterprise library which abstracts away many of the common patterns of managing data access:
http://www.codeplex.com/entlib