What Are The Biggest SharePoint API Mistakes?

The most prevalent SharePoint API mistake that I see is the lack of freaking Exist properties on proxy objects.

What do I mean?

One can’t do this in order to test, for example, whether a SPList object exists:

[csharp]
public static void DoesMyListExistIDunno()
{
SPWeb web = SPContext.Current.Web;
SPList list = web.Lists[“Heres My List”];

bool areYouThere = list.{An Exists Property Would Be Sweet Wouldn’t It?};
}
[/csharp]

As opposed to this, a developer is forced to do this (or a mild variation of this, I am just using the LINQ because it looks fancy) which is lame:
[csharp]

public static bool InspectForList(string listName)
{
var results = SPContext.Current.Web.Lists.Cast().Where(item => Equals(string.Compare(item.Title, listName, true), 0));
return results.Count()> 0;
}

[/csharp]
What do you think is the most rampant and cumbersome? I am interested in what other people see as being a pain in the butt.

Share

Remember When Using SPUtility.FormatDate To UTC (Extension Method)

This post is also because people said they required a more reusable extension method than here that tapped into SharePoint. Tyrants!

While I was doing a code review that tapped into some of the calendar segments of SharePoint I found this issue come up. When passing date parameters into SPUtility.FormatDate it will expect that it will be in UTC, which in my particular case, as well as I would assume others, was inaccurate since it was stored as local time. This can be overcome by using the methods provided by the SPWeb.RegionalSettings.TimeZone class, which will allow proper analysis to occur on SPWeb objects to support suitable conversion.

Wouldn’t it just be helpful if all this nonsense was taken care of, and you could just call a SPListItem.GetDateAsIso and pass in the SharePoint field name you would like to query against? Since this is going to extending the API and reused heavily, it makes sense to put this into an extension method (and for my own devious purposes of expanding on the previous post)! Since ISO8601 format is common in regulatory agencies, this is the return format I am going to target.

In the below Extensions class, there is the GetDateAsIso method which returns a DateTime object taking in 2 supplementary parameters outside of type declaration: the SharePoint field name, and a default DateTime value. We perform some argument checking, and then call Convert.ToDateTime on the specific SharePoint field. After, a combination of SPWeb.RegionalSettings.TimeZone.LocalTimeToUTC / UTCToLocalTime is used to ultimately populate the SPUtility.FormatDate method. The return should be a date string representative of the ISO8601 format, therefore in order to return this as a DateTime object Convert.ToDateTime is used.

[csharp]
public static class Extensions
{
public static DateTime GetDateAsIso(this SPListItem listItem, string fieldName, DateTime defaultVal)
{
SPWeb web = listItem.Web;
try
{
if (string.IsNullOrEmpty(fieldName))
{
return defaultVal;
}
if (listItem[fieldName] == null)
{
return defaultVal;
}
DateTime curDate = Convert.ToDateTime(listItem[fieldName]);
DateTime regionDate = web.RegionalSettings.TimeZone.UTCToLocalTime(web.ParentWeb.RegionalSettings.TimeZone.LocalTimeToUTC(curDate));
return Convert.ToDateTime(SPUtility.FormatDate(web, regionDate, SPDateFormat.ISO8601));
}
catch (Exception exception)
{
Debug.Write(exception.Message);
}
return defaultVal;
}
}

public static void TestingExtensionMethod()
{
SPList list = SPContext.Current.Web.Lists[“My List”];
foreach (SPListItem item in list.Items)
{
item.GetDateAsIso(“My Field”, DateTime.Now);
}
// Do whatever you want!
}

[/csharp]

Share

Writing Extension Methods for SharePoint

Extension methods are a formidable programming construct that augment implementation abstraction and modularize segments of code, lending itself well for filling gaps that may be present in a closed API, such as the one that SharePoint provides. Often times there may be a particular method that is desirable on a particular type, however the options for providing it are not available in the shipped API due to sealing and other modifies. Using Extension methods, it is possible to bypass this limitation while maintaining a clean implementation that can avoid deep inheritance tree references.

Extension methods are increasingly important when working with SharePoint code because a majority of objects that would normally mandate customizations of behavior, for example on SPList types, is decorated with a sealed access modified thereby negating possible inheritance. This is most noticeable when you are working with mock objects, which outside of certain frameworks (i.e. TypeMock) require an unsealed class and a default constructor.

As opposed to providing the method definition within the class, an extension method is simply defined by an association and contained in a separate static class supported by partial class constructs (i.e. it must exist in a namespace in the current scope). The method itself is invoked using instance method syntax, allowing some level familiarity in the code constructs. While the method is static, it can be called only on instances as defined in the parameters. In essence, an extension method will allow injection of a method into another class, so it is declared as if it is part of it.

In order to decrease method ambiguity due to extensions methods being defined only by the method name, it is important to take into account the appropriate naming convention (in fact, if the signature is the same the extension will be ignored!). Furthermore, the SharePoint types that will be extended are of course subject to the revisions of the API as released by MSFT. Therefore, when the API changes, there may not be the desired level of backwards compatibility.

The syntax for an extension method is very simple (it is important to note that while VB.NET requires the Extension attribute to be defined, C# does not. However in C# we are forced to create a copy of the object / return value so it evens it out!).

[csharp]
public static class Extensions
{
public static Type DoSomething(this Type type)
{
// let’s get something going!
}
}
[/csharp]

You can see that in the static Extensions class the DoSomething method has its sole parameter decorated with the this keyword modifier, to indicate the type to which this method will extend. So, for example when writing extension methods to extend the SPList class (without any supplementary parameters), our class would like this:

[csharp]
public static class Extensions
{
public static Type DoSomething(this SPList list)
{
// let’s get something going!
}
}
[/csharp]

But that isn’t doing much, so let’s take a more pragmatic example.

In the below, I am assuming that within an application, on SPList objects, I am going to be frequently reordering the current instance SPListItem collection into a descending order by the modified date, and then retrieving the last 5 items.

In the HarvestLastFive, it is noticeable that I am firstly specifying the type to target by using the this keyword with the SPList type. Following, I am building a SPListItemCollection of the SPList.Items, which then uses the LINQ OrderByDescending method in combination with the SPBuiltInFieldId.Modified property to handle the ordering. Lastly, Take returns the first 5 items out of the modified collection. If you just wanted the reordering (a variety of extensions I use daily use such LINQ collection modifiers for enhanced manipulation support) you would just take out the Take statement.
[csharp]

public static class Extensions
{
public static IEnumerable HarvestLastFive(this SPList typeToTarget)
{
try
{
SPListItemCollection collection = typeToTarget.Items;
var finalCollection = tempCollection.OrderByDescending(x => x[SPBuiltInFieldId.Modified]).Take(5);
return finalCollection;
}
catch (Exception exception)
{

}
return null;
}
}[/csharp]

You can see in the members of the Extensions class, that the HarvestLastFive method has a different icon (little down arrow) which specifies it as an extension method.

Using the method in a class is analgous to other methods available on that type. For example, the HarvestLastFive method takes on the form:
[csharp]
public static void TestingExtensionMethod()
{
SPList list = SPContext.Current.Web.Lists[“My List”];
var collection = list.HarvestLastFive();
// Do whatever you want!
}[/csharp]

Within Visual Studio, this method is noted as an extension method on the ToolTip with the prefix (extension).

This should give you enough to get going on extension methods. I will be posting some of my common extension methods that I use with SharePoint shortly, as this was meant to be an introduction.

Share