How to: Write a value into the property bag

Posted Monday, May 12, 2008 2:51 PM by CoreyRoth

I have ran into a few people that didn't even know what the property bag is on the SPWeb object, so I figured that would be a good topic for a post.  The property bag exposed by the Properties and AllProperties collections on the SPWeb object gives the developer a way to cache information on a site.  It can be compared to ASP.NET's cache object but the values are shared across the farm and will persist through server reboots.  Unfortunately, using the property bag isn't as simple as you would think.  In fact to get it working in all situations, it requires a number of settings to allow it to work.  It's probably enough to scare a lot of developers away from it.

Before we start, let me talk about the differences between Properties and AllProperties.  Properties is a collection of type SPPropertyBag.  It is sort of considered deprecated.  You can use it to add new items to the property bag, but it will only return a subset of everything in the property bag when retrieving data.  Why is that?  I have no idea.  So instead, Microsoft later implemented the AllProperties Hashtable which contains everything in the property bag.

Here is what the start of our code block looks like to write to the property bag.  This assumes it is inside a using block to get access to an SPWeb.

// unsafe updates are required to be able to write to the property bag

currentWeb.AllowUnsafeUpdates = true;

 

// you must check to see if the collection has a value in the assigned key already

if (!currentWeb.AllProperties.ContainsKey(key))

    currentWeb.Properties.Add(key, myValue);

else

    currentWeb.AllProperties[key] = myValue;

 

// update the properties

currentWeb.Properties.Update();

currentWeb.AllowUnsafeUpdates = false;

There are a number of things to note here.  First, it requires AllowUnsafeUpdates to be set to true.  Secondly notice that the AllProperties object actually has a method to check to see if a key exists.  This is probably the only collection in SharePoint that lets you check to see if something exists without throwing an exception.  This is of course because, the type is Hashtable and not a custom SharePoint collection.  If the key does not already exists, you add it to the Properties object (not AllProperties).  If a value already exists, you store the value using an indexer with the AllProperties object.  You might be able to get this to work other ways, but after lots of attempts, this is what works for me.  After the value is stored, you have to call Update on the Properties object if you want it to actually store the values.  If you have multiple values to store, you only need to call this once.  Lastly, be sure to remember and turn off AllowUnsafeUpdates.

The above code works great...as long as the account running it is an administrator.  If you need this code to work when executed by a regular user, there is an additional step.  You have to use SPSecurity.RunWithElevatedPrivileges.  I am assuming you are already familiar with how this method works.

SPSecurity.RunWithElevatedPrivileges(delegate()

{

    using (SPSite currentSiteCollection = new SPSite("http://myserver/mysite"))

    {

        using (SPWeb currentWeb = currentSiteCollection.OpenWeb())

        {

            // unsafe updates are required to be able to write to the property bag

            currentWeb.AllowUnsafeUpdates = true;

 

            // you must check to see if the collection has a value in the assigned key already

            if (!currentWeb.AllProperties.ContainsKey(key))

                currentWeb.Properties.Add(key, value.Value.ToString());

            else

                currentWeb.AllProperties[key] = value;

 

            // update the properties

            currentWeb.Properties.Update();

            currentWeb.AllowUnsafeUpdates = false;

        }

    }

});

There is a complete example.  One thing to remember is that the method inside RunWithElevatedPrivileges requires that you create a new SPSite object for it to work.  Do not pass it a reference from one that already exists.  Create a new one by passing it a URL.  Since we need the SPWeb object in this case, I have things nested like I have mentioned in my post in the past.

Luckily, reading from the property bag is not as difficult.  Just check to see if the key exists and read from it using AllProperties.

if (currentSite.AllProperties.ContainsKey("MyItem"))

    myItem = currentSite.AllProperties["MyItem"].ToString();

This may seem like a lot to store and retrieve values in the property bag, but it's pretty easy to wraps this code up into a class.

Comments

# Links (5/13/2008) « Steve Pietrek - Everything SharePoint

Pingback from  Links (5/13/2008) « Steve Pietrek - Everything SharePoint

# re: How to: Write a value into the property bag

Friday, January 21, 2011 7:01 AM by Todd Bleeker

Do you have any updated insight into using AllProperties within the context of a SharePoint 2010 Sandboxed Solution?

<Todd />

# re: How to: Write a value into the property bag

Tuesday, April 5, 2011 1:30 AM by Jennifer

@ Todd, simply use the AddProperty method.

E.g., SPContext.Current.Site.RootWeb.AddProperty("ABC_test", "ABC test");

Best, jennifer

# re: How to: Write a value into the property bag

Tuesday, July 12, 2011 12:09 PM by Steve

Using SP2010, I found that I had to include a call to SPWeb.Update() after setting the value with SPWeb.AllProperties[currentPropName] = currentPropValue; to commit the change to the dbase.

# re: How to: Write a value into the property bag

Monday, October 24, 2011 5:48 AM by Mikael

Thanks Steve,

SPWeb.Update() was indeed required when updating the property value. Note that calling Properties.Update() before SPWeb.UpdatE() does not work. I got it working like this:

using (var site = new SPSite(url))

               {

                   SPWeb rootWeb = site.RootWeb;

                   rootWeb.AllowUnsafeUpdates = true;

                   var keyExists = rootWeb.AllProperties.ContainsKey(key);

                   if (!keyExists)

                   {

                       WriteEventLog("WriteWebConfig key does not exist in PropertyBag. Adding it. " + key + " " + value, EventSeverity.Information);

                       rootWeb.Properties.Add(key, value);

                       rootWeb.Properties.Update();

                   }

                   else

                   {

                       WriteEventLog("WriteWebConfig keyPair already exists. Updating it.. " + Environment.NewLine +

                           "Previous keyPair: " + key + ", " + rootWeb.AllProperties[key] + Environment.NewLine +

                           "New keyPair: " + key + ", " + value, EventSeverity.Information);

                       rootWeb.AllProperties[key] = value;

                       rootWeb.Update();

                   }                  

                   rootWeb.AllowUnsafeUpdates = false;

                   result = "Success: KeyPair successfully written to PropertyBag. Key: " + key + ", Value: " + rootWeb.AllProperties[key];

               }

# re: How to: Write a value into the property bag

Tuesday, May 28, 2013 11:44 PM by Suresh Pydi

Nice post. Here is one more post explaining to get and set property bag values in SharePoint 2013 apps using CSOM

sureshpydi.blogspot.in/.../set-and-get-property-bag-values-in.html

# re: How to: Write a value into the property bag

Monday, December 1, 2014 11:20 PM by Pankit Patel

if i want SPWebapplication level property bag then how i will do that ?//

Leave a Comment

(required)
(required)
(optional)
(required)