Get state of ASP.NET page life cycle - asp.net

I need the following functionality in my method: if the method is called before OnLoad event of ASP.NET life cycle throw an exception else continue execution of the method.
I was thinking of something like this:
if (Page.LifeCycleState < LifeCycleState.OnLoad) {
throw new InvalidPageStateException();
}
Is it possible to retrieve the state of ASP.NET page life cycle?

One approach would be to use a Basepage that you always use in your site. This would contain a variable called PageLoadComplete, which you would set at the end of your PageLoad event. Then you could check the state of this variable from within your method.
public abstract class BasePage : System.Web.UI.Page
{
public bool PageLoadComplete { get; private set; }
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
PageLoadComplete = true;
}
}
If you want to access the variable from code external to your page such as a UserControl, you would have to make it public and cast your page as BasePage.
public partial class MyUserControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
BasePage basePage = this.Page as BasePage;
if (basePage != null && !basePage.PageLoadComplete)
{
throw new InvalidPageStateException();
}
}
}

There is property in a realization of System.Web.UI.Control class(realization):
internal ControlState ControlState {
get { return _controlState; }
set { _controlState = value; }
}
Where ControlState is enum that contains members such as: Initialized, ViewStateLoaded, Loaded etc. here declaration
But as you can see this property is internal. So only way to get control state is proposed by Daniel Dyson.

You maybe able to find what you are looking for, by looking at the CurrentHandler and PreviousHandler properties of the current HttpContext.

if the method is called before OnLoad event of ASP.NET life cycle
throw an exception else continue execution of the method.
It is not clear which Onload event is meant, nor where the "method" resides. Is it the Page's Onload or a Control's OnLoad? Is it a Page's "method" or a Control's "method"?
Anyway, one can store sort of flag in the Context.Items Dictionary, which all controls (including Page) have access to during a request. This eliminates the need to use a general base page like suggested obove.
In the OnLoad method (no matter whether it is a Page's OnLoad or a Control's OnLoad):
Context.Items[UniqueID] = this;
In the "method":
if (Context.Items[UniqueID] != null)
{
throw new InvalidPageStateException();
}

Related

Call parent page function from user control

I have a Default.aspx page and I am using a usercontrol in it. On some condition in usercontrol.cs I have to invoke a function present in Default.aspx.cs page (i.e parent page of user control). Please help and tell me the way to do this task.
You have to cast the Page property to the actual type:
var def = this.Page as _Default;
if(def != null)
{
def.FunctionName();
}
the method must be public:
public partial class _Default : System.Web.UI.Page
{
public void FunctionName()
{
}
}
But note that this is not best-practise since you are hard-linking the UserControl with a Page. Normally one purpose of a UserControl is reusability. Not anymore here. The best way to communicate from a UserControl with it's page is using a custom event which can be handled by the page.
Mastering Page-UserControl Communication - event driven communication
Add an event to the user control:
public event EventHandler SpecialCondition;
Raise this event inside your user control when the condition is met:
private void RaiseSpecialCondition()
{
if (SpecialCondition != null) // If nobody subscribed to the event, it will be null.
SpecialCondition(this, EventArgs.Empty);
}
Then in your page containing the user control, listen for the event:
public partial class _Default : System.Web.UI.Page
{
public void Page_OnLoad(object sender, EventArgs e)
{
this.UserControl1.OnSpecialCondition += HandleSpecialCondition;
}
public void HandleSpecialCondition(object sender, EventArgs e)
{
// Your handler here.
}
}
You can change the EventArgs to something more useful to pass values around, if required.
parent.aspx.cs
public void DisplayMsg(string message)
{
if (message == "" || message == null) message = "Default Message";
Response.Write(message);
}
To Call function of parent Page from user control use the following:
UserControl.ascx.cs
this.Page.GetType().InvokeMember("DisplayMsg", System.Reflection.BindingFlags.InvokeMethod, null, this.Page, new object[] { "My Message" });
This works fine for me..
Try this
MyAspxClassName aspxobj= new MyUserControlClassName();
aspxobj.YourMethod(param);

can httphandler fire an event?

I want to check Session in some pages. To do this I am adding the page names which I want to check inside web.config as a appsetting key.
I want to use httpHandler with firing an event after it finds the session is empty or something else.
If I create httpHandler as a dll(another project) and add to a web site, can handler fire an event and web site capture it inside a web page?
What you can do is this:
Your HttpHandler puts a value in the HttpContext.Current.Items collection telling if there was Session or not. Something like
HttpContext.Current.Items.Add("SessionWasThere") = true;
You create a BasePage that checks that value in the Page_Load event and raises a new event telling so:
public abstract class BasePage : Page {
public event EventHandler NoSession;
protected override void OnLoad(EventArgs e){
var sessionWasThere = (bool)HttpContext.Current.Items.Add("SessionWasThere");
if(!sessionWasThere && NoSession != null)
NoSession(this, EventArgs.Empty);
}
}
In your page, you suscribe to that event:
public class MyPage : BasePage{
protected override void OnInit(){
NoSession += Page_NoSession;
}
private void Page_NoSession(object sender, EventArgs e) {
//...
}
}

Can i unsubscribe to an event of BasePage from a page which inherits from BasePage in asp.net

I have a BasePage having common functionality required by all pages. I have defined a PreRender() event on page base. There are 2-3 pages which does not require this functionality. Can i unsubscribe to PreRender() event of BasePage from my .aspx page. I tried casting BasePage to Page
(PageBase as Page).PreRender -= OnPreRender(new EventArgs());
but it says PageBase is a type but is used as a variable. How to achieve this. Please suggest.
I am adding PreRender() event as follows:
public PageBase()
{
this.PreInit += new EventHandler(PageBase_PreInit);
this.PreRender += new EventHandler(PageBase_PreRender);
}
Your example looks close. What if you try:
base.Page.PreRender -= new EventHandler(Page_PreRender);
This assumes you added the event using:
base.Page.PreRender += new EventHandler(Page_PreRender);
Another option is override the OnPreRender method in your BasePage and use a protected field to check if it should be done. For the three pages, set it to false:
protected bool _useMyCustomPreRender = true;
protected override void OnPreRender(EventArgs e)
{
if (_useMyCustomPreRender)
{
// do my logic here
}
base.OnPreRender(e);
}

How to handle master page button event in content page?

My problem is this I have a base page that creates content dynamically. There are buttons on my Master Page that fire events that my base page needs to know about. But the OnLoad function on my base page fires before my Button_Command function on my master page. So I either need to figure out a way to load my base page after the Button_Command function has had the chance to set a variable or I must call a function in my base page from the Button_Command function.
Have you considered using strongly typed master pages?
You can also check out my answer to this question.
I believe you can do this with an interface
public interface ICommandable
{
public void DoCommand1(object argument);
}
So the child page implements this interface
public class MyPage : Page, ICommandable
{
public void DoCommand1(object argument) {
}
}
And on the master page
public class Master : MasterPage
{
public void Button_Command(object sender, EventArgs e)
{
if (Page is ICommandable)
{
(Page as ICommandable).DoCommand1(myargument);
}
else
throw new NotImplementedException("The current page does not implement ICommandable");
}
}
It has been a long time since I worked with webforms however, so I can't swear that this works. I seem to recall writing something like this before.
Could you simply encapsulate the logic that is Button_Command into a public method and call that method both from the Button_Command event on the Master Page and from the Load event on the child page? So something like
protected void Page_Load( object sender, EventArgs e )
{
var master = (MyMaster)this.Master;
master.Foo();
}

Pass data to user components in asp.net

It is .net 2.0 here, not MVC, and I am crap at asp forms.
I have a page with user controls on it. When I click on something in the page, I want to load the usercontrol based on a parameter from the page.
I cannot do it.
In my page's FaultTree_Clicked, I get the value, then:
I tried exposing a property on the
child user control to set the value, which i set in FaultTree_Clicked,
it gets forgotten.
I tried saving it to
Session["mykey"], and loading
Session["mykey"] in the control's
Page_init... the value is blank.
I tried saving it to
ViewState["mykey"], and loading
ViewState["mykey"] in the control's
Page_init... the value is blank.
EDIT: more specific info:
Here is a cut down version of what the page(MyFault) looks like:
<form id="form" runat="server">
<div id="faulttree">
<asp:TreeView ID="FaultTree" ......>
</div>
<uc1:_DefectDetail ID="DefectDetail" runat="server" Visible="true" EnableViewState="true" />
</form>
And there is a method on the pages code behind "FaultTree_SelectedNodeChanged()".
When that method is hit, I want to load/show the DefectDetail control. The DefectControl requires a faultid, which comes off the Tree, which I successfully get in the SelectedNodeChanged method. I cannot get the faultid into the defect control.
This has to do with ASP.NET page lifecycle. By the time the click event fires, the control's init event has already happened.
In order to better assist you, please provide a more detailed explanation of what the FaultTree control is, what is the desired result and some sample code.
UPDATE:
Instead of a public property, you can simply create a public method in the control that does the desired action and invoke it from the FaultTree_SelectedNodeChangeEvent.
Example (for a public method named Refresh):
_DefectDetail.Refresh(object data);
Basically you have to use EventHandlers....
1. Add a event handler to your user control (I had a search bar UscSearchCriteriaBar1)
public event EventHandler CriteriaChanged;
+
private void InternalOnCriteriaChanged()
{
OnCriteriaChanged();
}
+
protected virtual void OnCriteriaChanged()
{
// If there are registered clients raise event
if (CriteriaChanged != null)
CriteriaChanged(this, EventArgs.Empty);
}
+
Example
public int EmployeeID
{
get
{
f (Session["EmployeeID"] != null)
{
ViewState["EmployeeID"] = Convert.ToInt32(Session["EmployeeID"]);
}
if (ViewState["EmployeeID"] == null)
ViewState["EmployeeID"] = 0;
return int.Parse(ViewState["EmployeeID"].ToString());
}
set
{
ctlEmployee.SelectedValue = value.ToString();
ViewState["EmployeeID"] = value;
Session["EmployeeID"] = value;
}
}
In your page or other control
override protected void OnInit(EventArgs e)
{
InitializeComponent();
UscSearchCriteriaBar1.CriteriaChanged += new EventHandler(this.CriteriaChanged);
base.OnInit(e);
}
private void CriteriaChanged(object sender, EventArgs e)
{
try
{
RefreshData();
}
catch (Exception ex)
{
ExceptionManager.Publish(ex);
}
}
You can get UscSearchCriteriaBar1.EmployeeID
This code should give you some ideas...was done for 1.1 should work on 2.

Resources