0

I would like to know if I can prevent the event bubbling / propagation on the page load based on condition like:

protected override void OnLoad(EventArgs e)
{
    // If the user press F5 from the browser
    if (IsRefresh)
    {
        // Here I want to stop propagation/bubbling the events like OnClick of a submit button but without using the button object (I want it generic)
    }
    else
    {
        base.OnLoad(e);
    }
}

Is this possible?

Ahmed Magdy
  • 5,956
  • 8
  • 43
  • 75
  • Are you looking for something similar to this? http://stackoverflow.com/questions/5484000/asp-net-stop-button-event-running-on-refresh –  Apr 15 '13 at 15:09
  • I don't want to implement the check if every click event, I want it to be generic – Ahmed Magdy Apr 15 '13 at 15:18

5 Answers5

3

Prevent the event bubbling has two difficulties - detect the F5 and stop the events - i would simply use the Post/Redirect/Get-pattern:

protected void Button1_Click(object sender, System.EventArgs e)
{
    // do what you need to do
    // now redirect to the same page, 
    // then a browser-refresh via F5 won't trigger this event again
    Response.Redirect(Request.Url.PathAndQuery);
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • In this case if I want to show a success or error message, where is the condition? – Ahmed Magdy Apr 15 '13 at 15:20
  • @AMgdy: You can use an url parameter. – Tim Schmelter Apr 15 '13 at 15:21
  • But this won't be a appropriate, if the user take the url with query strings and open it in a new tab or in a new browser he will get the message but actually doing anything! – Ahmed Magdy Apr 15 '13 at 15:22
  • @AMgdy: You could also use the `Session`. However, imho an url-parameter is more appropriate. If the user wants to know if your URL parameters are vulnerable to script injection he can try. If nothing happens his plan fails which is desired. – Tim Schmelter Apr 15 '13 at 15:29
  • Session is disabled by default in SharePoint and I don't want to enable it, and I would like my url to be clean that why I'm looking to a way to stop the event bubbling – Ahmed Magdy Apr 15 '13 at 15:45
  • As I mentioned in my answer in more detail, you can use cookies or short-expiry cache (with some user token as part of the key). – Meligy Apr 21 '13 at 00:15
1

I did once in ASP.NET WebForms project when user press on F5 it'll do something other than refresh, I done this by use jQuery keypress even for the page and call e.preventDefault(); check this

Update:

$(document).ready(){function(){
        this.keydown(e){
          if (e.which == 116){
                  e.preventDefault();
             window.location.href = "http://foo.com/?IsReferesh=1";     
           }
        };    
)};

You can use the QueryString to check if user press F5 and the reflection in Code Behind. If I missed something, then I didn't fully understand your question.

Community
  • 1
  • 1
Emad Mokhtar
  • 3,237
  • 5
  • 31
  • 49
1

Regarding the specifics of your question, how about inverting it? Maybe add a Load event listener (say, in page Init) only if the condition is not met.

Another option might be doing something like:

this.Load -= MyPageLoadMethod;

You are likely looking at the event itself, not the OnLoad method. Eitherway, I think it is possible, see some options here How to remove all event handlers from a control

There is a big "BUT" though...


Like most people here, I think you are not solving the right problem. I'm sorry the same applies for Emad's solution I think.

Tim nailed it. This answer will try to explain this option more.

The pattern Post-Get-redirect is very popular and very standard. In most of our applications, submitting the same form more than once either by re-clicking the submit button before page loading or refreshing the browser causing another POST call is wrong, so, the practice of redirect after a non-AJAX form submission has become so standard.

Everything else you may try will be no more of a dirty workaround than a proper solution.

--

Now, comes the problem of providing feedback to the user. Ruby On Rails provides a nifty helper for this called Flash helper. It's a message you can set before redirecting (or even in the same page if there is no redirect) and the next time you display it, it'll destroy itself, the next time you call it, you get nothing. so, you display nothing.

ASP.NET MVC has something like this which is TempData. TempData can be stored in many places, by default in the Session, so, if you are redirecting from an MVC action, you can set something like TempData['Message'] , and read it in the next Controller. ASP.NET MVC will handle removing it after the redirect.

So, how about Webforms? There's nothing to prevent you from doing it too. It really isn't rocket science

  • You can check for URL Referrer whether it is an edit page or not and display message based on that.

  • You can store a message in Session before redirect, and check for it in every page load, if found, you display it and delete it from Session

  • If Session is disabled, you can use cookies. You can check the date of the cookie before sending, so that if the redirect never happened (use network dropped or whatever) and use came to the page later in the time he doesn't see an outdated message.

  • You can also store in Cache (with some key related to user of course, as Cache is application wide), You can then set the Cache expiration to some short period to avoid the problem explained in cookies option

You can also google for Rails Flash-like for ASP.NET Webforms to see what reusable components other people came up with. This result for example came in my search:
http://highoncoding.com/Articles/542_Creating_Rails_Like_Flash_Feature_in__NET_The_Flash_Control.aspx
Check NuGet also maybe there's something there. Again, it's not hard to build your own anyway.


Update:

Another simple approach might be to just redirect to the same URL, this'll cause a GET request and will not run any handler, pretty close to the original implementation of Post-Get-Redirect (yours will be Post-Post-Redirect maybe, kidding), and pretty safe as well.

Something like:

Response.Redirect(Request.RawUrl);

Update 2

Just as mentioned above, if you are running after page init, say in page Load, you can always emove events in a way similar to:

this.SubmitButton.Click -= SubmitButton_Click;

You get the idea...

That's useful if what you want is stop particular events, while the previous bits of the answer were assuming you are trying to stop most of the events.

http://gurustop.net

Community
  • 1
  • 1
Meligy
  • 35,654
  • 11
  • 85
  • 109
0
protected override void OnLoad(EventArgs e)
{
        if (!IsPostBack)
        {
            if (Request.UrlReferrer != null)
                if (Request.UrlReferrer.PathAndQuery == Request.RawUrl)
                {
                    // Show Message
                }
        }
}

protected void Button1_Click(object sender, System.EventArgs e)
{   
     Response.Redirect(Request.Url.PathAndQuery);
}

Note:

if (Request.UrlReferrer.PathAndQuery == Request.RawUrl) // does not work with chrome so you can replace it with if (Request.UrlReferrer.AbsolutePath == Request.Url.AbsolutePath)

  • Thanks Tamer, this might help with showing the message but still didn't answer the question itself. – Ahmed Magdy Apr 17 '13 at 12:27
  • Yes, I know but it is a quick solution. – Tamer Farag Apr 17 '13 at 12:52
  • but the permanent solution will be more complicated as you will have to add a hidden field to the form and for every click event you fill it with a random value (the guid may be ok) - save the old value in variable - add it to the view state - and on the page load if there is a post back check the hidden field value and the view state – Tamer Farag Apr 17 '13 at 13:44
  • check these article: http://www.codeproject.com/Questions/97913/How-to-disable-PostBack-when-we-click-refresh-butt http://dotnetslackers.com/community/blogs/simoneb/archive/2007/01/07/Using-an-HttpModule-to-detect-page-refresh.aspx but do not use http modules with sharepoint as it will be called many times with each request - better to add them in the page base class and inherit it. – Tamer Farag Apr 17 '13 at 13:46
  • I had a solution for detecting the refresh here: http://stevenbey.com/archive/2012/02/18/detecting-page-refresh-in-asp-net-webforms-redux.aspx the point is don't want to check in each submit if I am in this mode or not, I just want to find a generic solution in Page_Load to detect if I am in refresh then stop any other events some thing like jQuery: e.stopPropagation() and this is my question :) – Ahmed Magdy Apr 17 '13 at 21:44
0
    static string REFRESH_CHECK_GUID = "REFRESH_CHECK_GUID";

    protected void Page_Load(object sender, EventArgs e)
    {
        if (ViewState[REFRESH_CHECK_GUID] != null && !ViewState[REFRESH_CHECK_GUID].ToString().Equals(Session[REFRESH_CHECK_GUID].ToString()))
        {
            Response.Redirect("Login.Aspx");
        }

        Session[REFRESH_CHECK_GUID] = System.Guid.NewGuid().ToString();
        ViewState[REFRESH_CHECK_GUID] = Session[REFRESH_CHECK_GUID];
Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35