How to store web specific properties in SharePoint

Some developers are unaware that you can store custom properties in SPWeb objects. It's usually referred as the property bag and can be useful for storing configuration variables.

If you look at an SPWeb object you will notice a property called AllProperties. "Great", you say, but looking further down reveals another property: Properties. "Which one to use?", you ask. The answer is simple: both.

Properties is of type SPPropertyBag and was only left for backwards compatibility. AllProperties was implemented later as a replacement and is an Hashtable object. Properties only contains a subset of what is stored in AllProperties.

To avoid any inconsistencies, you should write an entry to both, as following:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPSite site = new SPSite(SPContext.Current.Site.ID))
    {
        using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
        {
            web.AllowUnsafeUpdates = true;
            web.Properties[key] = value;
            web.AllProperties[key] = value;
            web.Update();
            web.Properties.Update();
            web.AllowUnsafeUpdates = false;
        }
    }
});

What an ugly code for such a simple thing. Unfortunately, the RunWithElevatedPrivileges and the AllowUnsafeUpdates are necessary for this to work. For retrieving an entry you should use AllProperties.

You're better off creating an utility class to add, update, get and remove properties.

You will be restricted to strings, but obviously you can also parse booleans, integers or even serialize objects to JSON (for that you can use To and FromJson Extension Methods).

Resources