Wednesday, March 30, 2011

ASP.NET Client Side Postback

I have your basic asp.net web form which contains some client-side JavaScript that forces the page to time out and then redirect after 5 minutes. Mainly to protect possibly sensitive information.

At timeout, I want to force a server post back allowing me to save the form values for future edits.

I have played with both ClientScript.GetPostBackClientHyperlink() and ClientScript.GetPostBackEventReference(). Both seem to cause EventValidation issues for me. Yes, I can turn off Event Validation but is there a different or better workaournd?

Ideally, I don’t want to invoke a control (which has to be displayed) but just cause a postback with some type of argument that I can recognize serverside as being the result of a timeout condition.

From stackoverflow
  • This may be overkill, but you could setup a javascript timer to fire a web service call. The .NET web service can accept the form data and save it.

  • Couldn't you use a javascript timer to "click" the submit button? It sounds like using this form would be really annoying though, if it keeps posting back while you're trying to fill it out.

  • No great solutions so I build my own. A pretty simple custom control. Comments welcome.

    using System;
    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace BinaryOcean.Web.Library.WebControls
    {
        [ToolboxData("<{0}:PostBackTimer runat=\"server\" />"), DefaultProperty("Seconds"), DefaultEvent("Timeout")]
        public class PostBackTimer : Control, IPostBackEventHandler
        {
            public PostBackTimer() { }
    
            public string CommandArgument
            {
                get { return (string)ViewState["CommandArgument"] ?? string.Empty; }
                set { ViewState["CommandArgument"] = value; }
            }
    
            public string CommandName
            {
                get { return (string)ViewState["CommandName"] ?? string.Empty; }
                set { ViewState["CommandName"] = value; }
            }
    
            public bool Enabled
            {
                get { return (bool)(ViewState["Enabled"] ?? true); }
                set { ViewState["Enabled"] = value; }
            }
    
            public int Seconds
            {
                get { return (int)(ViewState["Seconds"] ?? 0); }
                set { ViewState["Seconds"] = value; }
            }
    
            [Description("PostBackTimer_OnTimeout")]
            public event EventHandler Timeout = delegate { };
    
            [Description("PostBackTimer_OnCommand")]
            public event CommandEventHandler Command = delegate { };
    
            public void RaisePostBackEvent(string eventArgument)
            {
                Timeout(this, EventArgs.Empty);
                Command(this, new CommandEventArgs(CommandName, CommandArgument));
            }
    
            protected override void OnPreRender(EventArgs e)
            {
                if (Enabled && Seconds > 0)
                {
                    var postback = Page.ClientScript.GetPostBackEventReference(this, null);
                    var script = string.Format("setTimeout(\"{0}\",{1});", postback, Seconds * 1000);
                    Page.ClientScript.RegisterStartupScript(GetType(), "PostBackTimer_" + UniqueID, script, true);
                }
    
                base.OnPreRender(e);
            }
        }
    }
    
  • with javascript, call __doPostBack("clientIdOfSubmitButton", null). This will fire off a postback just as if that button (or any other control you want) had triggered it.

0 comments:

Post a Comment