I have a static class and static property
public static class Test
{
public static string Tests { get; set; }
}
Now the problem is, I have a Action in a Controller
public ActionResult SomeActionInController(){
`` ``
// this place always execute in every request
if (null == Test.Tests)
Test.Tests = "some value";
`` ``
}
But I will get null in every requests, not local debug, only on the server.
I saw so many people said : Static property value will keeping on whole application domain, But why this is happening now ? Is there any way to fixed it? Thank you.
My Server use IIS 8.5 with Windows Server 2012 R2
Update1
There is no static constructor in the static class.
if I send request to the Action, the null will happen every time, because I can see it use log4net.
I already disable Idle time out and free time out, all set to 0. So there is no recycle problem.
This is my Global.asax:
public class MvcApplication : System.Web.HttpApplication
{
private readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(MvcApplication));
protected void Application_Start()
{
Elmah.Mvc.Bootstrap.Initialize();
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// Setting log4net
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(Server.MapPath("~/log4net.config")));
// Only keep Razor
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());
System.Threading.Tasks.Task.Factory.StartNew(new Action(() =>
{
try
{
System.Threading.Thread.Sleep(1000 * 100 * 1);
// Send a fake request for warm up the website, when after it recycle
WebClient webClient = new WebClient();
using (Stream stream = webClient.OpenRead(ConfigurationManager.AppSettings["InitialPath"]))
{
if (stream.CanRead)
{
log.Debug("Success warm up when recycle");
}
else
{
log.Debug("warm up failed");
}
}
}
catch (WebException ex)
{
log.Debug(ex);
}
catch (Exception ex)
{
log.Error(ex);
}
}));
}
/// <summary>
/// Setting Page Language
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current != null && HttpContext.Current.Session != null)
{
if (AdminLanguage == 1)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("xx-xx");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("xx-xx");
}
else
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("xx-xx");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("xx-xx");
}
}
}
/// <summary>
/// Cache setting
/// </summary>
/// <param name="context"></param>
/// <param name="arg"></param>
/// <returns></returns>
public override string GetVaryByCustomString(HttpContext context, string arg)
{
// cache from DevTrends.MvcDonutCaching
if (arg == "NavStatic")
{
return "NavStatic=" + HttpContext.Current.Session.SessionID;
}
return base.GetVaryByCustomString(context, arg);
}
}
Update 2
I will set it every time, because I use this code, So don’t worry about it.
if (string.IsNullOrEmpty(Test.Tests))
{
log.Debug("Test: null, this time it will be setting");
Test.Tests = "Test";
}
else
{
log.Debug("Test: " + Test.Tests);
}
And on the server, The log4net will output it when every request(access the action) :
Test: null, this time it will be setting
Test: null, this time it will be setting
Test: null, this time it will be setting
Update3
For some friends advice I put some code in the Application_Start()
Test.Tests = "Test";
So now, every request it will successful get the value.
But I change my code to this in Action:
if (string.IsNullOrEmpty(Test.Tests))
{
log.Debug("Test: null, this time it will be setting");
Test.Tests = "Test";
}
else
{
log.Debug("Test: " + Test.Tests);
Test.Tests = "Test3";
log.Debug("Now the Test new Value = " + Test.Tests);
}
Now every request the log4net will output like this:
Test: Test
Now the Test new Value = Test3
Test: Test
Now the Test new Value = Test3
Test: Test
Now the Test new Value = Test3
But that’s not what I want. I want the static property can be read and modify in whole application domain, not only 1 time .
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
After discussion with George Stocker and Dave Becker , And keeping debug it. And finally find the problem source is: just because I create the log4net log file into the website “Bin” folder. then when every request come in, log4net write the log, and IIS detect there is some file changed, then The Application_End() will execute. all gone.
Many thanks these 2 firends.
If you has a same problem, don’t every put or create any file to “Bin” folder, or trying to write it. Unless you want application destroyed you can do it 🙂
Method 2
It sounds like you want a global variable in ASP.NET MVC. Luckily your problem has already been solved with this Stack Overflow question.
Statics aren’t magical. If you don’t set them, they will have no value.
In your controller action, you’re checking to see if it’s set yet (hint: If you didn’t set it already, it’s not set):
if (null == Test.Tests)
{
Test.Tests = "some value";
}
So where are you setting Test.Tests? If you want it to be set for each controller action, you need to be sure it’s set when that controller action would run. A great place would be in your Application_Start method of your global.asax.cs:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
Tests.Test = "This is set";
}
}
public static class Tests
{
public static string Test { get; set; }
}
Controllers are instantiated on every request; the Application_Start method is called once per App Pool Recycle (or once per instantiation of the Application).
The reason your Tests.Test is null is that you never set its value.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0