Can you share the session variables between two .net 2.0+ applications? - asp.net

I was told this works, but...
I guess I'm just not getting this, it seems there's a hidden step I may be missing, can anyone correct this or point out my mistake? Thanks.
I have a blank solution:
- inside is two .net 2.0 web applications
1) webapp1
2) webapp2
I want them to share the same session data.
My page setups:
Application 1:
Session("value") = "this is the value"
Application 2:
If Not (Session("value") Is Nothing) Then
value = Session("value").ToString()
End If
My thought process:
1) go to services, turn on the asp.net state service
2) open the web configs in both projects: set the
< machineKey
validationKey="BFE2909A81903BB303D738555FEBC0C63EB39636F6FEFBF8005936CBF5FEB88CE327BDBD56AD70749F502FF9D5DECF575C13FA2D17CA8870ED21AD935635D4CC"
decryptionKey="2A86BF77049EBA3A2FA786325592D640D5ACD17AF8FFAC04" validation="SHA1" />
< sessionState mode="StateServer" stateConnectionString="tcpip=localhost:42424"
cookieless="false" timeout="20"/>
in both sites.
3) compile and test the site
4) become disappointed because it does not work. I never see the session from the second webapp.

You cannot share sessions between different ASP.NET applications without some custom code. What you did in web.config was to use an out of process sessions, which means that data will no longer reside into memory but into the memory of a dedicated machine. This is useful for server farms and it uses the ApplicationName to know which application the session belongs to. So basically your applications need to have the same name if you want them to share sessions. There are some dirty workarounds though.

Why do you want to share Sessions between applications? ASP.NET Session is not designed to do that.
Your proposed solution of using the same ASP.NET State Server does not work because your user will simply get 2 different session tokens, even if they use your 2 applications concurrently from the same machine, and same browser. You need to consider how Session works to understand why this is.
From MSDN:
ASP.NET session state enables you to store and retrieve values for a
user as the user navigates ASP.NET pages in a Web application. HTTP is
a stateless protocol. This means that a Web server treats each HTTP
request for a page as an independent request. The server retains no
knowledge of variable values that were used during previous requests.
ASP.NET session state identifies requests from the same browser during
a limited time window as a session, and provides a way to persist
variable values for the duration of that session.
ASP.NET Session is a metaphor for a user's current interaction with one ASP.NET application. It exists in ASP.NET to give us a place to store temporary state data between the various page requests that a user makes while using your application.
If your applications are very closely related, e.g. the user uses both at the same time, or almost the same time, you could consider merging them into a single ASP.NET application. You could deploy them into different Virtual Directories to maintain some degree of logical separation, but use only one Application in IIS.
If your applications are not that closely related, perhaps they should be sharing the same database as a means to exchange data, or using an API e.g. based on Web Services to exchange information.

They will share session data if they are in the same app pool and the session mode is set to inproc. The way that stateserver and sqlstate work is they use the root of your web address as logical boundaries.
Eg if they are both hosted on the same address and port (or 'site' in iis) but in different sibfolders then they should share session I think.

Additionally both apps must run on the same domain so that user browser use one cookie to store session id.

Related

Alternative to Session for a per-user variable in ASP.NET MVC

I am working on a MVC 3 application that will be hosted in a web-farm with a multi-worker process setup. There are about a dozen variables that are being stored in Session but are getting lost due to the IIS setup.
By getting lost I mean that when the Logon process succeeds I see through logging that I have set the Session variables but then after the Redirect action and on the landing Controller Action the Session variables are often empty. I'm not sure if this is related but this is in a HTTPS.
We are looking at the possibility of moving our user-specific settings that are stored in Session out to some other mechanism but there is one variable that I won't be able to do that with. Given the above deployment environment I have the following questions.
Are cookies my only (best?) alternative to storing Session variables for user-specific settings?
If so is there a secure mechanism for writing cookies so they cannot be manipulated and can still be read in a multi-server environment?
As I understand it System.Runtime.Caching suffers from the same problem when ran in the above IIS configuration. Is that true?
Are cookies my only (best?) alternative to storing Session variables
for user-specific settings?
No - they are about the worst possible approach. Three reasons that come to mind:
They can be manipulated.
They travel with every request from client to server - inefficient.
They will add more complications to your implementation since you'll have to start thinking about securing them in different ways.
If so is there a secure mechanism for writing cookies so they cannot
be manipulated and can still be read in a multi-server environment?
See answer above.
As I understand it System.Runtime.Caching suffers from the same
problem when ran in the above IIS configuration. Is that true?
True. You should be using any of the State Providers that are out of proc. You can either use Sql Server to store session data -provided your objects are serializable, obviously- or the State server mode mode="stateserver"
Read here for more details

ASP.NET SQL SessionState or Custom solution?

The ASP.NET SQL SessionState provider seems excessive for my requirements. SQL Server has to be 'configured' to support it and I have questions about how optimized it is (i.e. is there one db hit to fetch the whole session or one for every session item requested?).
I think I could implement a custom solution very easily that I would understand and easily redeploy to other projects. Is there something fundamental I haven't considered here and an obvious reason why the built in SessionState handler is the 'best' way to go?
Just to clarify, our applications run on single servers at the moment. My main motivation for doing this is to enable Session to persist across IIS restarts and therefore provide more reliability for users.
you could use StateServer mode.
StateServer mode stores session state in a process, referred to as the ASP.NET state service, that is separate from the ASP.NET worker process or IIS application pool.
Using this mode ensures that session state is preserved if the Web application is restarted and also makes session state available to multiple Web servers in a Web farm.
more info at http://msdn.microsoft.com/en-us/library/ms178586.aspx
It takes just minutes to setup SQL session state server (assuming you have SQL server already running). I can't imagine that you can write anything in less time than it would take to at least try out what already exists and is free and supported by MS.
A proven, built-in/off-the-shelf solution is always better place to start than custom. You may still end up with a custom solution, but don't pick it because you didn't bother to test what is already available to you.

ASP.NET: Is Session Object my acceptable solution for static variable?

I've read several threads about this topic and need some clarification on a few sentences I read in a book:
If you store your Session state in-process, your application is not scalable. The reason for this is that the Session object is stored on one particular server. Therefore storing Session state in-process will not work with a web farm.
What does "scalable" in the first sentence mean?
Does the third sentence means if my app resides on a shared web host, I shouldn't use Session["myData"] to store my stuff? If so, what should I use?
Thanks.
1:
Scalability in this sense:
the ability of a system, network, or process, to handle growing amounts of work in a graceful manner or its ability to be enlarged to accommodate that growth.[
2:
Use a session server or store sessions in SQL Server, which are described here.
ASP.NET can store all the combined Session information for an Application (the "Session State") in 3 possible places on the server-side (client cookies is also possible but that is a different story):
"InProc" (In Process) which means in memory on the IIS server attached to the asp.net worker process,
"StateServer" which is a separate process that can be accessed by multiple IIS servers but still stores the Session state in memory, and
"SQLServer" which stores the Session state in a SQL Server database.
1) The reason In-process is not scalable is if your needs exceed the capacity of a single IIS server, multiple servers can't use an In-process session state. If you have determined a shared hosting scenario will fulfill you needs, you don't need to worry about it.
2) When you store something in Session["Name"], ASP.net stores that data wherever the application is configured to store Session state. If you want to change where Session state is stored, all you need to do is configure your web.config file. If you are using a shared hosting environment, your IIS deployment is considered single server even though no doubt the actual servers are in a farm of some sort.
See: MSDN Session-State Modes

How to maintain the same session id across multiple web applications in ASP.NET

I have two identical applications setup on IIS on different virtual directories (I have done some workaround to ensure that they both have the same application name). Is there a way to share session id across two asp.net web applications?
Since I'm storing the session in StateServer, they should both be getting the same session data, however, a different session id is created everytime I go from application a to applicatino b. Wouldn't this happen in a load balancing scenario as well? Where when I go to www.test.com, it would redirect that request to server a, and then if I hit it again, it would go to server b, but since it's a different web application, it would create a new session id?
First, configure the sessionState element in your web.config to use cookieName="SOME_COOKIE_NAME_HERE" in both apps.
Then, just make sure the urls have the same TLD (top-level domain), i.e. app1.mydomain.com and app2.mydomain.com and you should be able to handle the Session_Start event in Global.asax and put this code:
HttpCookie cookie = new HttpCookie("SOME_COOKIE_NAME_HERE", Session.SessionID.ToString());
cookie.Expires = DateTime.Now.AddMinutes(20);
cookie.Domain = "*.mydomain.com";
cookie.HttpOnly = true;
Response.SetCookie(cookie);
Also, I would recommend that you go with the SqlServer SessionState Mode.
Initially i faced the same issue. What I did is, I overide the jsession id from each domain. I mean, If the user lands on domain1.com, set the same session id for domain2.com from iframe. and vice versa. With this, you can maintain same session across multiple domains.
You need to test the impact over multiple server over network with load balancer.
Is your goal to share the session state between 2 applications, not just the session ID? I believe the StateServer also uses the application path as well as the SessionID to store the data so even if the SessionID's were the same you still wouldn't be able to share the data. You might have to write your own session module.
Load balancing web apps don't have this problem because the application path is the same across cluster members.

ASP.Net Session State

I was wondering whether it would be possible to change the sqlConnectionString used for SessionState in ASP.net based upon the domain an application is running on?
A scenario; We have 20 sites running from one application all talking to different databases depending which domain (site) they are browsing from.
When browsing www.domain1.com the application talks to the database 'db1'. The site www.domain2.com on the other hand talks to the database 'db2' etc, thus selecting the relevant content and also spreading the load to each database rather than using one master database to handle all connections for the sites.
An issue that has arisen though - for this setup we use SqlServer mode for the SessionState so all users to all sites sessions are stored in 1 aspstate database, now as the sites get busier / number of sites increase this database comes under increasing strain to handle all the session requests for all the sites and we are starting to get some timeout errors where the connections to this database are bottlenecking.
We can seperate out the sites to from their own application and set up different applications with the same code but within each application set a different Session database in each Web.Config and thus lightening the load. This task would be quite time consuming though and would result in more management in the long term. SO.. I would love to know if it's possible to modify within the code the sqlConnectionString used for SessionState, based upon a domain, before the session object is created? Can we inherit from System.Web.HttpApplication and use the Application_AcquireRequestState event to create the required setup of the HttpSessionState object?
Hopefully this makes sense and that someone can provide some pointers and prove to me that this isn't a pipe dream!
Cheers,
Steve
I think you are missing a big point--putting things in separate databases on the same server isn't going to help things at all if the bottleneck is sql server--it is either SQL running out of headroom or the network running out of bandwidth. I'd try and figure out which one it was before doing anything.
Your issue isn't so much that the connections to the database are bottlenecking, its that you are overwhelming the network connection to the database with data from all of the sessions.
By default, the Sql Server state provider simply serializes your data and ships it to the database. This is VERY inefficient and takes a LONG time to transfer on a fast network.
We solved this problem by going to a custom provider, like DOTSS that compresses session content before shipping it to the database. The compression rates we see are 80%-90% and the compression time is less than 10ms.
You can implement a custom session state provider. See MSDN for details. I've never done it, but with a little luck you can wrap the SqlServer session state module and redirect it based on the domain
First of all, I don't see there is advantage of "I would love to know if it's possible to modify within the code the sqlConnectionString used for SessionState, based upon a domain, before the session object is created" compared to set this in web.config.
Secondly, I think you need change that connection string setting in App_Start, so all the request will use that changed settings.Application_AcquireRequestState probably too late for this.
Why not split up the sites into sperate web applications and use hostheader to differentiate between the web sites. That way you could easily configure which session database you want your web application to use since each web application would have a seperate web.config file.
You could partition your session across different databases by implementing IPartitionResolver, and using a different partition for each domain.
Here's an example showing how to implement a custom partition resolver. (The example partitions by session ID, but it would be trivial to change it to partition by domain instead.)
We have several dozen development sites whose database connections are handled via the project's main Web.Config.
There is a separate configuration section corresponding to each URL on our intranet (e.g. http://development11, http://development12). We have SQL instances with a similar naming convention (DEVDB1\SQL1, DEVDB1\SQL2).
Based on the URL configured on the intranet IIS server, the app grabs the appropriate config. For testing we can easily modify the user, the database server or individual databases utilized for a particular site.

Resources