Monday, December 17, 2012

Implementing a jQuery Callback Function for SharePoint

Introduction

It is sometimes useful to be able to subscribe to the successful completion of asynchronous jQuery calls. For example, if you make a call to get data, you may want several events to fire upon successful completion of that call and the events may vary based on what page or area of the site you are on. You could just call those events directly from the asynchronous data call and add conditional logic for each page, but a layer of abstraction allows for more flexible and reusable code. This post will show you how to setup your asynchronous jQuery data calls in a generic way (for example, to be included in your master page) and then setup custom subscriber events that vary by page or page layout.

Generic Subscriber and Data Retrieval Functions

The code below is a function that sets up jQuery callbacks and allows subscribers to add or remove themselves from the callbacks. You would include this in a javascript library on your master page (note that this function is not my creation but comes from here: https://gist.github.com/1321768).

 jQuery.Status = function(id) {  
   var callbacks,  
     status = id && statuses[id];  
   if (!status) {  
     callbacks = jQuery.Callbacks();  
     status = {  
       publish: callbacks.fire,  
       subscribe: callbacks.add,  
       unsubscribe: callbacks.remove  
     };  
     if (id) {  
       statuses[id] = status;  
     }  
   }  
   return status;  
 };  

The code below is a sample ajax data call to a web service that returns json data. If, for example, this data is commonly used throughout your SharePoint farm, you could include a jQuery library on your master page that includes this function.

 function GetData() {  
   $.ajax({  
     type: "GET",  
     url: path,  
     data: {},  
     dataType: "json",  
     timeout: 10000,  
     success: function (data) {  
       //Do Stuff  
       //Publish event  
       $.Status("EventToSubscribeTo").publish();  
     },  
     error: function (xhr, status, error) {  
       alert(error);  
     }  
   });  
 }  

Page or Layout Specific Code

Once you have your master page setup, you could include code on a single page or layout to call the GetData function. You could then subscribe to the successful completion of the GetData function using the code below. The code below subscribes to the successful completion of the "EventToSubscribeTo" function. Once the "EventToSubscribeTo" function is successfully complete, it calls the "EventToFire" function. I do not include code for the "EventToFire" function, but that is where you would add page or layout specific code to manipulate the resulting data call.

 $.Status("EventToSubscribeTo").subscribe(EventToFire);  

Conclusion

Abstracting asynchronous data calls by placing the functions to make those calls in a master page javascript library allows for more flexible and reusable code. You could then call the functions to get the data on a page specific basis and manipulate the data in a custom manner by subscribing to the successful completion of the data call.

Thursday, December 6, 2012

Programmatically Creating a Content Type, Site Column and List in SharePoint

I often find the need to create a new site collection and start throwing objects (lists, content types, etc...) onto it. There are obviously a million ways to do this, but I just thought I would share how I do it.

In this code example, I create a Feature Receiver that inherits from SPFeatureReceiver and overrides the FeatureActivated and FeatureDeactivating methods. In the FeatureActivated method, I create a new SharePoint content type that inherits from item. I then create a new list and site column. finally, I connect them all together.

Note that I use a couple of helper classes. to actually create each item. I do it often enough that I have abstracted it out into a Utility class.

This is the code for FeatureReceiver class. Note that it inherits from SPFeatureReceiver

 
public class FeatureReceiver : SPFeatureReceiver
{
}

Within the FeatureReceiver class, I override the FeatureActivated method. So, when my feature is activated on the site, it will create my content type, list, and site column

 
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
}

Within the FeatureActivated method I go through the work of creating each item and connecting them. I also set a few properties along the way.

 
SPSite site = (SPSite)properties.Feature.Parent;
using (SPWeb web = site.OpenWeb())
{
	//Create a new content type. Note that it inherits from item
	SPContentTypeId itemContentTypeId = new SPContentTypeId("0x01");
	SPContentType myContentType = Utility.CreateSiteContentType(web, "Content Type Name", itemContentTypeId, "Grouping Name for the Custom Content Type");

	//Write the changes to the database
	web.AllowUnsafeUpdates = true;
	myContentType.Update();
	web.AllowUnsafeUpdates = false;

	//Add a single choice field to the site as a site column
	SPField field = Utility.CreateSiteColumn(web, "My Choice Field", SPFieldType.Choice, "My Custom Fields");
	field.Title = "Type of Data";
	field.Description = "Audience : Choice field used to determine whether the requested video is for internal, external or both internal and external dissemination.";

	//Add the new field to the new content type
	Utility.AddFieldToContentType(web, myContentType.Id, field);

	//Write the changes to the database
	web.AllowUnsafeUpdates = true;
	myContentType.Update();
	web.AllowUnsafeUpdates = false;

	//Add a new list to the site
	Guid guid = web.Lists.Add("List Name", "List Description", SPListTemplateType.GenericList);

	//Write the changes to the database
	web.AllowUnsafeUpdates = true;
	web.Update();
	web.AllowUnsafeUpdates = false;

	//Add the new content type to the new list
	SPList myList = web.Lists.GetList(guid, false);
	myList.ContentTypesEnabled = true;
	myList.ContentTypes.Add(myContentType);

	//Add a couple of event receivers to the list 
	myList.EventReceivers.Add(SPEventReceiverType.ItemAdded, "[DLLName], Version=1.0.0.0, Culture=neutral, PublicKeyToken=[DLL Key Token]", "[Namespace].[MethodName]");
	myList.EventReceivers.Add(SPEventReceiverType.ItemUpdating, "[DLLName], Version=1.0.0.0, Culture=neutral, PublicKeyToken=pDLL Key Token]", "[Namespace].[MethodName]");

	//Change some of the properties on the list
	myList.EnableAttachments = false;
	myList.EnableFolderCreation = false;
	myList.EnableVersioning = true;
	myList.ForceCheckout = false;

	//Write the changes to the database
	web.AllowUnsafeUpdates = true;
	myList.Update();
	web.AllowUnsafeUpdates = false;
}

I also override the FeatureDeactivating method and clean everything up when the feature is deactivated. Depending on your environment and what you are using this for, you may not want to do this. It will delete your data.

 
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
	try
	{
		SPSite site = (SPSite) properties.Feature.Parent;
		using (SPWeb web = site.OpenWeb())
		{
			//Delete the list.
			//Note that if the list is not there
			//it throws an Argument Exception.
			//We trap it and ignore it.
			try
			{
				web.Lists["List Name"].Delete();
				web.AllowUnsafeUpdates = true;
				web.Update();
				web.AllowUnsafeUpdates = false;
			}
			catch (ArgumentException)
			{				}

			//Delete the content type. 
			//Note that if the content type is not there
			//it throws an Null Reference Exception.
			//We trap it and ignore it.
			try
			{
				web.ContentTypes["Content Type Name"].Delete();
				web.AllowUnsafeUpdates = true;
				web.Update();
				web.AllowUnsafeUpdates = false;
			}
			catch (NullReferenceException)
			{				}

			//Loop through the fields in My Custom Group
			//and delete them
			for (int i = 0; i < web.Fields.Count; i++)
			{
				if (web.Fields[i].Group == "My Custom Fields")
					web.Fields[i].Delete();
			}
		}
	}
	catch (Exception exception)
	{
		//Insert code to write the error to the log
	}
}

This utility class provides a couple of methods for creating a content type, site column and adding the site column to the content type. My actual implementation of this has several overloaded versions of each method for various purposes.

public static class Utility
{
	public static SPContentType CreateSiteContentType(SPWeb web, string contentTypeName,
		SPContentTypeId parentItemCTypeId, string group)
	{
		if (web.AvailableContentTypes[contentTypeName] == null)
		{
			SPContentType itemCType = web.AvailableContentTypes[parentItemCTypeId];
			SPContentType contentType = 
				new SPContentType(itemCType, web.ContentTypes, contentTypeName) {Group = @group};
			web.ContentTypes.Add(contentType);
			contentType.Update();
			return contentType;
		}
		return web.ContentTypes[contentTypeName];
	}

	public static SPField CreateSiteColumn(SPWeb web, string displayName,
		SPFieldType fieldType, string groupDescriptor)
	{
		if (!web.Fields.ContainsField(displayName))
		{
			string fieldName = web.Fields.Add(displayName, fieldType, false);
			SPField field = web.Fields.GetFieldByInternalName(fieldName);
			field.Group = groupDescriptor;
			field.Update();
			return field;
		}
		return web.Fields[displayName];
	}
		
	public static void AddFieldToContentType(SPWeb web,
		SPContentTypeId contentTypeId, SPField field)
	{
		SPContentType contentType = web.ContentTypes[contentTypeId];
		if (contentType == null) return;
		if (contentType.Fields.ContainsField(field.Title)) return;
		SPFieldLink fieldLink = new SPFieldLink(field);
		contentType.FieldLinks.Add(fieldLink);
		contentType.Update();
	}
}

As always comments and feedback are welcome. Enjoy!

Wednesday, September 19, 2012

SharePoint Development: The Way it Was, Is, and Will Be


The Way It Was

SharePoint development was pretty much always a painful exercise that only the truly masochistic enjoyed. If you actually enjoyed finding and installing a variety of tools and scripts to package and deploy your solutions, there was always the woefully inefficient process of tracking down a particular error, or the documentation that never seemed to tell you what the sealed class actually did, or the IDE that kept crashing, or the seemingly never-ending process of getting your environment "just right".

It has been known to happen that, after installing Windows Server 2003 and SharePoint 2007 on a dedicated SharePoint development box and tweaking the environment for days, the whole thing explodes in a microsecond because the hard drive went bad, the wrong thing was tweaked, there was a power surge...whatever. Development boxes weren't backed up. Or if they were, the process of restoring it was more painful than just rebuilding it.

So much time was wasted...

The Way It Is

Visual Studio has come a long way. We now have simple F5 deployment for our development environment. We have correlation ids to help us find our errors. We can now install SharePoint on the consumer Operating System rather than a server operating system. Documentation is much better. Visual Studio is far more stable and developer friendly.

Oh, and there are virtual machines. I can create an environment, get it just right, then snapshot it and save it somewhere safe...on a NAS, on a special backup drive, or in my pocket.

But a lot of time is still wasted...

The Way It Will Be

Windows 8, Azure, TFS Online, and Visual Studio 2012 changes the game.

Most decent sized companies have multiple SharePoint environments. They may have an Extranet, an Intranet, corresponding development and test environments, and various other pilot SharePoint installations.

One day soon SharePoint developers, after logging into TFS online and checking their task list, will do one of two things:
  1. Within a few minutes, they will download the latest VHDs (Hyper-V VMs) they need from a cloud or on premises source, spin them up on their Windows 8 machine and start developing.
  2. Within a few seconds, they will login to Azure and spin up the latest VHDs they need and start developing.
The way of the development world is changing. Clients and consumers want their software and they want it now. They don't want to wait for developers to fiddle with their environments and add-ins. They don't want  to wait for developers to get "ramped up". They don't want to wait for anything. Whether or not you agree with this, it is the reality. Software development has become an iterative process and the iterations are getting shorter and shorter.

Somasegar, Corporate Vice President of the Developer Division at Microsoft, stated the issue clearly in his blog recently, "as your customers evolve, so too do your apps, requiring you to continuously improve and incorporate innovations faster than ever before, with continuous feedback, continuous quality, and continuous delivery." (http://blogs.msdn.com/b/somasegar/archive/2012/09/12/visual-studio-2012-and-net-4-5-launch.aspx)

Microsoft is adapting. Visual Studio will receive more "regular updates" with new enhancements and features. Azure is constantly evolving and improving it's product. A Microsoft SharePoint Product Manager recently stated that SharePoint will be receiving more "iterative updates".  The 2-3 year major software release cycle is dead.

The evolution of software development starts with the developer and the process they follow:
  1. TFS Online (available now as TFS Preview: https://tfspreview.com/) means that your entire code base is available almost immediately.
  2. Azure means that SharePoint virtual machines (setup to your environment specs) will be available within minutes. For reference, Microsoft has released a white paper on the subject: http://www.microsoft.com/en-us/download/details.aspx?id=34598
  3. In combination with the above, Visual Studio provides virtually everything you need to start developing almost instantly.
There is virtually no internal infrastructure. There is virtually 100% up time. Recovery and availability comes part and parcel with TFS Online and Azure.

So, stop wasting time and start churning out software that your clients will love...Do it NOW!

Monday, August 27, 2012

SharePoint 2010 Development in Visual Studio 2012

There is plenty to get excited about for SharePoint 2010 developers with Visual Studio 2012. A new content type designer, a more intuitive template structure and Javascript intellisense are a few of the things that will make most of our lives a little easier. Below, I outline a few of the new features for SharePoint 2010 developers in Visual Studio 2012.

Content Type Designer
Content types are a critical component of SharePoint development. Unfortunately, they have a legacy of a rather unusual inheritance structure. Inheritance is done through the content type id. This is a nuisance for SharePoint developers that have to remember content type ids or constantly look them up. Now there is a Content Type item template and designer that provides a nice little drop down for setting up inheritance:



Once you have selected what content type you would like to inherit from, you are presented with a nice little designer. While I am not a huge fan of many of the Visual Studio designers, I do like this one because it simplifies the rather mundane task of adding columns to your content type.


Note that this designer builds out a declarative content type. Also note that if you add a new site column using the new site column item template, the site column is immediately available for selection in the content type designer.

I did notice some quirky behavior. For example, when I double click on the elements.xml file for the content type in order to view the raw xml, I am presented with a dialog box that tells me the file is already open (even though it is not) and asks me if I want to close it. If I click yes, the raw xml is opened and the designer closes. That is what I wanted, but the dialog was a little confusing.

Streamlined Templates
Many of the SharePoint 2010 project templates were moved to item templates. This more closely aligns the templates with how SharePoint developers setup their projects and solutions. In Visual Studio 2010 most of us got in the habit of creating a blank SharePoint project and building from there. In Visual Studio, you will select the "SharePoint 2010 Project" template instead, which really isn't much different, but a lot of the noise has been reduced.

There are now just a few SharePoint 2010 project templates. Below are the templates available in Visual Studio 2012 out of the box.



Most of the templates are now at the item level. Below are the SharePoint 2010 item templates available in Visual Studio 2012 out of the box.



Note that the item level templates now specify whether they are available as Sandbox solutions ("Farm Solution only").

You can find all of the documentation on the SharePoint 2010 templates available in Visual Studio 2012 here: http://msdn.microsoft.com/en-us/library/ee231554.aspx

Javascript Intellisense
If you work with Javascript on a regular basis, you probably have a tool that provides Javascript intellisense (I personally love ReSharper by JetBrains). But if Visual Studio 2012 can provide it as part of the built in functionality...even better.

 

What Else
There is a new, lightweight find bar (I was always moving my find window around in Visual Studio 2010 because it was so big and clunky).


Project managers will love the much improved Agile and Scrum templates for Team Foundation Server 2012. And, of course, Visual Studio 2012 integrates perfectly with them. You can update work items, track bugs, manage builds, and even set alerts all from the comfortable confines of Visual Studio 2012.

Visual Studio 2012 officially launches on September 12 but is available now (http://www.microsoft.com/visualstudio/11/en-us). If you haven't already tried it, you should. I think you will like it.

Tuesday, August 7, 2012

Creating a Custom E-mail Notification Solution for SharePoint 2010

In this post I outline a possible solution for a custom e-mail notification system built on SharePoint Server 2010.

Requirements

  • The notification system must allow for fully branded and customized e-mails.
  • Administrators and Designers must be allowed to easily modify branding elements and content within each e-mail notification.
  • Each e-mail notification must allow for personalized dynamic content (for example, recipient name, address, etc...).
  • Some e-mail notifications will be time delayed or scheduled.
Our task is to create a scalable n-tier code solution that will allow other developers to easily generate custom e-mails using predefined templates.

High Level Process Flow

The high level process flow will look something like this:


Some type of web based activity on SharePoint 2010 will trigger the need for a notification. We don't really care what the activity is for our task. We just need to provide other developers some way of plugging into the e-mail notification framework that we are building. Once an activity is triggered, we need to know two things (these are our inputs):
  1. Which e-mail template to use
  2. The values of any personalized properties for the notification (for example, the e-mail address to which the e-mail will be sent).

Data Layer

You could probably set this up a hundred different ways. For my purposes and for this example, I created two tables and a SharePoint document library.

SharePoint Document Library

The SharePoint document library stores an html file for each e-mail template. The example file I will use is a temporary password e-mail. The file, called TemporaryPasswordEmailTemplate.html looks like something this:

[ a bunch of branding stuff]
Your temporary password is: #!#TEMPORARYPASSWORD#!#
[further instructions, disclaimers, and more branding]

#!#TEMPORARYPASSWORD#!# is the replacement key. The code will look for and replace that key with the actual temporary password at the time the e-mail is generated.

Also in the SharePoint document library is a column for the template name. In this example, the template name is TempPassword. The template name in the document library tells the code which replacement keys to look for.

EmailTemplateConfiguration Table

The EmailTemplateConfigurationTable has two relevant columns:
  • TemplateId: the template id
  • Key: the name of a replacement key contained in the template
In this example we have one entry (but there could be as many as needed):
  • TemplateId: 2
  • Key: TemporaryPassword

Email Table

This table stores all outgoing e-mails. A timer job picks up any unsent e-mail and sends it. It has columns for To, From, Subject, Body, ScheduledSendTime, ActualSendTime, etc...

Base Layer

The base layer contains an enum for EmailTemplateType and an abstract class that the business layer will inherit. The abstract class does the heavy lifting.

EmailTemplateType Enum

First, I create an enum for the e-mail template types. Right now, we just have two (an undefined default type and an e-mail type for sending out a temporary password).

    public enum EmailTemplateType : int
    {
        Undefined = 0,
        TempPassword = 1
    }

CustomEmailMessage Abstract Class

Next I create an abstract class that will do most of the work of constructing the e-mails. The idea is that a new class will be created for each e-mail type (the implementation classes). Each new class will inherit the core functionality from the abstract class. The implementations will set the template type in the constructor. Properties on each of the implementations will set the values of dynamic content (if any). The implementations will then call the SendMail method (added later in this post) to do the work of constructing the e-mail and sending it out.

    public abstract class CustomEmailMessage : MailMessage
    {
         //Placeholder
    }

Note that the CustomEmailMessage abstract class inherits from System.Net.Mail.MailMessage. We will use the functionality in that class to set the To, From, Subject, and Body properties rather than create them ourselves.
Next I add the appropriate properties to the abstract class:
   
    public abstract class CustomEmailMessage : MailMessage
    {     
        private EmailTemplateType _type = EmailTemplateType.Undefined;
        private StringDictionary _replacementTags = new StringDictionary();
        private DateTime _sendDateTime = DateTime.Now;
        
        public EmailTemplateType TemplateType
        {
            get { return _type; }
            set { _type = value; }
        }
    }

The _type will be used to determine the e-mail template that we are going to use. The constructor of the implementation class will set the TemplateType property. Notice that it is of type EmailTemplateType (the enum created above).

The _replacementTags StringDictionary will be used to place personalized content in the e-mail templates. Each e-mail template with personalized content will contain placeholder keys. The placeholder keys will correspond to properties in the implementation class. At run time, the implementation class will set those properties and, when the SendEmail method is called, the base class will match up the properties with the appropriate keys in the template.

The _sendDateTime will be used to queue up e-mails that need to be scheduled for a certain time in the future.

Next I stub out the methods:
   
    public abstract class CustomEmailMessage : MailMessage
    {     
        private EmailTemplateType _type = EmailTemplateType.Undefined;
        private StringDictionary _replacementTags = new StringDictionary();
        private DateTime _sendDateTime = DateTime.Now;
        
        public EmailTemplateType TemplateType
        {
            get { return _type; }
            set { _type = value; }
        }
        
        public virtual void GetReplacementKeys()
        {
            //Placeholder
        }

        public virtual void GetReplacementValues(object sender)
        {
            //Placeholder
        }

        public virtual void GetTemplateHtml()
        {
            //Placeholder
        }

        public virtual void ReplaceTags()
        {
            //Placeholder
        }

        public virtual void WriteEmailToDB()
        {
            //Placeholder
        }

        public virtual void SendEmail()
        {
            //Placeholder
        }
    }

GetReplacementKeys
GetReplacementKeys does just as the name suggests. It populates _replacementTags with the appropriate keys. It's a StringDictionary so it is stored in key/value pairs. At this point we are just populating the keys. I won't include the code here, because I have a data layer with another level of abstraction that doesn't suit this walk through. The simplest way to do this, though is to create a SharePoint list with a column for TemplateType (_type) and a column for Key. Use the _type to pull the appropriate keys and add them to the StringDictionary _replacementTags.

GetReplacementValues
This method is a little trickier. We are going to use reflection to get the values of the implementing method's properties and match them up with the keys in _replacementTags. The code looks like this:
    public virtual void GetReplacementValues (object sender)
    {
        PropertyInfo[] propertyInfos = this.GetType().GetProperties();
        foreach (PropertyInfo propertyInfo in propertyInfos)
        {
             object _internal = propertyInfo.GetValue(sender, null);
             if (_internal != null)
             {
                  if(_internal.GetType() == typeof(string))
                  {
                       _replacementTags[Globals.Delimiter + 
                           propertyInfo.Name.ToLowerInvariant() +
                           Globals.Delimiter] =
                           (string)_internal;
                  }
             }
        }           
    }

The caller of this method is actually the SendEmail method (which we will get to shortly). It passes in "this" as the sender object used in the GetReplacementValues method above.

Next, I get all the properties of the implementation object and put them into a PropertyInfo array. I enumerate through the array and extract the values from the sender object. As long as the values are not null and are of type string, I add them to the _replacementTags StringDictionary using the property name (plus a delimiter) as the key.

So this is important...in this setup, the property names on the implementation object must match the keys stored for the EmailTemplateType and they must match the replacement values in the html markup.

Note Globals.Delimiter. I have a class in my code for global variables. I have to use some kind of delimiter in the html markup to denote a replacement key. In this example, our delimiter is "#!#". The markup includes the delimiter but the stored keys don't. I add it here.

GetTemplateHtml
This method is pretty simple...go get the template html file and put it in the Body property (the Body property is part of the inherited MailMessage class. I store the template html files in a document library with a custom column to denote which EmailTemplateType the file corresponds to. Sparing you all the code to get the appropriate document library item, here is the most important line:
    Body = web.GetFileAsString(items[0].File.ToString());
ReplaceTags
Once I have all the appropriate template in the Body property and I have the key/value pairs in the _replacementTags StringDictionary, it's time to actually replace the tags:

    public virtual void ReplaceTags()
    {
        foreach (string key in _replacementTags.Keys)
        {
             Body = Body.Replace(key.ToUpperInvariant(), _replacementTags[key]);
        }
    }

WriteEmailToDB
Now I write the e-mail to a SQL database and a timer job picks it up and sends it.
    public virtual void WriteEmailToDB()
    {
        emailHelper.WriteToDB(To.ToString(), From.ToString(), Subject, Body,
            _sendDateTime);
    }

Note that I use a helper class. I don't include the code that actually writes the data to the table in this post.

SendEmail
Finally, the SendEmail method pulls it all together:

    public virtual void SendEmail(DateTime sendDateTime)
    {
        _sendDateTime = sendDateTime;

        GetReplacementKeys();
        GetReplacementValues(this);
        GetTemplateHtml()l
        ReplaceTags();
        WriteEmailToDB();
    }

Business Layer

Every time I create a new e-mail type, I will add an entry to the EmailTemplateType enum, create appropriate rows on the EmailTemplateConfiguration table, add the template html to the SharePoint document library, and create a class in the business layer that inherits from the CustomEmailMessage abstract class. For this example, I create a Temporary Password e-mail. My business layer implementation looks like this:
    public class TempPasswordEmail : CustomEmailMessage
    {
        public string TemporaryPassword { get; set; }
        
        public TempPassword()
        {
             TemplateType = EmailTemplateType.TempPassword;
             base.Subject = "Your Temporary Password";
             base.From = new MailAddress("SharePointDoug@doughemminger.com");
        }
    }

In this example, I know that the From and the Subject are going to be the same for every instance of the TempPassword class. So, I set them in the constructor.

UI Layer

When the user clicks a button to request a temporary password, the process triggers a notification to the user. Assuming the temporary password is appropriately generated and stored in the variable "x" and the user's email address is stored in the variable "userEmail" we would trigger a notification like this:

    TempPasswordEmail tempPasswordEmail = new TempPasswordEmail();
    tempPasswordEmail.To = userEmail;
    tempPasswordEmail.TemporaryPassword = x;
    tempPasswordEmail.SendEmail(DateTime.Now);

Wrap-Up

There are a few disadvantages and things to note about this approach:
  • A new e-mail type (for example, if we were to add an e-mail type for workflow notifications), requires a code change. An enum value has to be added at Base layer and implementations have to be added at the business layer and possibly at the UI layer.
  • I intentionally left out all of the try/catches and RunWithElevatedPrivileges. Add where appropriate if you use this code.
  • The properties in the business layer implementations must match the Keys stored in the data layer. In this example TemporaryPassword matches exactly at the business layer and the data layer
  • The replacement keys in the html markup must be all uppercase. In this example, #!#TEMPORARYPASSWORD#!# is all uppercase.
There are many advantages to this approach:
  • New e-mail types are added relatively easily (even though they require a code change). And once a new e-mail type is created, it can be easily implemented wherever you need it.
  • Storing the e-mail templates as html in a document library allows designers to mock-up and make changes to the templates as needed. In my real-world implementation we use header and footer html files to store CSS, logo, and disclaimer information for all e-mails.
  • It is fairly straightforward to implement dynamic content by using replacement keys in the html markup and the e-mail implementations.
  • Any of the methods in the abstract class can be overridden. If for, example, there were a use case to bypass the timer job and send the e-mail immediately, you could override the SendMail method, call all of the appropriate methods that are already there except the WriteEmailToDB method.
 
 

Wednesday, July 18, 2012

Installing SharePoint 2013 Preview in 3 Easy Steps

First, A few caveats

This was a quick installation. From start to finish, including time for downloads and windows updates, it took about 4.5 hours. I intended it to be a developer environment...not a production or even QA quality installation. I just wanted an environment up and running as quickly as possible.

Also, I do not outline every button I clicked in the three easy steps below. But, I did take time to highlight the important steps.

So, here they are...3 easy steps

1) Install Windows Server 2008 R2 SP1 Standard Edition

I started with a Windows Server 2008 R2 SP1 Standard Edition (x64) iso file. I provisioned a new VM in VMWare on a Laptop using the iso file. I gave it 1 CPU with 4 cores , 12 GB of RAM, and 150 GB of hard disk space.

After the OS was installed, I did all the usual things:
  • Enabled RDP
  • Ran Windows Update
  • Etc...
One thing of special note...I manually enabled the Web Server Role on the server so that .Net 3.5 would be installed. I then ran Windows Update again.

2) Install SQL Server 2012 Standard Edition

I started with the SQL Server 2012 Standard Edition (x64) iso file. I mounted the file on a virtual drive and ran through the setup. If you already installed the web server role, you should have no issues.

3) Install SharePoint Server 2013 Preview

I started with the SharePoint Server 2013 Preview img file. I mounted the file on my VM and first ran the prerequisite installer.

I then installed the three hotfixes highlighted in this document:
http://technet.microsoft.com/en-US/library/cc263202(v=office.15).aspx

For your reference, the 3 Hotfixes that need to be installed after the prerequisites are installed are linked below:

http://go.microsoft.com/fwlink/p/?LinkId=254221
http://go.microsoft.com/fwlink/p/?LinkID=254222
http://go.microsoft.com/fwlink/p/?LinkId=254227

I then started the SharePoint Server 2013 installation.

The installation completed and a few clicks later, the configuration wizard was running.

After the configuration wizard was complete, I created a web application and a site collection with a Team Site and viola!



Friday, June 1, 2012

Visual Studio 2012 Release Candidate - A SharePoint Developer's Initial Perspective

Out of the box, there are no new project templates for SharePoint 2010 in Visual Studio 2012 RC


Notice also that there are no SharePoint 2007 templates. It is unclear to me at this point if SharePoint 2007 templates will be available at some point in the future as a separate download. I doubt it.

For some reason, I feel like Microsoft is yelling at me when I look at the all caps menus:


A cursory review of the menus reveals that there appear to be a few things that make life a little simpler for us developers. For example, Create GUID is already in the tools menu. No need to add it (like in previous versions of Visual Studio):


Once I create a SharePoint project and add a new item, there are several new options to choose from:


I picked the Site Column template just to see what it looked like. After clicking OK, it created a Declarative Site Column in XML and added it to the project feature:


The feature and package designers both seem to have been slightly redesigned. The tabs are at the top, for example, which makes a lot more sense. And there is more room at the bottom to make customizations to the manifest:


Adding a content type was fun. I was surprised to see this handy little content type designer:


This is, of course, nice because it asks you what content type you want to inherit from and creates the XML - including the Id - for you:


Just for fun I added a javascript file to test it out and found some nice little interface improvements (functions are automatically collapsible, for example).

There is obviously a lot more to explore but overall, my initial impression is positive. The product is continuing to evolve and become more mature.

Friday, April 20, 2012

SharePoint Development - Process

Once an organization has made a decision to develop on SharePoint (see The Decision to Develop on SharePoint) and has collected the right people (see SharePoint Development - People), it's time to figure out how to get the work done...the process. A future post will focus on tools and technology. Note that this post is part of a series of posts on the topic of setting up an organization infrastructure that supports SharePoint development. Here are the parts to this series (this post is part 3):


  • Part 1: The Decision to Develop on SharePoint
  • Part 2: SharePoint Development - People
  • Part 3: SharePoint Development - Process (this post)
  • Part 4: SharePoint Development - Technology (coming soon)

  • Introduction
    For most situations involving SharePoint development, I advocate some form of an Agile process. This post will go into detail about what an Agile process is, why it is usually better than a traditional approach, and how to implement your own version of Agile for SharePoint development. It is important to understand that, although this is a long post, and there are lots of links to external resources, I am just barely scratching the surface. Agile is an iterative approach to development that requires a commitment to continuous improvement of the process itself. That means that there is no end state. There is no best practice. Every organization has to adopt the form of Agile that works best for their organization, and then work to continuously adapt and improve on it as they go. I encourage you to explore the links in this article and seek out your own resources. There is no shortage of good information about Agile.

    What is Agile?
    I am going to borrow Wikipedia definition of Agile. This definition can be found here: Wikipedia Definition of Agile and is copied below (in part) for the convenience of discussion. It is a good starting point.

    "Agile is a group of software development methods based on iterative and incremental development, where requirements and solutions evolve through collaboration between self-organizing, cross-functional teams. It promotes adaptive planning, evolutionary development and delivery, a time-boxed iterative approach, and encourages rapid and flexible response to change."

    Below, I am going to highlight three parts to the Wikipedia definition that I think are particularly important.

    "Software development methods"
    Agile does not tell you what to do. In most respects, it does not tell you how to do it either. Agile provides a Manifesto and Principles. It is up to the organization to adopt a particular methodology, a hybrid of methodologies, or even invent their own methodology to come up with the how.

    "Collaboration"
    It is worth talking about collaboration briefly because it is such an important part of Agile. It is not just a token word in the definition, "Close, daily co-operation between business people and developers" (from the Agile Principles) is one of the key underlying principles of Agile. Because Agile is "iterative" and "incremental" Agile developers have to constantly be working with the business to understand changing requirements and an evolving set of circumstances. In fact, some of the Agile methodologies posit that a team is most effective when they are all sitting and working in the same physical location. Casual conversations, quick questions, and ad-hoc problem solving are the cornerstone of collaboration in an Agile environment.

    "Iterative and Incremental"
    The first underlying principle in Agile is "Customer satisfaction by rapid delivery of useful software." "Rapid delivery of useful software" is the key way to achieve customer satisfaction with Agile. Along those lines, the ideas of "welcome changing requirements, even late in development" (the second principle) and "Working software is delivered frequently" (the third principle) both underscore the importance of adapting to change and doing it quickly. Through collaboration and an iterative, incremental approach developers and businesses are able to quickly adapt to changing needs because they are collaborating and delivering software incrementally. Each increment of software delivered can be changed to accommodate new specifications.

    Why Agile?
    In order to help understand why we should even consider an Agile methodology for SharePoint development, I am going to highlight a case study of Salesforce.com, point you to some research, and appeal to common sense.

    Salesforce.com Case Study
    In 1999, Salesforce.com started their business of developing Software as a Service (SaaS). They had a handful of developers and used a traditional Waterfall approach to development. By 2006, they had over 150 developers. Their software development life cycle had ground to a virtual halt. They were only releasing one major update per year. Their customers were not happy because Salesforce.com was not responding to customer needs in a timely fashion. Salesforce.com employees were not happy, in part, because they hardly ever got to see their work come to fruition. A lot of this is documented in a Stanford case study here: Salesforce.com: The Development Dilemma . In 2006, Salesforce.com dove headfirst into their own version of an Agile methodology called ADM. They created roughly 30 teams with 6-10 members each. Three one-month Sprints made up their first release cycle. Within the first nine months of implementing ADM, Salesforce.com delivered on 60+ "critical" features. Customers were getting features delivered in roughly half the time as before. Salesforce.com delivered the results of their Agile transformation at a conference in 2007. The slide presentation can be found here: Salesforce.com Agile Transformation . The results are hard to argue.

    Research
    In his book, "Succeeding with Agile Development", Mike Cohn does a survey of the research done to illustrate the benefits of Agile over traditional approaches. The results are overwhelmingly in favor of a well-implemented Agile approach to software development. I am not going to list out all the details here. Please see Mike Cohn's book if you are interested in the details. Just know that studies have shown that Agile produces higher quality work, quickly.

    Common Sense
    If the Salesforce.com case study and the research highlighted in Mike Cohn's book isn't enough, common sense and logic should bring home the point. Software developers provide a service to their customers. They write software that provides some business benefit to their customers. In order to best service those customers and provide the most business benefit possible, developers need to listen to and understand their customers' needs and then deliver software to help them with those needs. They need to do this as quickly as possible. That is the essence of Agile. Do this repeatedly and you will have succeeded in implementing at a minimum your own form of an Agile approach to software development.

    How?
    I am going to outline a simple Agile/Scrum approach that I have used in the past for SharePoint software development. Every organization is going to have their own nuances to Agile. What is important is that the essence of the Manifesto and Principles are respected.

    Start with a Product Backlog. The product backlog defines, usually in the form of User Stories, what will be delivered. The Product Owner, with the help of business users, create the User Stores. Using older terminology, these are the requirements. The Product Owner, with the help of the business users and the key stakeholders then prioritize the items on the Product Backlog.

    Then you define your Sprint Backlog. The Sprint Backlog defines, usually in the form of tasks, how each item on the Product Backlog will be delivered. Sprints are usually 2-4 weeks in duration. The Sprint Backlog is created by the development team. Each item on the Sprint is estimated with a number of hours. Each Sprint lasts roughly 2-4 weeks. Items from the Product Backlog are added to the Sprint Backlog and estimated in priority order until resources are at full capacity for the Sprint duration.

    During the Sprint, developers meeting on a daily basis for a short meeting to discuss any roadblocks or problems they are encountering. This meeting is facilitated by the ScrumMaster, whose job it is to remove roadblocks and help problem solve. The progress on the Sprint Backlog is typically tracked using the Sprint Burndown chart. A typical Sprint Burndown chart looks something like this:


    At the end of the Sprint, the new code is deployed and there is usually a Sprint Review Meeting to discuss how things could be improved.

    Agile for SharePoint
    Agile is rapidly gaining in popularity among software shops of all types. And for good reason. It's time it worked it's way into SharePoint development. Most companies that implement SharePoint don't realize or understand the path they are taking when they start down the path of custom SharePoint development. Assuming, however, that you are there (you either have custom SharePoint solutions to support or have undertaken a new project to implement a custom solution), you should select the software development methodology that has thus far, in my opinion, proven most successful.

    Agile for SharePoint can be implemented as a comprehensive process solution for software development at companies that have extensive custom development needs and large teams of developers. Or it could be implemented by 1 developer who just wants to follow the manifesto and 12 principles when working with his SharePoint business users. The results should be the same: the consistent, rapid delivery of valuable software.

    What's Next
    In the final blog post for this series, I will detail some of the tools and technology used to develop in SharePoint. Most of the tools and technology I focus on will be from a process perspective. That is, I am not going to show you how to build a SharePoint solution in Visual Studio. However, I will show you how to track your progress on your Sprint using Visual Studio Scrum plug ins.

    Monday, April 16, 2012

    On Saturday, April 14, I spoke at the Twin Cities SharePoint Saturday. The topic was an introduction to Agile development methodologies for SharePoint. Here is the presentation. Enjoy!

    Sunday, February 5, 2012

    SharePoint Development - People

    Once an organization has made a decision to develop on SharePoint (see The Decision to Develop on SharePoint), it's time to start putting into place the necessary infrastructure. This blog post will focus on the People considerations. Future posts will focus on Process and Technology. Note that this post is part of a series of posts on the topic of setting up an organization infrastructure that supports SharePoint development. Here are the parts to this series (this post is part 2):
    Collaboration
    The traditional stereotype of a software developer is that that they are antisocial nerds. The problem with this stereotype is that while likely applicable at some point in the past, today it is largely untrue. A study in the Global Journal of Engineering Education of Cuban software developers demonstrated that, among the sample population, 26% of the developers were ESTJ on the Meyers-Briggs scale:


    Compare this to 8%-12% for the general population in the United States (from Wikipedia):


    This implies that software developers are largely more outgoing and task oriented than the general population. While the study was only Cuban software developers, I would expect that populations of software developers would have a similar profile.

    Nowadays, software development is very much a collaborative effort, which means that developers have to have social skills that facilitate communicating effectively and efficiently with all interested parties. Microsoft Research has done some work on this. Their article on Human Interactions in Programming states that "software development is done by people working together." The article goes on to emphasize the collaborative nature of successful software development.

    When setting up infrastructure that supports SharePoint development, an organization should strive to find outgoing, well-adjusted, experienced developers and give them the the tools and resources they need to work in a highly collaborative environment.

    Grady Booch, one of the creators of UML (Unified Modeling Language) is credited with coining the term "Collaborative Development Environment" (CDE). Generally considered an evolution from the Integrated Development Environment, a CDE is a seamless integration between development environments, communication tools and collaboration tools that all the involved parties can use. It applies specifically to tools but can be extrapolated to the entire way of working for a developer. On any given project, a developer may make thousands of tiny decisions that aren't documented but may (taken together) affect the overall outcome of the project. In order to facilitate a process that helps developers make decisions that meet or exceed the goals of a project, organizations should support and encourage strong communication ties (physical proximity, instant messaging, screen share, video conferencing, etc...) not only between each other but also between each other and the end users. A strong feedback loop is critical.

    So what does all this mean?

    Ideally, for any given project, there is a team of resources 100% dedicated to the project, all sitting in an open work area together collaborating to achieve project goals. To maximize the chances for success, the team should be made up of a diverse group of smart people that can communicate effectively and efficiently. Interestingly, although to this point I have cited nothing about process, we are starting to venture into the sweet spot for Agile, which will be covered in the next post in this series.

    Technical Proficiency
    SharePoint development generally requires a diverse set of skills. It's important to remember, however, if an organization has a highly collaborative environment, not every developer has to have all the skills. In fact, on some projects, it is impossible for one person to have all the required SharePoint skills for the project.

    Eric White from Microsoft details the comprehensive set of developer skills for SharePoint 2010 in a two part article. Here is a link to part 1: http://msdn.microsoft.com/en-us/library/gg454784.aspx. For convenience, listed below are the technical skills I've identified that are important for SharePoint 2010 developers. Note that these match up pretty closely to to Eric's article but for a more thorough explanation of the skills listed, please see Eric's article:
    • C#
    • LINQ (and CAML)
    • WCF
    • ASP.Net
    • XML/XSLT
    • html/CSS
    • javascript/jQuery
    • REST
    • SharePoint Client Object Model
    • Silverlight/XAML
    • PowerShell
    It is important to understand that, in many cases, the skills will be divided among multiple people. One logical division is client-side skills vs server-side skills as follows:


    In addition to the technical development skills, however, a developer needs to understand various components of the SharePoint architecture. The following article from Ricky Kirkham of Microsoft does a good job of outlining the SharePoint 2010 architectures: http://msdn.microsoft.com/en-us/library/gg552610.aspx. Again, for convenience, I listed the ones I think are important.
    • Authentication & Security (WIF, Directory Providers)
    • Search
    • Services (User Profile Synchronization, Excel, Access)
    • Workflow
    • Business Connectivity Services and Business Intelligence
    • Social Collaboration
    • Governance
    • Disaster Recovery
    • Taxonomy
    Once again, in many cases, the skills will be divided among multiple people.

    Summary
    When building a team of SharePoint 2010 developers, you want to setup a collaborative environment and hire outstanding communicators that can work effectively and efficiently in that environment. In addition, the developers should have a strong mix of technical skills and understand various components of SharePoint architecture. Easy, right?

    In the next post, I will focus on process. You have made your decision to develop on SharePoint and have hired the right people. Next it will be time to talk about how they will get the work done.

    Friday, January 13, 2012

    The SharePoint Development Decision

    Parts to this Series (this is Part 1)
    Part 1: The Decision to Develop on SharePoint
    Part 2: SharePoint Development - People
    Part 3: SharePoint Development - Process (coming soon)
    Part 4: SharePoint Development - Technology (coming soon)

    About this Series
    Custom application development is rapidly evolving into a standard subset of an organization's Information Systems infrastructure. It has been a part of most larger organizations for many years now, but I am seeing it rapidly permeate into the lower tiers of organization size. This post will, at a high level, focus on what it means for an organization to have its own application development group--how I think it should be structured and how SharePoint development fits into the picture.

    Organizations to Which this Series Applies
    The scope of organizations covered in this series is small to medium size businesses (roughly 50 to 5,000 people) whose primary business does not involve the development and delivery of software products to it's customers. That is, they are not a software development company and they are not large.

    This post is also geared towards organizations that have made a strategic decision to use Microsoft and related technologies as the foundation for its software development and IT infrastructure. That is, from a development perspective, they are primarily .Net shops.

    Definition of Customization
    Note that, for this series, I am not defining customization as anything done in SharePoint Designer, through standard web parts, or what many are calling the "Middle-Tier" of SharePoint. For the purpose of this series, I am defining customization as something that uses the SharePoint server-side object model, is usually written in C# and deployed via a solution package.

    The Alternatives
    Many organizations don't realize or understand the strategic implications of deciding (or deciding not) to develop custom software solutions. In my opinion, there are four basic choices:
    1. Purchase software. Don't customize.
    2. Purchase software. Customize as needed
    3. Write your own software.
    4. Any combination of two or more of the above.
    Option Number 1
    There is a clear contrast between number 1 and the rest. Specifically, if an organization makes a strategic decision to not write code, they do not need the internal infrastructure that goes with having an internal development process. However, there are a few important drawbacks worth noting. First, rarely can a software product or a set of software products meet all the needs of an organization without customization. Second, the evolution of this strategy ultimately results in a number of disparate systems that don't always play nice together. Third, software companies can be a transient bunch; when a software company goes out of business or stops supporting a product, this can put an organization at risk.

    Options 2, 3, and 4
    These options all require an internal development infrastructure. This series will go into a lot of detail about what this means for an organization and how to setup this infrastructure, but, in terms of the decision making process, it involves setting up a sometimes costly infrastructure to support the development process.

    The Grey Area
    It used to be the case that developers wrote code. You knew who the developers were and you knew what code was. This is evolving and will continue to evolve. Both the definition of developer and the definition of code are changing. Is C++ code? Probably. What about C#? jQuery? Javascript? Html? PowerShell? What about a VB.Net macro? How about using a tool like SharePoint Designer 2010 to insert a content editor web part into a page and then copying and pasting some html into the web part?

    Eventually, depending on how you define code and developer (and there are already a lot of discussions about this), either everyone will be a developer or virtually no one will.

    The Slippery Slope
    Increasingly, software is not only more easily configured, but it is also more easily customized. In addition, complex business systems increasingly require both configuration and customization to meet a particular organization's needs. For example, in order to enable a certain feature, the organization may have to write a script. In order to perfectly match business needs, the organization may have to write .Net code--even though they purchased a software product. If the organization is writing a script to enable a feature, why not write a little code to make it more closely match the organization's needs?

    SharePoint as a Development Platform
    SharePoint is the perfect example of a flexible software product that entices organizations down the path of writing custom code and (sometimes unintentionally) developing an internal software development infrastructure. There are a plethora of scenarios where this might happen. A simple scenario is when an organization needs something that SharePoint can do but requires customization. They are faced with the decision to purchase a different product and possibly pay consultants to implement it and integrate it. Or they could just write a few lines of code in SharePoint to solve the problem. But then, a little while down the road, something changes and the code has to be modified. Or new code has to be written. Or another feature is desired. Suddenly the organization has a full staff of SharePoint developers fixing bugs and writing new features.

    The Decision
    At some point, organizations need to make a conscious, strategic decision to either have a software development infrastructure that can support customizations...or not. For many organizations SharePoint does not meet all of their needs without some customization.

    This is not an IT decision. IT should certainly be consulted, but they do not make the final decision. Organizations, at the most senior levels (CIO, CEO, COO, etc...) need to take a strategic look at how applications support the primary business functions and whether the benefit of building or customizing those applications outweighs the cost and risk of purchasing the applications or doing without them. This applies to SharePoint too. No one should fire up Visual Studio and pound out some code without an organizational decision to have a software development infrastructure that supports custom SharePoint development. I can't stress this enough. Too many times, I have seen organizations trapped by difficult decisions brought about by rogue SharePoint customizations.

    Next Step
    Once an organization has made the decision to have an internal SharePoint development team, IT will build out a plan for the organizational infrastructure and negotiate resources with senior management based on expected need. This will be covered in detail in the next part of this series.