Search code examples
asp.netwebformsglobal-variables

Global or accesing global variable datetime string dynamically in web form application using Visual Studio 2022


I've searched an answer to how to make a variable global in a web form application but can not get the correct answer.

I have a simple app with a datepicker and when date changed I store it in a string variable (var_date) - at the same time I navigate to a new page (selectedDate). I would like to get the date-string-variable accessible to the new page. How do I accomplish that?

I've tried the global.asax approach that is working fine, but how do I assign a new variable-value dynamically?

My markup for Site.Master:

<body>
    <form runat="server">
        <!-- Nav bar -->
        <div class="top-nav">
            <a runat="server" href="~/">SMT</a>

            <div class="right-nav">
                <input class="date-input" type="date" runat="server" id="datePicker1" onchange="handler(event);">
            </div>
        </div>
        <script>
            function handler(e) {
                var_date = e.target.value;
                window.location.href = "selectedDate";
            }
        </script>
    </form>
</body>

My code for Global.asax.cs:

    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
        RouteConfig.RegisterRoutes(RouteTable.Routes);

        Application.Lock();
        Application["var_date"] = "2024-03-23";
        Application.UnLock();
    }

Solution

  • In web land, there is no concept of global variables. Once a page is sent to the client, then on server side, the page, the page class, the variable(s) are disposed of, destroyed, removed from memory, and NOW the web server is ready to accept and process a page from ANY other user.

    You have to think of a web server as a single computer. And you have to accept and adopt the term called state-less. That term means that the server is starting in effect from scratch each time a web page is loaded, the code behind page class is created, and then the code runs, and the web page is then sent back to the client side. On server side, it does not maintain a copy of that page in memory, (nor the values of variables in code). So, now the web server is just sitting idle waiting for the next post-back of a web page in which the page life cycle starts again.

    So, the web server only deals with and works with the one page + code behind at a time. Once that page is processed, then all that code, and page is tossed out of memory and does not exist on the server anymore.

    And you can't use application start, since that ONLY runs when the web server is started, not for each user. That event will thus probably only run what, once every month or week if you are lucky. So application start is a "one time" event that occurs when the web site starts up, not when a user visits or logs on the site.

    So, then, how does one pass "values" from one page to the next?

    Well, at one time the "most" common way was to pass the value(s) in the URL. Then when the next page loads, it can grab such values from the URL.

    Of course, for "general" variable and values, that makes for a VERY messy and poor looking URL.

    However, while the web pages don't persist and stay in memory? For each user, you can use session[] to maintain values (persist them between page post-backs), and you can also use session[] to pass values to the next page in question.

    So, then, on page one we might drop in a text box (with textmode = date for a built-in date picker).

    Then below, we have a button, and when clicked on, we run server-side code, save the date value into session, and then navigate to say page 2. Once the value is placed into session[], then that value will persist and remain valid for that one user while they are on the site. If they logoff, or leave the site, then session[] will timeout and those values will then go out of scope.

    Hence this:

    WebForm1.aspx

            <h3>This is Webform1.aspx</h3>
            <h3>Please select a date</h3>
    
            <asp:TextBox ID="txtDate" runat="server"
                TextMode="Date">
            </asp:TextBox>
            <br />
            <br />
            <asp:Button ID="cmdContinue" runat="server" Text="Continue to page 2"
                OnClick="cmdContinue_Click" />
    

    And code behind for above is this:

        protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    
        protected void cmdContinue_Click(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Parse(txtDate.Text);
    
            Session["MyDate"] = dt;
            Response.Redirect("WebForm2.aspx");
        }
    

    And for WebForm2.aspx, we have this markup:

            <h3>This is WebForm2.aspx</h3>
            <br />
            <h3 id="myheading" runat="server"></h3>
    

    And code behind is this:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                DateTime dt = (DateTime)Session["MyDate"];
                myheading.InnerText = dt.ToString("D");
            }
        }
    

    And the result is thus this:

    enter image description here

    So, session is global to the ONE current user. Thus, each user has/gets their own session, and that's thus a good choice if you looking to persist some date value for a given user.

    If you looking to have some special date that applies to all users? Say maybe you have to set some "season" or say some school term date that applies to all users?

    Then I would use a database, and have an "admin" like page in which you can set the date, save to the database and then now all users of the site can work from that date, and when you need that date, you have to pull that date from the database.

    So, it is not clear if you looking to set a system wide date value for everyone, or you looking for each user to be able to set their own date, or say perhaps you want to assign some date to a given logged on user that remains "in use" as long as the user is logged on?

    So, session is per user.

    You can consider viewstate, but that is "per page" persisting.

    And you can consider saving the date in a database if this is say some tour season or school term type of date that some administrator of the site would setup.

    And you can use the application object, and that setting would be global to all users.

    So, using the above code, but using application object, then your code would/could be this:

            Session["MyDate"] = dt;
            Application.Lock();
            Application["MyDate"] = dt;
            Application.UnLock();
    
            Response.Redirect("WebForm2.aspx");
    

    And in the target page, then this:

                DateTime dt = (DateTime)Application["MyDate"];
                myheading.InnerText = dt.ToString("D");
    

    I never been that keen on using Application for storing values, since any re-start of the app-pool or site and those values are lost.

    And even if you using a master page, then tag the part of the menu or element with a runat="server", and add a "id" to the markup like I did for the "h3" element.

    Then in the master page load event, you can use the above like code to get the value from Application and display that value into that given element.

    You of course can't set session, or Application values from client side JavaScript, so in near all cases, you want to use a simple button and code behind to save the selected value as I done above.

    And if you need to display such values on any web page, then use the forms "load" event, and grab the Application["SomeName"] into a casted variable, and then that form's load event is free to display such values into any control or element on that page.