Changing and saving the profile is another story. You setup your profile provider in the web.config. In that configuration, there is an automaticSaveEnabled setting. When this is true, the profile provider automatically saves the profile when the page request is finished. It also is smart enough to only save the profile if it is 'dirty' (you have changed something in it). If this is false, you are responsible for saving the profile anytime it changes.
All sounds great. There is one big catch. If you store any non primitive type in the profile, it does not know if you changed it or not. So, as soon as you read the profile property, the provider assumes you changed it and saves it back out. For me, I typically always have some basic object I am storing, so that means my profile would be saved on every request if I had automaticSaveEnabled.
Introducing a MVC [Profile] action filter. Inspired by the new SessionState attribute (see [LINK HERE]optimization issue on that one too), this action filter lets you take control over exactly what happens to the profile with a filter attribute.
This filter has 4 ProfileBehavior options:
1) Default - this is basically a no-op. Just do what .net has always done.
2) ReadOnly - this will not save the profile, even if you access a complex property and automaticSaveEnabled=true.
3) Save - this will call save on the profile provider at the end of the request no matter what. It is up to the profile provider to skip the save if isDirty=false.
4) SaveIfDirty - this will call save on the profile provider at the end of the request if the profile is marked dirty.
This lets you use this attribute in several ways.
Set automaticSaveEnbled=true in your web.config and mark all controllers and/or actions with the profile filter set to ReadOnly when you know you do not want it saved.
Set automaticSaveEnbled=false in your web.config and mark all controllers and/or actions with the profile filter set to Save/SaveIfDirty where you know you want the profile saved at the end of the request.
Either way, this helps optimize the number of database calls made by the profile provider.
Download source here.