views:

1650

answers:

4

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.

+1  A: 

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.

hacker
A: 

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.

Jon Tackabury
A: 

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);
        }
    }
}
Andrew Robinson
A: 

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.

Matt Briggs