简体   繁体   English

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

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

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 . 但是我只会在服务器上的每个请求中得到null ,而不是本地调试。

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 我的服务器在Windows Server 2012 R2中使用IIS 8.5

Update1 更新1

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 . 如果我向Action发送请求,则每次都会发生null,因为我可以使用log4net看到它。

I already disable Idle time out and free time out, all set to 0 . 我已经禁用了空闲超时和空闲超时,它们都设置为0 So there is no recycle problem. 因此,没有回收问题。

This is my Global.asax: 这是我的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 更新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) : 在服务器上,log4net将在每个请求(访问操作)时将其输出:

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 测试:null,这次将设置

Update3 更新3

For some friends advice I put some code in the Application_Start() 对于一些朋友的建议,我在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: 现在,log4net的每个请求都将输出如下:

Test: Test 测试一下

Now the Test new Value = Test3 现在测试新值= Test3

Test: Test 测试一下

Now the Test new Value = Test3 现在测试新值= Test3

Test: Test 测试一下

Now the Test new Value = Test3 现在测试新值= 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 . 我希望可以在整个应用程序域中读取和修改静态属性,而不仅仅是1次。

After discussion with George Stocker and Dave Becker , And keeping debug it. George StockerDave Becker讨论之后,并对其进行调试。 And finally find the problem source is: just because I create the log4net log file into the website "Bin" folder . 最后找到问题的根源是:仅因为我将log4net日志文件创建到网站的“ Bin”文件夹中 then when every request come in, log4net write the log, and IIS detect there is some file changed, then The Application_End() will execute. 然后,当每个请求进入时,log4net写入日志,并且IIS检测到某些文件已更改,然后将执行Application_End()。 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. 如果您有相同的问题,请不要将每个文件都放置或创建任何文件到“ Bin”文件夹中,也不要尝试将其写入。 Unless you want application destroyed you can do it :-) 除非您希望销毁应用程序,否则可以做到这一点:-)

It sounds like you want a global variable in ASP.NET MVC. 听起来您想要在ASP.NET MVC中使用全局变量。 Luckily your problem has already been solved with this Stack Overflow question . 幸运的是,这个Stack Overflow问题已经解决您的问题。

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 ? 那么,您在哪里设置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: 一个很好的地方是位于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; }
}

Controllers are instantiated on every request; 在每个请求上实例化控制器; the Application_Start method is called once per App Pool Recycle (or once per instantiation of the Application). 每个App Pool Recycle(或每个Application实例一次)调用Application_Start方法。

The reason your Tests.Test is null is that you never set its value. 您的Tests.Test为null的原因是您从未设置其值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET MVC5-可空模型属性在编辑模型时始终丢失其值(空) - ASP.NET MVC5 - Nullable model property always losing its value (null) when editing model Session 值返回 null 在 mvc5 asp.net - Session value returned null in mvc5 asp.net Asp.net MVC5 Application_Start每个请求都发生-有时每个请求多次 - Asp.net MVC5 Application_Start happens every request - sometimes multiple times per request 在调用Application_Start()之后,Asp.Net MVC应用程序属性始终为null - Asp.Net MVC application Property is always null after Application_Start() is called Asp.net MVC 2 Request.files [“”]始终返回null - Asp.net MVC 2 Request.files[“”] return null always ASP.net mvc5 每 7 天发送一次电子邮件? - ASP.net mvc5 sending email every 7 day? 从数据库中检索图像并将其设置为asp.net mvc5中的background-image属性css - Retrieve image from database and set it to background-image property css in asp.net mvc5 C#/ ASP.NET MVC:我设置了属性的值,但它仍然为null - C#/ASP.NET MVC: I set the property's value, but it's still null 值不能为空。 参数名称:项目(在下拉列表中)ASP.NET MVC5 - Value cannot be null. Parameter name: items (in Dropdown List) ASP.NET MVC5 System.ArgumentNullException:值不能是 null ASP.NET MVC5 - System.ArgumentNullException: Value cannot be null ASP.NET MVC5
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM