Handling of Browser-Refresh (F5)

Sep 3, 2009 at 1:06 AM

Hi Radim,

first: I suppose you will let me know if I ask too much (trying to learn from your experience).

Since we do not have state in MVC unless we implement it ourself (within Session I suppose ?) the user will loose all entries if he hits F5 or jumps to a different view before clicking Save. Should I just accept this behaviour since it is the web and it's very common to loose changes if one is jumping somewhere else? For Refresh (F5) however, a lot of applications nowadays handle this graceful. My users might except this. On the other hand, one could argue, that F5 means refresh, thus reloading from the DB.

How are you handling a browser refresh on your applications?

What I tried when the user works on a complex object with multiple actions (sync and async) occurring: in the action handler I update my model and store the relevant parts in the session. If there is already something in the session I restore the model before I apply the new changes. So it's RestoreModel - ApplyChanges - StoreModel. On CancelEdit and Update I clean up the session. For DetailViews I don't store anything into the session since no changes will be applied anyway. This way I can handle F5 graceful. The user can even jump somewhere else in the application and come back to the editview and the values will be still there as long as he does not cancel or save. What I don't like: it will leak memory over time, if the user never finishes the update.

Do you have a better approach?

kind regards


Sep 3, 2009 at 6:00 AM

Hi Benno

Another really nice question or design area, approach decision. I like these discussions. They have many results and only when we know (and UNDERSTAND) more then one solution - than we can decide.

The Catharsis approach is based on the platform == web and browser! And description will again profit from separation of concern - multi-layer architecture.

There is a center point of any change (store to Database, store to XML, change Application cache (static), changes to Cache etc.) This gate is called: Business materialized in entity Facade. If you ask for entity - you can usually do it only via GetBySearch() or GetById() . If you need to change entity, ask the Add(), Update() or Delete(). The Facade must take care of the rules: Can be provided entity Added (is correctly set)? Can be item updated without impacts on the application? Is the demand for entity removing available, aren't there any remaining references? If all these business rules are met - change is processed using underlying Dao objects.

That among other results also brings one fundamental simplification: Whenever any upper application level (MVC or batch) request the change for not existing, or already updated or newly added element - Facade will check that fact and inform: Yes - your change will be processed, No - it is not possible, the information about error search in Messages collection.

The user UI part (based on MVC, SilverLight, Smart client, WPF ...) takes care about user comfort: There are readonly views: Detail, List, Search etc. These provides the 'readOnly' ifnormation based on the Facade results coming from  GetBySearch() or GetById(). There are edit views (new, update and even the list action with delete hyperlink) which allows to collect the user change-sets and then ask Facade to process them.

The Catharsis framework decided to profit from the web-browser UI platform as much as possible. User is provided with hyperlinks for actions. It also means, that any hyperlink can be open in a new window. (The list view - with cooperation of Search parameters - even provides the setting for the detail navigation to be opened in a new window).

That all together means, that Catharsis approach is based on NO Session and NO view except of the SearchParameters object. If user selects some filters, orders and page number on for any entity - this information is stored in the session. It means that in session is stored One object per entity per user. There is also the Session size counter which you can turn on in the Log4NET.config. This will give you an overview about the Session per user size. From our existing projects experience - this is never larger then 500kB - coool :)

Anything else, is always reloaded from The DAO layer. It means, that user is always provided with the latest information. Always.

F5 - Refresh == Catharsis (as any other approach) can never grant you restoring the edited data (filled in inputboxes) when F5 is clicked. There simply must be the request call with the filled FORM. Then the row-parameters can be converted into the entities and via Facade stored in the storage.

User can re-act with any piece of application in any browser window. If there is an request - Controller's Action can Ask Facade to check it and persist it (using Facade's Dao).

User can update the same item differently via two or more opened browser windows - then the last change will win.

User can click F5 to get the latest data - and application will provide them.

So F5, many browser windows are not a problem - from my point of view.


So until now - in the session only the SearchParam object is stored.


If this approach is not suitable for you - because you think that you need complex Entity with many sync and async actions - yes you can for a while store that in the session. And what's more - Catharsis framework is ready for that approach!!!

In fact - you can during the Item editing -> store it in the 'Model.Item' property (as a reference of course). This is the intended reference for the framework (thanks the Generics it will be always fully typed e.g. <T> as Person). This reference is Stored and Restored from the session in any Controllers's ACTION! So - you can count on this object among many operation, before the Facade is asked to persist the result.

BUT - as you said!!! - it could cause a large damage to performance - every user can have opened Item on every controller - and this could lead to memory leak.

It CANNOT - there is a very smart switch: 'DoNotStoreItemInSessionStorage' placed in the 'Model.ItemModel'. This switch is by default set to false, and Items are always temporarily- persisted in the session. The trick is on 3 actions:

Detail, Search, List - (observe theirs OnBefore())

Whenever one of these actions is called - it means that user stopped editing the item - that is obvious ==> 'DoNotStoreItemInSessionStorage' is set to true - and this reference on opened item is lost!!! removed from session.


(ou:) I do like it :) Really nice, powerful, simple - and adjustable, (adjust it to your needs!)  without impacts to the performance or memory leaks.)


Thanks for your feedback - review - or whatever! For us - that's the proof of concept - The Catharsis architecture is "developer" oriented :)

Enjoy Catharsis

Radim Köhler

Sep 3, 2009 at 5:52 PM


There is the BETA Example of the Catharsis 1.5 available on the Source code tab. I suggest to concentrate on this new stuf. Soon there will be the Guidance as well and standard release.

Catharsis 1.5 brings simplification, new Dao implementation based on XML, XHTML 1.1 valid markup, one CSS for all browsers, new layer for AOP...

Enjoy Catharsis 1.5 BETA Example

Radim Köhler