在 ASP.NET MVC5 上设置值后,每个请求中的静态属性始终为 null [英] Static property always null in every request after set value on ASP.NET MVC5

查看:17
本文介绍了在 ASP.NET MVC5 上设置值后,每个请求中的静态属性始终为 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个静态类静态属性

 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";
         ``              ``
}

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

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.

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

My Server use IIS 8.5 with Windows Server 2012 R2

更新 1

静态类中没有静态构造函数.

There is no static constructor in the static class.

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

if I send request to the Action, the null will happen every time, because I can see it use log4net.

我已经禁用空闲超时和空闲超时,都设置为 0.所以不存在回收问题.

I already disable Idle time out and free time out, all set to 0. So there is no recycle problem.

这是我的 Global.asax:

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

    }

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

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

And on the server, The log4net will output it when every request(access the action) :

测试:null,这次会设置

Test: null, this time it will be setting

测试:null,这次会设置

Test: null, this time it will be setting

测试:null,这次会设置

Test: null, this time it will be setting

更新 3

对于一些朋友的建议,我在 Application_Start()

For some friends advice I put some code in the Application_Start()

Test.Tests = "Test";

所以现在,每个请求都会成功获取值.但是我在 Action 中将代码更改为此:

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

现在 log4net 的每个请求都会输出如下:

Now every request the log4net will output like this:

测试:测试

现在测试新值 = Test3

Now the Test new Value = Test3

测试:测试

现在测试新值 = Test3

Now the Test new Value = Test3

测试:测试

现在测试新值 = Test3

Now the Test new Value = Test3

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

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 .

推荐答案

George Stocker 讨论后和 Dave Becker ,并继续调试.最后找到问题根源是:只是因为我创建了log4net日志文件到网站Bin"中文件夹.然后当每个请求进来时,log4net 写日志,IIS 检测到有一些文件被更改,然后 Application_End() 将执行.都过去了.

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.

非常感谢这两位朋友.

如果你有同样的问题,不要每次都把或创建任何文件到Bin";文件夹,或尝试编写它.除非您希望应用销毁,否则您可以这样做:-)

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

这篇关于在 ASP.NET MVC5 上设置值后,每个请求中的静态属性始终为 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆