2

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 .

qakmak
  • 1,287
  • 9
  • 31
  • 62
  • 2
    What's the static constructor look like? Does this 'null' happen every time? Or is it after the code is running and the App Pool times out? What does your Global ASAX look like that the static constructor is in? Where are you setting the static property? In a request? Are you also setting it in the global ASAX? – George Stocker Feb 09 '15 at 13:34
  • 1
    @GeorgeStocker, don't put on hold it please. I already update my question. – qakmak Feb 09 '15 at 14:04
  • It's on hold because it's unclear what you're asking. "I will set it every time, because I use this code, So don't worry about it." Is not a valid problem statement. When I attempted to let you know what your problem was, you're coming back and saying "It's not a problem." That's why it's on hold: It's very unclear what you're asking us for help with. – George Stocker Feb 09 '15 at 14:06
  • If you can edit the question to state exactly what your problem is; that'd be helpful. If your problem is that the value isn't set on every request, the answer is to set it in your global.asax.cs on Application_Start. – George Stocker Feb 09 '15 at 14:06
  • @GeorgeStocker, So I post the code together, I warry you don't belive I debug it, right. Why it still not clear? – qakmak Feb 09 '15 at 14:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/70574/discussion-between-qakmak-and-george-stocker). – qakmak Feb 09 '15 at 14:10
  • It sounds like you want a global mutable singleton. Is that what you want? – George Stocker Feb 09 '15 at 15:03
  • @GeorgeStocker, Yes, But I also want to know why the static property can't modify by other request. because I saw alot of place said: the static class will blone the whole application domain. I also want a answer. – qakmak Feb 09 '15 at 15:05

2 Answers2

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 :-)

Community
  • 1
  • 1
qakmak
  • 1,287
  • 9
  • 31
  • 62
0

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.

Community
  • 1
  • 1
George Stocker
  • 57,289
  • 29
  • 176
  • 237
  • I will set it on every request. because I already told you I have log4net. I will update my problem. – qakmak Feb 09 '15 at 13:55
  • @qakmak What does Log4Net have to do with your static class? If you set the value in the Global, it'll be there when your request spins up. I feel like you're leaving out some important detail that will allow all of this to make sense. – George Stocker Feb 09 '15 at 13:59
  • log4net for display the debug info. believe me If I know it, I will not waste my 2 days for this.... – qakmak Feb 09 '15 at 14:02