In part one I talked about strongly typed access to SharePoint list items and we did set a base for how to retrieve values in a more strongly typed fashion. In part two I'll extend this example and show you how to retrieve wrapped items from a SharePoint list.
Our final solution is created out of three classes which all have a specific use.
The Extensions class is a static class which contains extension methods for SPItem, SPListItem and SPListItemCollection. These extension methods help us throughout our SharePoint development and can be extended to contain even more helpfull methods.
The ListItemWrapper class is an abstract base class that all of our custom wrappers should inherit. It provides us with the possibility to access properties of list items in a strongly typed fashion
The ListWrapper class is a generic class that helps us in querying sharepoint lists. Returning wrapped list items.
If you're not interested in large chunkes of code you can find a download link with the full sourcecode and the end of this post. So be my guest and download it. If you however would like to get a feel of how you can use this simple class library hang on with me and I'll show you how to use it with a real life example.
Outline: We have a SharePoint site for a car selling business. On this site we have a SharePoint list with content types and one of those content types is the Car type. This Car content type has an id of '0x01000D483DA73079A341828E6E216045019A0078881191FD5D1642839403A59FC701C0' and several columns of which we take 3 columns for our example. It has an Url column that contains the website url of the brand named 'ManufacturerUrl'. It has an Integer column that contains the mileage named 'Mileage'. And it contains a LookupMulti column that contains a list of accessoiries named 'Accessoiries'
The only way we could normally access these fields in our code is by the field indexer on SPListItem. Which causes a lot of problems.
And that's just to name a few. That's why we create a wrapper. And our wrapper will take care of all of thos issues mentioned before. Just have a look at the next code.
public sealed class CarWrapper : ListItemWrapper {
private static readonly string contentTypedId = "0x01000D483DA73079A341828E6E216045019A0078881191FD5D1642839403A59FC701C0";
public CarWrapper(SPListItem listItem)
: base(listItem, true, ContentTypeId) {
}
public static string ContentTypeId {
get {
return contentTypedId;
}
}
public int Mileage {
get {
return ListItem.GetValue<int>("Mileage", 0);
}
}
public SPFieldUrlValue ManufacturerUrl {
get {
return ListItem.GetUrlFieldValue("ManufacturerUrl");
}
}
public SPFieldLookupValueCollection Accessoiries {
get {
return ListItem.GetLookupFieldValueCollection("Accessoiries");
}
}
public static IEnumerable<CarWrapper> GetItemsByContentTypeId(string url) {
return new ListWrapper<CarWrapper>(url).GetItemsByContentTypeId(ContentTypeId);
}
public static IEnumerable<CarWrapper> GetItemsByContentTypeId(SPList list) {
return new ListWrapper<CarWrapper>(list).GetItemsByContentTypeId(ContentTypeId);
}
}
What you see here is a simple class that inherits from ListItemWrapper. We set the ContentTypeId to the Id of the Car content type and we add our three columns as properties. To retrieve the values in our properties we simply use the extension methods from our library. So from now on we can actualy access our properties strongly typed, without knowing exactly what field the value comes from. Just like this:
CarWrapper someCar = new CarWrapper(someSPListItem);
Console.WriteLine(someCar.Mileage + " miles");
Console.WriteLine("Accessoiries:");
foreach (var accessory in someCar.Accessoiries) {
Console.WriteLine(accessory.LookupId + " : " + accessory.LookupValue);
}
You must admit that this does look a lot better already don't you? This alows for much faster development. Do not forget the intellisense you get when you're working with strongly typed code and the fact that there's an automated check to validate the content type id(which is optional). So we do have a wrapper but we are not finished yet. Why not automagically wrap all list items of a list? It's very very easy beacause of the generic ListWrapper class.
Most of the time we would like to itterate through a number of list items in a SharePoint list. And if possible in a strongly typed fashion right? Well if you did take a good look at the wrapper class you would have noticed that there are two methods in there that return an IEnumerable of type CarWrapper simply by the Url or an instance of a SPList. I used the generic ListWrapper class to do so.
Imagine you have just one list in you site where you store all the cars. You could extend the wrapper with static methods that return IEnumerables of CarWrapper without the input of a url. Have a look at this:
private static readonly string carUrl = "http://mysite/lists/cars";
public static IEnumerable<CarWrapper> GetAllCars() {
return new ListWrapper<CarWrapper>(carUrl).GetItemsByContentTypeId(ContentTypeId);
}
I would like to point out is that this library is not your end point. You can extend your wrappers to allow for updating or add a lot of predefined queries. All I realy want you guys and girls to do is work strongly typed! Because I don't know about you but I'm realy tired of reading lines like 'int mil = (int)item["Mileage"]' all over the code. We should not work like that do we?
Please do leave a comment if you do or do not like my idea of working with SharePoint list items.
Happy coding!
Wesley
Comments have been disabled for this content.