Forum Discussion
Session values lost on switching server with statesession in asp.net webform with webfarm blue/green
Can you please share the custom solution herehttps://pintdd.com/pengunduh-gambar-pinterest/?lang=id I also trying something relevant, If I add this feature in my project so it would put great impact.
I would be thankful to you.
Regards
MarioElian Yes, here's my final solution and it work great in production.
As said earlier, you must make sure the basic configuration for webfarm are in place (same machine key, sessionState mode="StateServer"). Now your user will not lose his session while switching website instance. However, the value in his session will not transfer. To correct that problem you add the following code in your global.asax.
/// <summary>
/// Variable used to initialize the execution of code using reflection to correctly operate session
/// variables once (or a few times due to concurrency). The variable is static so its scope is for
/// the current application loaded in memory. When loading a new instance of the site (blue/green),
/// a new “instance” of the static variable is in memory and therefore the application will go
/// through reflection again to correctly initialize the session.
/// </summary>
private static bool hasInitializedApplicationName = false;
/// <summary>
/// This is a hack so that the values in the session variable are shared between the web sites
/// of a server farm. There is a configuration in the web.config called ApplicationName which
/// will be injected into the module that isolates session values (different if classic/integrated mode).
/// So, the first user(s) will modify this value in the module that is loaded so that sessions are
/// shared correctly for everyone.
/// *The value that is overwritten corresponds to a combination of the physical path of the website
/// and the site ID in IIS. For this to work without a hack, the second website must be on another
/// server with the same path AND the website must have the same ID. Quite fragile…”
/// </summary>
private void InitializeASPNETSession()
{
if (hasInitializedApplicationName)
return;
try
{
// Get the app name from config file...
string appName = ConfigurationManager.AppSettings["ApplicationName"];
if (string.IsNullOrEmpty(appName))
return;
foreach (string moduleName in this.Modules)
{
IHttpModule module = this.Modules[moduleName];
SessionStateModule ssm = module as SessionStateModule;
if (ssm == null)
continue;
FieldInfo storeInfo = typeof(SessionStateModule).GetField("_store", BindingFlags.Instance | BindingFlags.NonPublic);
SessionStateStoreProviderBase store = (SessionStateStoreProviderBase)storeInfo.GetValue(ssm);
if (store == null) //In IIS7 Integrated mode, module.Init() is called later
{
FieldInfo runtimeInfo = typeof(HttpRuntime).GetField("_theRuntime", BindingFlags.Static | BindingFlags.NonPublic);
HttpRuntime theRuntime = (HttpRuntime)runtimeInfo.GetValue(null);
FieldInfo appNameInfo = typeof(HttpRuntime).GetField("_appDomainAppId", BindingFlags.Instance | BindingFlags.NonPublic);
appNameInfo.SetValue(theRuntime, appName);
hasInitializedApplicationName = true; //We change the static variable here so the next calls avoid doing reflection. By the nature of the requests, it's possible that the code get exectuted multiple time but it's acceptable and will not cause side effect.
break;
}
else //IIS Classic and localhost debug IISExpress
{
Type storeType = store.GetType();
if (storeType.Name.Equals("OutOfProcSessionStateStore"))
{
FieldInfo uribaseInfo = storeType.GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic);
uribaseInfo.SetValue(storeType, appName);
}
hasInitializedApplicationName = true; //We change the static variable here so the next calls avoid doing reflection. By the nature of the requests, it's possible that the code get exectuted multiple time but it's acceptable and will not cause side effect.
break;
}
}
}
catch (Exception ex)
{
//Log the error
}
}
public override void Init()
{
base.Init();
InitializeASPNETSession();
}
That's it. I hope it help and save you some precious time.
- jf_ferlandMay 05, 2023Copper Contributor
You need to add the following setting in your web.config under appSettings to make everything work together
<appSettings> <add key="ApplicationName" value="WEBSITE_NAME" />