在 ASP.NET MVC5 上设置值后,静态 属性 在每个请求中始终为 null

Static property always null in every request after set value on ASP.NET MVC5

我有一个 static classstatic 属性

 public static class Test
 {
     public static string Tests { get; set; }
 }

现在的问题是,我在控制器中有一个动作

public ActionResult SomeActionInController(){
         ``              ``
     //  this place always execute in every request
     if (null == Test.Tests)
          Test.Tests = "some value";
         ``              ``
}

但我会在每个请求中得到 null,而不是本地调试,仅在服务器上

我看到很多人说:静态 属性 值将保留在整个应用程序域中,但为什么现在会发生这种情况?有什么办法可以解决吗?谢谢。

我的服务器使用 IIS 8.5Windows Server 2012 R2

更新1

静态class.

中没有静态构造函数

如果我向 Action 发送请求,每次都会发生 null,因为我可以看到它使用 log4net.

我已经禁用了Idle time out和free time out,都设置为0。所以不存在回收问题。

这是我的 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);
        }

    }

更新 2

我每次都会设置,因为我用的就是这段代码,所以不用担心。

       if (string.IsNullOrEmpty(Test.Tests))
                    {
                        log.Debug("Test: null, this time it will be setting");
                        Test.Tests = "Test";
                    }
                    else
                    {
                        log.Debug("Test: " + Test.Tests);
                    }

而在服务器上,log4net会在每次请求(访问动作)时输出它:

Test: null, this time it will be setting

Test: null, this time it will be setting

Test: null, this time it will be setting

更新3

为了一些朋友的建议我把一些代码放在Application_Start()

Test.Tests = "Test";

所以现在,每次请求它都会成功获取值。 但是我在行动中将我的代码更改为:

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);
                        }

现在 log4net 的每个请求都会像这样输出:

Test: Test

Now the Test new Value = Test3

Test: Test

Now the Test new Value = Test3

Test: Test

Now the Test new Value = Test3

但这不是我想要的。我希望静态 属性 可以在整个应用程序域中读取和修改,而不仅仅是 1 次。

听起来你想要在 ASP.NET MVC 中使用一个全局变量。幸好你的问题已经解决了with this Stack Overflow question.

静力学并不神奇。如果您不设置它们,它们将没有任何价值。

在您的控制器操作中,您正在检查它是否已设置(提示:如果您尚未设置,则未设置):

if (null == Test.Tests) 
{
    Test.Tests = "some value";
}

那你要在哪里设置Test.Tests?如果您希望为每个控制器操作设置它,您需要确保在该控制器操作 运行 时设置它。 global.asax.cs:

Application_Start 方法是个不错的地方
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; }
}

每次请求都会实例化控制器; Application_Start 方法在每次应用程序池回收时调用一次(或每次应用程序实例化时调用一次)。

您的 Tests.Test 为空的原因是您从未设置它的值。

George Stocker and Dave Becker讨论后,不断调试。最后找到问题的根源是:因为我将log4net日志文件创建到网站“Bin”文件夹。然后当每个请求进来时,log4net 写入日志,IIS 检测到有一些文件被更改,然后 Application_End() 将执行。都不见了。

非常感谢这两位朋友。

如果您有同样的问题,请不要每次都将任何文件放入或创建到“Bin”文件夹,或尝试写入它。除非你想要应用程序 destroyed 你可以这样做:-)