SharePoint is very strong as a development platform. As strong as it is, thereare still some disadvantages for developers. For example, poor performance of operating list items can be frustrating. Also,trying to store custom data can prove to be a not so simple task. To develop a product which needs to use a large amount of data or to execute very complex calculations, we generally need tocreate an assistant database to save our data. Although not always elegant in nature, SharePoint gives us several options when we want to develop a small product.
There are four classes:
- Properties (hashtable type)
- SPWeb
- SPFolder
- SPList Item
“Properties” is a hash table, so we can save data with a key value pair. The value should always be serialized. When we update the object, the property will be written to the database with the object. You can access the data from the object with a key. We won’t go into detail regarding this at the moment though.
Another method for storing data: SPPersistedObject
The SPPersisted object class is in the namespace Microsoft.SharePoint.Administration. From this we can conclude that the object can only be used in management, and the data will be stored in the configuration database. When we want to customizestorage configuration data by class, we first must create a class inheriting from SPPersistedObject class.
For example:
public class MyConfiguration : SPPersistedObject { [Persisted] public string FirstName; [Persisted] public string LastName; publicMyConfiguration( ) { } publicMyConfiguration( string name, SPPersistedObject parent, Guid id) : base( name, parent, id) { } }
Now, if you would like a configuration example which you want stored in the configuration database, you can use the following:
GuidinstanceId = Guid.NewGuid(); MyConfiguration conf = new MyConfiguration("test configure", webApplication, instanceId); conf.FirstName = "John"; conf.LastName = "Young"; conf.Update();
The configuration data will be serialized to xml, and will be stored or updated in the configuration database. Now you can get the data from the WebApplication object using the SPWebApplication.GetChild method.
MyConfiguration readed = webApplication.GetChild<MyConfiguration>("test configure"); // watch the configuration's FirstName field, and the LastName field, they are be same with the data you storaged before, // then update the data, and get it again, what will happened? readed.FirstName = "Joy"; readed.Update();
TheFirst Name will now say “Joy”. This means the data has been updated. You’ll be able to access data anywhere given you have enough permission. Generally, we will do this in the farm level or web application level solutions.
In case you were wondering, you can obtain data by id using the following:
farm.GetObject(guid);
UsingSPPersistedObject as the hierarchical storage object is pretty easy to follow. However, there are a few things which must be considered. First, it is a permission. Secondly, it is the attribute which can only be used in afield (including private fields) but not on a property. Thirdly, both the name and id must be unique, if not, when you create multiple objects with the same name or id, it will fail to update.
The fields are simple and the field types are underline type, so just use the sample for its simplicity and for it works well.
But if the field is in the category of a complex type, will it still work? We must find out, so let’s define another class inherited from the SPPersistedObject.
public class RootSetting : SPPersistedObject { [Persisted] public MyConfiguration First; public RootSetting( ) { } public RootSetting(string name, SPPersistedObject parent, Guid id) : base( name, parent, id) { } }
Create “root” from the class “RootSetting” and set a value for the “First” Field.Updating the “root” takes the “root” from the configuration database. Here we will find the “First” field is null and has not been updated to the database. When we update the “root” object, its field will not be updated automatically.
GuidrootId = Guid.NewGuid(); RootSetting root = new RootSetting("my root setting", webApplication, rootId); GuidfirstId = Guid.NewGuid(); root.First = new MyConfiguration("first configuration", webApplication, firstId); root.Update(); varrootFromData = webApplication.GetChild<RootSetting>("my root setting");
If we want to get “rootFromData” we will find that it’s null. Why? Since theSPPersistedObject will not be updated automatically, we must call the method “Update”. In order to “Update” we should do type the following:
root.First.Update() before we call root.Update()
So you may ask: can’t “field” be updated automatically? The answer to this is yes. If the field’s class is inherited from the class SPAutoSerializingObjectwhen we update the “root”, the field will be updated automatically. You can refer to the class SPAlternateUrlCollection if you need help which is a collection of SPAlternateUrls.
The collection class is inherited from the SPPersistedObject, but the element is inherited from the SPAutoSeiralizingObject. When we update the SPAlternateUrlCollection, every element in the collection will be updated automatically.
There are a few points to note here.For starters,the SPAutoSerializingObject doesn’t contain a method update, so it cannot be used to store data separately. Adding to this, there is no way to get to the object form farm or WebApplication directly.
Also the SPAutoSerializingObject cannot contain SPPersistedObject fields, but the SPPersistedObject can contain multiple SPAutoSerializingObject instances. Furthermore, every SPPersistedObject will be stored as a separated item in a sql table. This means thatstorage of every SPPersistedObject field will be divided. This also means the entirety of objects’SPAutoSerializingObject field will be stored with the examples other fields in one single item in a sql table.
The last thing I want to mention is that I reada post where the author tested what happened after calling the SPPersistedObject.Update() 50 times continuously. It turned out that it crashed. I apologize that I can’t test this while I write this post, but I do plan on trying. If you do as well and get the same results, please let me know.