Scott Mitchell has an excellent article on 4GuysFromRolla.com about how to use ASP.Net to prompt a user to save changes before leaving a page.  It is part of a series he wrote back in 2004 but it is still relevant today.  The only change you should make today is that he calls methods of the Page class (IsStartupScriptRegistered, RegisterClientScriptBlock, RegisterArrayDeclaration) and these methods are depcrecated and replaced by the same methods in the Page.ClientScript class.

Scott's code initializes a client-side array with a list of inputs to monitor and the initial value of each input.  He then uses the onbeforeunload event to check if the data in any of these inputs has changed and displays a confirmation prompt if any data hase changed.  This event fires even if the user attempts to exit the form by closing the browser or clicking the brower's 'Back' button.

I liked Scott's approach so much that I took his public methods and moved them into a base class that inherits from System.Web.UI.Page and I inherit all my web pages from this class.  Now in each Page_Load, I can call methods of the base class to register controls that, if changed, will mark page data as dirty and prompt the user when he attempts to navigate away without saving.

I noticed that the "initial state" of controls were reset whenever a postback occurred, so I created a method "MarkDataAsDirty" that could be called when a control's "autopostback" fired but when the user is not finished entering data.  This sets a hidden form on the client that is checked in the onbeforeunload method to determine if data has changed.

I also made the methods public so they could be accessible to any user controls dropped on a page.  And I created the utility method RegisterForConfirmUnsavedChanges that registers the most common controls on the page using Scott's original methods.

I've included a sample ASP.NET web site in which every page inherits from a base page and methods of that base class are called to implement this functionality.

 

ConfirmSaveSite1.zip (9.51 KB)