C# where to instantiate object in code behind

I have not been able to figure out where to instantiate my object in code behind where I can access in the various postbacks routines.  if i put instantiate in the constructor it has scope but gets reset on each page load, if i put it in the various postback routines I have scope but not the data from the last post back.  On other web controls on postback I still can get the controls last state (s = dropdownlist.Selected.Item.Value...).  How is that done, how do I persist within the page between postbacks?

Thank You
Sam

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1.BusinessLogic
{
    public partial class InstantiateClass : System.Web.UI.Page
    {
        //Locks2 Locks = new Locks2(); // if instantiated here everybody on this page can scope it, but it gets cleared on postback, oops!
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Locks2 Locks = new Locks2();  // if instantiated  here it doesn't get wiped out, but others cannot scope it???
                TextBox1.Text = "Initial Value";
                Locks.RegistrationDate = TextBox1.Text;
                TextBox1.Text = Locks.RegistrationDate;
            }
        }
        protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            Locks2 Locks = new Locks2(); // if instantiated in both places it is a different instance from above so the data is not what was set above, oops!
            TextBox1.Text = Locks.RegistrationDate; // if this is null or "" at first I did not get above, or not "Initial Value"
            Locks.RegistrationDate = TextBox1.Text;
            TextBox1.Text = Locks.RegistrationDate;
        }
    }
}
//namespace WebApplication1.BusinessLogic
//{
//    public class Locks2
//    {
//        public string RegistrationDate
//        {
//            get
//            {
//                return m_RegistrationDate;
//            }
//            set //Dispose, this is for epert exchange question
//            {
//                m_RegistrationDate = value;
//            }
//        }
//        private string m_RegistrationDate;
//    }
//}

Open in new window

SamCashAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kyle AbrahamsSenior .Net DeveloperCommented:
See in example . . . you can use the session object to store or you add an else and Load the Locks when it's not a post back.

   
        Locks2 Locks;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Locks = new Locks2();  
                TextBox1.Text = "Initial Value";
                Locks.RegistrationDate = TextBox1.Text;
                TextBox1.Text = Locks.RegistrationDate;
            }
else 
{
//     Locks = //get locks from the page OR

    Locks = (Locks2) Session["Locks"];
}
        }

 protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            TextBox1.Text = Locks.RegistrationDate; // if this is null or "" at first I did not get above, or not "Initial Value"
            Locks.RegistrationDate = TextBox1.Text;
            TextBox1.Text = Locks.RegistrationDate;
            Session["Locks"] = Locks;
        }

Open in new window

SamCashAuthor Commented:
Kyle,

Thanks for the prompt response.  

I want to get from page.  I do not seem to be able to guess the syntax to do that?  Please provide the second half.  "Locks = //get locks from the page"

I am building up to that line.

Thanks Again
Sam

else 
{
//     Locks = //get locks from the page OR

    Locks = (Locks2) Session["Locks"];
}

Open in new window

Kyle AbrahamsSenior .Net DeveloperCommented:
protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            Locks2 Locks = new Locks2(); // if instantiated in both places it is a different instance from above so the data is not what was set above, oops!
            TextBox1.Text = Locks.RegistrationDate; // if this is null or "" at first I did not get above, or not "Initial Value"
            Locks.RegistrationDate = TextBox1.Text;
            TextBox1.Text = Locks.RegistrationDate;
        }

What is locks?  The above makes no sense.  What exactly are you trying to do?
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

SamCashAuthor Commented:
Kyle,

Locks is a Class which processes: 1.  League registration  deadline date, the setting of this date and comparison to determine weather or not registration is open or closed.
2.  It does the same for locking rosters based on different levels of hierarchy; Classes of Play, Conferences, Divisions and Teams.

Locks has accessors for set{} userID, entityID, and the lock dates; and get{} the lock dates and open or closed based on the client time and timezone.  This part all works (in test :-).  (ps for this question I made a new Class named Locks2, it is very simplified, but exposes my frustration.  Which is:...

I want to instantiate an object in my code behind
Locks2 Locks = new Locks2;

Open in new window

and be able to access its properties and methods throughout the code behind, ie have scope, in the various Events fired from the webpage.  Just like webcontrols, which I think are objects, like
protected void ddlTimezoneList_SelectedIndexChanged(object sender, EventArgs e) 

Open in new window

I can access its value with
x = ddlTimezoneList.Value;

Open in new window



I want to access my properties with
x = Locks.MyProperty; and Locks.MyProperty = y;

Open in new window

 This works, of course, but I am not able to get the property's value on postback.

When I instantiated in the constructor of my code behind I had scope in all the Event Routines, but it cleared each time the page loaded because of the "new", so all I got was nulls after the first time.  Your suggestion of
Locks Locks;

Open in new window

in the constructor and then instantiate it only on page load
if( !IsPostBack)

Open in new window

instead should give me scope in all the Event routines, yea.  Now if I can just, in the Event routines set a reference to the original instantiated object, I think we got it.  I think I could get the Session version you suggested working,
Locks = (Locks2) Session["Locks"];

Open in new window

but I do not think I will be allowed to use Session variables so I have not tried.  I want to get the other version you suggested working,
 //     Locks = //get locks from the page

Open in new window

, I am assuming "page" is the code behind?

My current work-around is;
1.  instantiating the object on every post back in the Event routine called,
2.  get the prior values from sql,
3.  set{} all the accessors,
4.  finally, get{} the values needed,
5.  save everything in sql for the next post back. Please laugh...

Sorry about the book.

Kind Regards
Sam
SamCashAuthor Commented:
Kyle,

After working and studying my problem over the weekend, I think I should have marked this as C# and Object Oriented Programming issue and not an Asp.Net or web issue.  I am new, but I think I need to use inheritance? I am learning the OOP model which seems powerful way to organize everything, I am beginning to understand the concepts but lack the skill (syntax and where) to implement them.

I hope this background may help you assist me.  Hope you had a good weekend.

Regards
Sam
ste5anSenior DeveloperCommented:
Well, ASP.NET plays a role: ASP.NET Page Life Cycle Overview

You have basically three methods to "persist" data between "page calls".

1. Storing the data in a database.

2. Caching the data (using ASP.NET): Session, Cache.
  ASP.NET Caching: Techniques and Best Practices

3. Storing the data in the actual page: ViewState
  Understanding ASP.NET View State

From your short description, you should evaluate whether you should cache those objects.
Kamal KhaleefaInformation Security SpecialistCommented:
try like this

 public partial class InstantiateClass : System.Web.UI.Page
    {
      Locks2 Locks ;//= new Locks2(); // if instantiated here everybody on this page can scope it, but it gets cleared on postback, oops!
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Locks2 Locks = new Locks2();  // if instantiated  here it doesn't get wiped out, but others cannot scope it???
                TextBox1.Text = "Initial Value";
                Locks.RegistrationDate = TextBox1.Text;
                TextBox1.Text = Locks.RegistrationDate;
            }
        }
Kyle AbrahamsSenior .Net DeveloperCommented:
Sam,

The easiest way to do what you're explaining is this:

After you set the properties of Locks . . . you MUST set it in the session.

Then use the else block in the page_load (which is called every time, post back or not) to set locks back to what it was in the session.

so for example:
protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            TextBox1.Text = Locks.RegistrationDate; // if this is null or "" at first I did not get above, or not "Initial Value"
            Locks.RegistrationDate = TextBox1.Text;
            TextBox1.Text = Locks.RegistrationDate;
   //save locks "as is" to session.
            Session["Locks"] = Locks;
        }

Open in new window


       Locks2 Locks;
        protected void Page_Load(object sender, EventArgs e)
        {

            if (!IsPostBack)
            {
               //if first time, use a new locks.
                Locks = new Locks2();  
                TextBox1.Text = "Initial Value";
                Locks.RegistrationDate = TextBox1.Text;
                TextBox1.Text = Locks.RegistrationDate;
                Session["Locks"] = Locks;
            }
else 
{
//restore locks to variable from session.
    Locks = (Locks2) Session["Locks"];
}

Open in new window

SamCashAuthor Commented:
Thanks All,

After reading about the pros and cons of the different solutions, I have implemented the ViewState technique (partially, I still have to figure out how to save it at the last picosecond).  I still have a lack of understanding of  OOP.  I am not able to scope the object in a called routine, SomeCode();, like i can in TextBox1_TextChanged(...)  see code below.  

Please what do I do to scope this object in SomeCode() without having to restore it from ViewState multiple times in the same post?  And is there an appropriate state in the page life cycle to save the ViewState which would be after the last change?

Best Regards
Sam

namespace WebApplication1.BusinessLogic
{
    public partial class InstantiateClass : System.Web.UI.Page
    {
        Locks2 Locks; //= new Locks2(); // if instantiated here everybody on this page can scope it, but it gets cleared on postback, oops!, 
                        //I thought getting rid of the "new" would make it a page variable
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Locks2 Locks = new Locks2();  // if instantiated  here it doesn't get wiped out, but others cannot scope it???
                TextBox1.Text = "Initial Value";
                Locks.RegistrationDate = TextBox1.Text;

                ViewState["Locks"] = Locks;  // save it for now, I think I have to save this after every changes, just before page unload??

                SomeCode();  //&&&&&&&&&&&&
            }
            else
            {
                Locks = (Locks2)ViewState["Locks"];
            }
        }

        protected void SomeCode()
        {
            Locks = (Locks2)ViewState["Locks"];  // There must be a way to get rid of this &&&&&&&&&&&&&&
            string nop = Locks.RegistrationDate;  // I lost scope here how do I keep it without the above line every time I reference this object other than Event routines
        }

        protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            // The  "Locks = (Locks2)ViewState["Locks"];" in PostBack portion of Page_Load gives scope here, why doesn't in SomeCode()??           
            Locks.RegistrationDate = TextBox1.Text;  // if Locks.RegistrationDate is null or "" at first I did not get above value, or not "Initial Value"
            TextBox1.Text = Locks.RegistrationDate;
        }
    }
}

Open in new window

SamCashAuthor Commented:
Added information,

I just added a call to SomeCode(); in the TextBox1_TextChanged(... routine and the object "Locks" maintained scope in SomeCode(); where it dose not when called from Page_Load(.., awwlkjhmhvggvvugg, I cannot see any difference, hmmmmm?

Thanks Again
Sam
Kyle AbrahamsSenior .Net DeveloperCommented:
You don't need to read from the viewstate in the first example because Locks is already in scope.  (I *believe* the viewstate is only available on a postback).

namespace WebApplication1.BusinessLogic
{
    public partial class InstantiateClass : System.Web.UI.Page
    {
        Locks2 Locks; //= new Locks2(); // if instantiated here everybody on this page can scope it, but it gets cleared on postback, oops!, 
                        //I thought getting rid of the "new" would make it a page variable
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                  // first time thru:
                  // instantiate a new locks object.

                Locks2 Locks = new Locks2();  // if instantiated  here it doesn't get wiped out, but others cannot scope it???
                TextBox1.Text = "Initial Value";
                Locks.RegistrationDate = TextBox1.Text;


               // locks is already created, SomeCode can use it.
                SomeCode();  

                // last thing you do on the page.  You only need to save it again if you modify it.
             
                ViewState["Locks"] = Locks;  
            }
            else
            {
              //note this is called before the textbox changed
              //Locks populated here, all other functions can use it.
                Locks = (Locks2)ViewState["Locks"];
            }
        }

        protected void SomeCode()
        { 
/*********** no need for Locks as it's read from page_load
//            Locks = (Locks2)ViewState["Locks"];  
// you can just use it.
// you lost scope because you were trying to read the viewstate when it didn't exist . . . doesn't happen on page != postBack.
            string nop = Locks.RegistrationDate;
        }

        protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            
            Locks.RegistrationDate = TextBox1.Text;  
            TextBox1.Text = Locks.RegistrationDate;

            //locks potentially modified, so save it.
            ViewState["Locks"] = Locks;  
        }
    }
}

Open in new window

SamCashAuthor Commented:
Kyle,

Thanks for the comment.

As usual as one works a problem it gets down to a couple of lines.  The loss of scope in SomeCode(){}?

Thanks Much
Sam

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1.BusinessLogic
{
    public partial class InstantiateClass : System.Web.UI.Page
    {
        Simple MyClass; //This reference is to have "page" scope
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Simple MyClass = new Simple();
                ViewState["MyClass"] = MyClass; //Save on Page_Unload? for postback
                
                string nop = MyClass.SimpleProperty;
                SomeCode(); //Called here no scope in SomeCode(){}, NullReferenceExecption: Object reference not set to an instance of an object. [comment this line out to get by here]
            }
            else
            {
                MyClass = (Simple)ViewState["MyClass"];  //Get it from last page
                string nop = MyClass.SimpleProperty;
                SomeCode(); //Called here has scope in SomeCode(){}
            }
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            string nop = MyClass.SimpleProperty;
            SomeCode(); //Called here has scope in SomeCode(){}
        }
        protected void SomeCode()
        {
            string nop = MyClass.SimpleProperty;  // MyClass has scope when called from anywhere on this page execpt if (!IsPostBack)
        }
    }
}
//namespace WebApplication1.BusinessLogic
//{
//    [Serializable()]
//    public class Simple
//    {
//        public string SimpleProperty
//        {
//            get
//            {
//                m_SimpleProperty = "Scoped";
//                return m_SimpleProperty;
//            }
//        }
//        private string m_SimpleProperty;
//    }
//}

Open in new window

Kyle AbrahamsSenior .Net DeveloperCommented:
in the (!PostBack)  Part:

Simple MyClass = new Simple();  // BAD LINE.

Correctly:
MyClass = new Simple();

Explanation:
You're already declared MyClass for the page

If you declare
Simple MyClass = new Simple();  

you're creating a new object with the same name, that's NOT the page variable.

Removing the "Simple" on the left (eg:  the correct line) says use the page variable.

My apologies for not correcting that before, I don't normally use a compiler when I post to these.  Didn't mean to make it more confusing for you.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
SamCashAuthor Commented:
Kyle, Ste5an,

From a couple of lines down to one word.  Delete one word and everything works.  

Thank you very much I have learned a lot as I researched many topics trying to solve this.  I much better understand the Page Life cycle (lots more to learn before I able to use it effectively), about View state, Caching, and Sessions.

Thanks Again
Sam
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.