Blog Categories
CodePlex Projects
CryptoCollaboration
Posted by Adam Buenz
Was not merging the germane updates by default for both the client and server bits. The fact that to support SQL Server 2008 (isn’t it almost 2009 FFS?) you have to currently do an extraction and slipstream with the service pack, which to even figure out through astonishingly cryptic errors is a challenge in itself, is ridiculous. The fact that the Team Explorer update is included in the VS.NET 2008 SP1 as opposed to being rolled into the TE download bits is even more outlandish. It is time consuming when you have already applied the client service packs, and prone to errors when doing retractions and updates.
I can’t imagine that it is difficult to provide the bits as such, unless I am missing something. I am very, very disappointed that this is the current state of TFS.
It makes me a sad panda (for you South Park fans)
Share This
Posted by Adam Buenz
On this Veterans day, remember those who have made the ultimate sacrifice so that you could live in a free society.
(My old two units)
Share This
Posted by Adam Buenz
Along the same lines as this post, once one has located the relevant department that they desire from a collection, how is it possible to use that department string name in order to get a list of the relevant employees? As we used the KeywordQuery class the last time, we are going to take the same approach in order to return a new DataTable with those values.
Here is the code in order to execute that:
C#:
-
public static DataTable BuildDepartmentEmployees(string url, string deptName, int queryLimit)
-
{
-
using (var result = new DataTable ())
-
{
-
using (var site = new SPSite (url ))
-
{
-
using (var query = new KeywordQuery (site ))
-
{
-
query.ResultTypes = ResultType.RelevantResults;
-
query.EnableStemming = true;
-
query.TrimDuplicates = true;
-
query.StartRow = 0;
-
query.RowLimit = queryLimit;
-
string str =
-
query.QueryText = string.Format("scope:\"{0}\"", "people") + string.Format(" department:\"{0}\"", deptName);
-
query.SortList.Add("Rank", SortDirection.Ascending);
-
query.SelectProperties.Add("AccountName");
-
query.SelectProperties.Add("FirstName");
-
query.SelectProperties.Add("LastName");
-
query.SelectProperties.Add("JobTitle");
-
query.SelectProperties.Add("WorkEmail");
-
query.SelectProperties.Add("Department");
-
query.SelectProperties.Add("WorkPhone");
-
query.SelectProperties.Add("Fax");
-
query.SelectProperties.Add("UserProfile_GUID");
-
query.SelectProperties.Add("UserName");
-
query.SelectProperties.Add("PreferredName");
-
query.SelectProperties.Add("OfficeNumber");
-
query.SelectProperties.Add("MobilePhone");
-
query.SelectProperties.Add("PIctureURL");
-
query.SelectProperties.Add("WebSite");
-
query.SelectProperties.Add("PublicSiteRedirect");
-
using (ResultTable reader = query.Execute()[ResultType.RelevantResults])
-
{
-
result.Load(reader, LoadOption.OverwriteChanges);
-
}
-
}
-
}
-
return result;
-
}
-
}
Share This
Posted by Adam Buenz
On a recent side project of mine I was writing some SharePoint UserProfile heavy code in order to offer different schemes of showing user data. One of the common methods that I was using was collection building of arbitrary pieces of related user and business structure data, such as building lists of relevant departments assimilated by different data display. While there exist several mechanisms in order to support such a generic call, I have found the Microsoft.Office.Server.Search.Query.KeywordQuery class to be most effective and from a programmatic standpoint exceptionally easy to use (and it’s not just because I think the EnableUrlSmashing property has a nifty name). At a very high level, the KeywordQuery class simply provides the mechanisms in order to execute keyword syntax queries in the same manner as MOSS, returning a DataTable object.
The SDK IMHO adequately covers the innards of the particular classes, so let’s just get down to the code
C#:
-
public static DataTable RetrieveDepartmentNames(string url, int rowLimit, string department)
-
{
-
using (var table = new DataTable ())
-
{
-
using (var site = new SPSite (url ))
-
{
-
using (var query = new KeywordQuery (site ))
-
{
-
query.ResultTypes = ResultType.RelevantResults;
-
query.EnableStemming = true;
-
query.TrimDuplicates = true;
-
query.StartRow = 0;
-
query.RowLimit = rowLimit;
-
query.QueryText = string.Format("scope:\"{0}\"", "people");
-
query.SortList.Add("Rank", SortDirection.Ascending);
-
query.SelectProperties.Add("Department");
-
using (ResultTable reader = query.Execute()[ResultType.RelevantResults])
-
{
-
table.Load(reader, LoadOption.OverwriteChanges);
-
}
-
if (((table.Rows != null)) && (table.Rows.Count> 0))
-
{
-
using (var view = new DataView (table ) {Sort = department, RowFilter = (string. Format("NOT Isnull({0},'') = '' AND NOT {0} = ''", department ))})
-
{
-
return view. ToTable("Department", true, new[] { department });
-
}
-
}
-
}
-
}
-
}
-
return null;
-
}
Important to note is that DataTable objects implement IDisposable since it inherits from MarshalByRefComponent, and even while most consider it unnecessary it is proper to place the references in using statements!
Share This
Posted by Adam Buenz
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.
C#:
-
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!
-
}
Share This
Posted by Adam Buenz
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!).
C#:
-
public static class Extensions
-
{
-
public static Type DoSomething(this Type type)
-
{
-
// let’s get something going!
-
}
-
}
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:
C#:
-
public static class Extensions
-
{
-
public static Type DoSomething(this SPList list)
-
{
-
// let’s get something going!
-
}
-
}
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.
C#:
-
public static class Extensions
-
{
-
public static IEnumerable<SPListItem> 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;
-
}
-
}
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:
C#:
-
public static void TestingExtensionMethod()
-
{
-
SPList list = SPContext.Current.Web.Lists["My List"];
-
var collection = list.HarvestLastFive();
-
// Do whatever you want!
-
}
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 This
Posted by Adam Buenz
Auto-Implemented (or just automatic) properties are one of the new features in C# 3.0 that allow property declaration to be additionally succinct, lessening compulsory code thereby lightening maintenance and increasing readability. Auto-properties make SharePoint code, which tends to be property heavy for personalization features much easier to write, (sure, you can use the "prop" code snippet in VS.NET, however it still will subscribe to the old property structure) read, and maintain.
Firstly, let’s take a basic SharePoint class, OrthodoxWebPartClass in the below, which uses a conventional property declaration with minimal relevant attributes. The class doesn’t do much outside of rendering the text property to the output stream.
C#:
-
public class OrthodoxWebPartClass : WebPart
-
{
-
private string _text;
-
-
[Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("Text ToDisplay"), WebDescription("The Text To Display")]
-
public string Text
-
{
-
get { return _text; }
-
set { _text = value; }
-
}
-
-
protected override void RenderContents(HtmlTextWriter writer)
-
{
-
writer.Write(_text);
-
base.RenderContents(writer);
-
}
-
}
Not very interesting. Examining the above, the property takes on the customary declaration structure of:
C#:
-
private string _property;
-
public string Property
-
{
-
get { return _property; }
-
set { _property = value; }
-
}
Outside of the property attributes (for SharePoint interface instruction) this is 5 lines for declaration, a sizable amount to append to an arbitrary class file.
Automatic properties are instead written in the form of:
C#:
-
public string Property { get; set; }
Taking this construct into our example class file, our WebPart code will take on the form:
C#:
-
public class AutoWebPartClass : WebPart
-
{
-
[Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("Text To Display"), WebDescription("The Text To Display")]
-
public string Text { get; set; }
-
-
protected override void RenderContents(HtmlTextWriter writer)
-
{
-
writer.Write(Text);
-
base.RenderContents(writer);
-
}
-
}
Much trimmer, cleaner code!
Although there is an empty setter and getter, behind the scenes the get_PropertyName and set_PropertyName methods are still being called. The compiler will generate a private field used as the backing store for the property (which is why you can’t use field attributes, but can use property attributes).
What is most important out of the use of auto-properties is the adherence to an ever important OOP concept: encapsulation! There are some things to note however, namely setting a default value and creating read-only properties.
Setting a Default Value for An Auto-Property
Seeing as WebPart properties tend to hold vital configuration values, there should be compensation for assignment of default values. There are two ways for assignment:
Set The Default Value Via Assignment In the Constructor
Set The Default Value Using DefaultValue And The Property Type
In the below, I am demonstrating the assignment of the property within the WebPart constructor:
C#:
-
public class IntializationWebPartClass : WebPart
-
{
-
public IntializationWebPartClass()
-
{
-
Text = "Text";
-
}
-
-
[Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("Text To Display"), WebDescription("The Text To Display")]
-
public string Text { get; set; }
-
-
protected override void RenderContents(HtmlTextWriter writer)
-
{
-
writer.Write(Text);
-
base.RenderContents(writer);
-
}
-
}
Creating a Read-only Automatic Property
Creating a property that is set in the class and will be immutable when used is fairly easy (however a write-only property is obviously not possible). At first glance it might be assumed that simply by removing the set of the property that the property should be read-only, however this will only create a lean on the default value. In order to create a read-property, the private access modifier simply needs to be decorated on the set of the property.
C#:
-
public string Text { get; private set; }
That’s about all I have for now on automatic properties, because they are after all, just properties. However I hope this should get you going using auto-properties in your SharePoint code!
Share This
|