[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Passing Session Variables to a Web User Control using C#

Posted on 2006-04-19
7
Medium Priority
?
2,207 Views
Last Modified: 2012-06-27
I have a C# web app with a textbox and some buttons on the main form.
There is also some Web User Controls on the form.
I'm trying to take the text that is in the texbox, put it in session scope, pass it to one of the Web User Controls, and display it in the user control.
It seems like a trival task but I can't seem to get the session variable to display on the web user control.
Could someone tell me how to pass a session variable from a main form to the web user control?
Any advice would be grately appreciated.


Here is the C# code:

index.aspx
======================================
<%@ Register TagPrefix="uc1" TagName="ucNeighborhood" Src="ucNeighborhood.ascx" %>
<%@ Register TagPrefix="uc2" TagName="ucLTAV" Src="ucLTAV.ascx" %>
<%@ Register TagPrefix="uc3" TagName="ucRatioStudy" Src="ucRatioStudy.ascx" %>
<%@ Register TagPrefix="uc4" TagName="ucFindProperty" Src="ucFindProperty.ascx" %>
<%@ Page language="c#" Codebehind="index.aspx.cs" AutoEventWireup="true" Inherits="MLS.frmMLS" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
      <HEAD>
            <title>WebForm1</title>
            <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
            <meta content="C#" name="CODE_LANGUAGE">
            <meta content="JavaScript" name="vs_defaultClientScript">
            <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
      </HEAD>
      <body>
            <form id="frmMLS" method="post" runat="server">
                  <table id="tblMain" style="MARGIN-LEFT: 8px" cellSpacing="0" cellPadding="0" width="100%" border="1">
                        <tr>
                              <td width="300">&nbsp;</td>
                              <td width="150">&nbsp;</td>
                              <td width="150">&nbsp;</td>
                              <td width="150">&nbsp;</td>
                              <td>&nbsp;</td>
                        </tr>
                        <tr>
                              <td align="center" colSpan="5">&nbsp;<asp:label id="lblTitle" runat="server" Width="112px" Font-Bold="True">MLS Reports</asp:label></td>
                        </tr>
                        <tr>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                        </tr>
                        <tr>
                              <td>&nbsp;<asp:label id="lblSubID" runat="server" Width="128px">Subject Property ID</asp:label></td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                        </tr>
                        <tr>
                              <td>&nbsp;<asp:textbox id="txtSubjectPropertyID" runat="server" Width="272px"></asp:textbox></td>
                              <td>&nbsp;<asp:button id="cmdNeighborhood" runat="server" Text="Neighborhood"></asp:button></td>
                              <td>&nbsp;<asp:button id="cmdAV" runat="server" Text="Sales LT AV"></asp:button></td>
                              <td>&nbsp;<asp:button id="cmdRatio" runat="server" Text="Ratio Study"></asp:button></td>
                              <td>&nbsp;</td>
                        </tr>
                        <tr>
                              <td>&nbsp;<asp:button id="cmdFindProperty" runat="server" Text="Find Subject Property ID"></asp:button></td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                        </tr>
                        <tr>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                              <td>&nbsp;</td>
                        </tr>
                        <tr>
                              <td colSpan="5">
                                    <uc1:ucNeighborhood id="UcNeighborhood" runat="server" Visible="False"></uc1:ucNeighborhood>
                                    <uc2:ucLTAV id="UcLTAV" runat="server" Visible="False"></uc2:ucLTAV>
                                    <uc3:ucRatioStudy id="UcRatioStudy" runat="server" Visible="False"></uc3:ucRatioStudy>
                                    <uc4:ucFindProperty id="UcFindProperty" runat="server" Visible="False"></uc4:ucFindProperty>
                              </td>
                        </tr>
                  </table>
            </form>
      </body>
</HTML>




index.aspx.cs
====================================================
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace MLS
{
      /// <summary>
      /// Summary description for WebForm1.
      /// </summary>
      public class frmMLS : System.Web.UI.Page
      {
            public System.Web.UI.WebControls.TextBox txtSubjectPropertyID;
            protected System.Web.UI.WebControls.Label lblTitle;
            protected System.Web.UI.WebControls.Label lblSubID;
            protected System.Web.UI.WebControls.Button cmdNeighborhood;
            protected System.Web.UI.WebControls.Button cmdAV;
            protected System.Web.UI.WebControls.Button cmdRatio;
            protected System.Web.UI.WebControls.Button cmdFindProperty;

            protected ucNeighborhood UcNeighborhood;
            protected ucLTAV UcLTAV;
            protected ucRatioStudy UcRatioStudy;
            protected ucFindProperty UcFindProperty;
      
            private void Page_Load(object sender, System.EventArgs e)
            {
                  // Put user code to initialize the page here
                  Session["subjectPropertyID"] = "";
            }

            #region Web Form Designer generated code
            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();
                  base.OnInit(e);
            }
            
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {    
                  this.cmdNeighborhood.Click += new System.EventHandler(this.NeighborhoodEngage);
                  this.cmdAV.Click += new System.EventHandler(this.LTAVEngage);
                  this.cmdRatio.Click += new System.EventHandler(this.RatioEngage);
                  this.cmdFindProperty.Click += new System.EventHandler(this.FindPropertyEngage);
                  this.Load += new System.EventHandler(this.Page_Load);

            }
            #endregion

            private void NeighborhoodEngage(object sender, System.EventArgs e)
            {
                  // set visibility
                  UcNeighborhood.Visible = true;
                  UcLTAV.Visible = false;
                  UcRatioStudy.Visible = false;
                  UcFindProperty.Visible = false;
                  // *** the 2 lines below work fine on this page (index.aspx.cs) ***
                  //Session["subjectPropertyID"] = txtSubjectPropertyID.Text.ToString();
                  //Response.Write(txtSubjectPropertyID.Text.ToString());
                  
            }

            private void LTAVEngage(object sender, System.EventArgs e)
            {
                  // set visibility
                  UcNeighborhood.Visible = false;
                  UcLTAV.Visible = true;
                  UcRatioStudy.Visible = false;
                  UcFindProperty.Visible = false;
                  Response.Write(txtSubjectPropertyID.Text.ToString());
            }

            private void RatioEngage(object sender, System.EventArgs e)
            {
                  // set visibility
                  UcNeighborhood.Visible = false;
                  UcLTAV.Visible = false;
                  UcRatioStudy.Visible = true;
                  UcFindProperty.Visible = false;
                  Response.Write(txtSubjectPropertyID.Text.ToString());
            }

            private void FindPropertyEngage(object sender, System.EventArgs e)
            {
                  // set visibility
                  UcNeighborhood.Visible = false;
                  UcLTAV.Visible = false;
                  UcRatioStudy.Visible = false;
                  UcFindProperty.Visible = true;
                  Response.Write(txtSubjectPropertyID.Text.ToString());
            }




      }
}




ucNeighborhood.ascx
==========================================================
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="ucNeighborhood.ascx.cs" Inherits="MLS.ucNeighborhood" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
This is the Neighborhood user control.<br>
<asp:Label id="lblPropertyID" runat="server"></asp:Label>


ucNeighborhood.ascx.cs
===========================================================
namespace MLS
{
      using System;
      using System.Data;
      using System.Drawing;
      using System.Web;
      using System.Web.UI.WebControls;
      using System.Web.UI.HtmlControls;
      using System.Web.SessionState;
      

      /// <summary>
      ///            Summary description for ucNeighborhood.
      /// </summary>
      public class ucNeighborhood : System.Web.UI.UserControl
      {
            protected System.Web.UI.WebControls.Label lblPropertyID;

            private void Page_Load(object sender, System.EventArgs e)
            {
                  // Put user code to initialize the page here
                  lblPropertyID.Text = Session["subjectPropertyID"].ToString();
                  Response.Write(Session["subjectPropertyID"].ToString());
            }

            #region Web Form Designer generated code
            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();
                  base.OnInit(e);
            }
            
            /// <summary>
            ///            Required method for Designer support - do not modify
            ///            the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  this.Load += new System.EventHandler(this.Page_Load);

            }
            #endregion
      }
}


0
Comment
Question by:FastEddie___
  • 3
  • 2
  • 2
7 Comments
 
LVL 13

Accepted Solution

by:
dungla earned 500 total points
ID: 16494698
You should have a public property in your user control to receive the value of Session from main page:
ucNeighborhood.ascx.cs
=================
private string msubjectPropertyID;
///<summary>
/// write-only property
///</summary
public string subjectPropertyID
{
set ( msubjectPropertyID = value;}
}
 private void Page_Load(object sender, System.EventArgs e)
          {
               // Put user code to initialize the page here
               lblPropertyID.Text = msubjectPropertyID;
               Response.Write(msubjectPropertyID);
          }

========== index.aspx.cs =============
private void NeighborhoodEngage(object sender, System.EventArgs e)
          {
               // set visibility
               UcNeighborhood.Visible = true;
               UcLTAV.Visible = false;
               UcRatioStudy.Visible = false;
               UcFindProperty.Visible = false;
               // *** the 2 lines below work fine on this page (index.aspx.cs) ***
               //Session["subjectPropertyID"] = txtSubjectPropertyID.Text.ToString();
               // sets value of subjectPropertyID
               UcNeighborhood.subjectPropertyID = txtSubjectPropertyID.Text;
          }
0
 

Author Comment

by:FastEddie___
ID: 16499109
Hi dungla,

I folowed your instructions but it did not work. I got no errors but also no display of the string typed into the textbox.
However when I clicked on the other buttons I did see the textbox string at the top of the page from the response write method.
So the response write did work but did not initially show up when I clicked on the "Neighborhood" button.
And the assignment of the subjectPropertyID to the lable :
    lblPropertyID.Text = msubjectPropertyID;
did not work at all.

This seems a little funny to me. If the session variable has already been set then why can't the web user control just use it directly?

The user control is being displayed but without the session variable. For example on the ucNeighborhood.ascx there is text that says:
     "This is the Neighborhood user control.<br>"
That text is showing up including the break character when I click on the neighborhood button but for some reason I'm not able to
display the session variable that is on the next line. This is very wiered to me.

Have you got any other suggestions?

I do appreciate your input.

-Eddie



0
 

Author Comment

by:FastEddie___
ID: 16499501
Oh one more thing to note. This code works fine:

   lblPropertyID.Text="ggggggggg"

This code does not:

    lblPropertyID.Text=Session["subjectPropertyID"].ToString();

So the web user control is there and it is made visible and invisible correctly
however when I try to use a session variable within the code it chokes.



0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 12

Assisted Solution

by:AGBrown
AGBrown earned 500 total points
ID: 16499937
Try doing this in dungla's code, it should then update the label text each time that you reset the property:
      
    public string subjectPropertyID
    {
        set ( lblPropertyID.Text=msubjectPropertyID = value;}
    }

Of course, if you don't need to store the label text, you could just do

    public string subjectPropertyID
    {
        set ( lblPropertyID.Text = value;}
    }

Does the code "choke" with an exception when you do "lblPropertyID.Text=Session["subjectPropertyID"].ToString();". Could you try and do this instead:
    lblPropertyID.Text=HttpContext.Current.Session["subjectPropertyID"].ToString();

Related to that last comment, I'll go into Session in a bit more detail. Bear with me if you know this already. I'm not sure I agree with the bit about "passing session through a property". It isn't necessary once you understand what Session is and how it works: Session is a "state bag" exposed by the ASP.NET runtime to _all_ code that is running inside the runtime.

If you store something in the Session, any control/class/page/anything can get to it by using the line
    HttpContext.Current.Session["key"] = "value"; (and the opposite to read instead of write)

The System.Web.UI.Page class, which all pages are based on exposes a property called Session which is simply a quick way of getting to HttpContext.Current.Session. It is nothing other than:
    protected HttpSessionState Session
    {
        get { return HttpContext.Current.Session; }
    }
In fact, you can put this exact property into your own classes and controls to make it "easier" to get to the session state.

The point of Session, ApplicationState and Cache are that they are state-persistence stores that are accessible from _all_ objects in the ASP.NET runtime. If you look at the inner workings, then you will see that behind the scenes they are all in fact very inter-related. The differences are that:
1) ApplicationState is available to all user sessions in the application domain on one server.
2) SessionState is (effectively, without explaining how) specific to each user.
3) Cache is like ApplicationState, but has timed expiry for objects (Session is in fact stored using Cache - that's why it expires, unless you lengthen its lifetime in the config files, 20 minutes after it's last access).

To re-emphasise, none of these are specific to any particular page or control. They are accessible from any of your code running in ASP.NET.

This means that you don't have to "pass" them around. To get access to the session state from a page you can use Session. But really you are using HttpContext.Current.Session. So inside a control, or any other class, using HttpContext.Current.Session will give you access to the same "state bag" as using "Session" on a page.

So this brings us to the issue of what you need to achieve. If you are storing values that are specific to a user and that you need to store between postbacks from the client, you use Session. To pass values to and from a control you shouldn't be using Session at all as you are taking up unnecessary server memory and opening yourself up to coupling between classes. Instead you should use a public property to pass the values (as dungla says). You can use a combination of the two to both store and pass values; as dungla showed, you can use the property to pass the value to the control. Using properties to pass values ensures your code always works. Imagine a page that does this:

Session["myKey"] = "aValue";

and a control that does this:

lblMyLabel.Text = Session["myKey"].ToString();

What happens when a well-meaning developer mis-spells the control's line as "Mykey" , or changes "myKey" to something more meaningful and misses the bit in the control which gets the value of myKey from the session. There is no compile-time error to prevent the code from being released, so it can easily get to production.

Instead you should do:
    Session["myKey"] = "value I Want To Store For The Next Postback"; // single point of storage for the session key in all your code
    myControl.MyProperty = Session["myKey"]; // single point of read for the session key in all your code

...with the MyProperty property doing something like we have covered already:

    public string subjectPropertyID
    {
        set ( lblPropertyID.Text=msubjectPropertyID = value;}
    }

If you need to get the value of Session["myKey"] from more than one page, consider implementing a property class with static properties for each session key.
public class SessionProperties
{
    public static string myKey
    {
        get
        {
            return Session["myKey"];
        }
        set
        {
            Session["myKey"] = value;
        }
    }
}

Or, if that is too cumbersome, at least have a central class that defines the keys as constants:
public class SessionKeys
{
    const string SESSION_MY_KEY = "myKey";
}
... page code:
Session[SessionKeys.SESSION_MY_KEY] = "value";

Things like that will help prevent hard-to-find problems in your code later on.

So, after all that, did the suggestions at the top of the post help at all? ;-)

Andy
0
 

Author Comment

by:FastEddie___
ID: 16500391
It helped in that I have a better understanding of how the app should be coded in situations where session and user control properties are mixed. However as you stated, the session scope can be accessed from any location and should not need any special consideration for user controls.

I figured out the problem. I was setting the session to nothing "" on the PageLoad event when it should have been set to nothing in the     if (!IsPostBack)     section only. After I made the change I was able to access the session variable with :

      lblPropertyID.Text=Session["subjectPropertyID"].ToString();

No need for the "HttpContext.Current" prefix but that is good to keep in mind for future reference.

I realize that session is problably not the most effecient way of doing this but it is used only for one variable and it just makes persistence so easy. The app is basically taking a variable and performing differnent types of operations on it. One type of operations per user control. I'm sure that with more expierence I'll be able to find better ways to modularize my code but for now user controls seem to work just fine. I do hate using session when the user control is on the same page though. Oh well...

I'd like to split these points with you and dungla. Now I've got to figure out how to do that.   :-)

Thanks a bunch for your help.




0
 
LVL 12

Expert Comment

by:AGBrown
ID: 16500443
In addition to your statement about persistence, and my rhetoric ;) about state persistence. You may want to go with ViewState to store this calculation variable. Try opening your app, and going to the place where that variable is first created. Then spawn a new Internet Explorer window from the window you are using through File, New Window. Now use the first window to go half way through the variable modification workflow. Now go back to the other window, it will access the same session, so may mess things up for you if it tries to modify the same variable.

ViewState is the state bag to use if you need to store the state of a particular workflow represented by page instances. SessionState helps you store central information that is used by all pages for a user session, and that can be modified by any page in any order without bad effects.

A
0
 
LVL 13

Expert Comment

by:dungla
ID: 16504127
Thanks AGBrown for correct the answer :)

-D
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses
Course of the Month19 days, 4 hours left to enroll

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question