can httphandler fire an event? - asp.net

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) {
//...
}
}

Related

Session created after the postback occured and page-load event doesnt use session correctly in ASP.NET

I’ve made a handy “user control” for login to my website and it is placed in the site master.
The natural procedure is that the user logs in the web site and he should be announced with a welcome message containing its full name. The full-Name naturally should sits in a session variable created when the user logged on.
There is no doubt that we place the desired code in the “page_load” event and expect it to pass user’s full-name to the right circumstances (here its a label named lblFullName) in order to print/show the welcome message when login button clicked, But the full-name doesn’t passed until the user logs in the website again (for the 2nd times).
Why this problem happens?
Its some part of my code:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["FullName"]==null)
{
//nothing 2 do.
}
else
{
lblFullName.Text = Session["FullName"].ToString();
}
}
You probably set the Session variable in the user control after the Page_Load event has been processed, so that it will not see the user name until the next postback.
In order to update the Label text as soon as the login is validated, you could:
Define an event in the user control
Register an event handler in the main page
Call the event handler as soon as the user has logged in
In the event handler, update the Label text
You could also eliminate the Session variable by passing the user full name in an EventArgs derived class. If you make the following class accessible in the user control and in the main form:
public class StringEventArgs : EventArgs
{
public string Value { get; set; }
public StringEventArgs(string value)
{
Value = value;
}
}
then you can define this event in the user control:
public event EventHandler<StringEventArgs> UserLoggedIn;
In the function where the login is confirmed, you call the event handlers:
private void UserLoginValidation()
{
// Login validation is done here
bool loginSuccessful = ...
if (loginSuccessful && UserLoggedIn != null)
{
UserLoggedIn(this, new StringEventArgs(fullName));
}
}
In the main page, you register the event handler, which updates the Label:
protected void Page_Load(object sender, EventArgs e)
{
loginUserControl1.UserLoggedIn += loginUserControl1_UserLoggedIn;
...
}
private void loginUserControl1_UserLoggedIn(object sender, StringEventArgs e)
{
lblFullName.Text = e.Value;
}

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 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);
}

Get state of ASP.NET page life cycle

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();
}

Can I bubble up event from Master page to ASPX

Can I bubble up a button click event of a button in master page to be handled by an event handler in the aspx page ?
You can expose the event handler and hookup to it, like this:
In the master:
public event EventHandler ButtonClick
{
add { ButtonThatGetsClicked.Click += value; }
remove { ButtonThatGetsClicked.Click -= value; }
}
In the page:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
((MyMasterType)Master).ButtonClick += MyHandler;
}
private void MyHandler(object sender, EventArgs e)
{
//Do Something
}
Also, you can avoid the Master type cast and have it already appear in intellisense as your Master's type by using the #MasterType directive in the aspx markup.
You can rebroadcast the event. Declare a new corresponding event in your master page, such as HelpClicked and then aspx pages that use this master can subscribe to the event and handle it appropriately. The master can also take a default action if there are no subscribers (or use an EventArgs with a Handled property or something like that).

Resources