Tuesday, April 27, 2010

Building a WCF REST + jQuery webpart based realtime request graph for SP2010, in less than 5 minutes

In the following screencast I demonstrate how quickly one can write, build and deploy a WCF REST web service, visual webpart and jQuery code to an all clean SharePoint 2010 portal. The solution I'm building (which could obviously be made cooler, if you had - say - 10 minutes) is a realtime incoming request monitor. It will render bars based on how many incoming requests the SharePoint portal has at a given moment.

Watch the (somewhat stressed) screencast:



And here's the source code, with quite a few visualization improvements I didn't think of in the build demo above.

Building and deploying a WCF service to SharePoint 2010, and writing a console client, all in 3min 28sec

Here's a 3m 28s screencast (which could have been a lot quicker, if I didn't fumble about so much), where I build and deploy a WCF service to a blank SharePoint 2010 site, and then create a console client to make a request from the service.


A couple of quick tricks make it swifter than a blink of an eye - seriously.

1: Avoid manually typing the full assembly (and PublicKeyToken) reference in your .svc files

To do this, make a one-time update to your build box' SharePoint MSBuild targets. Go to your "Program files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\SharePointTools" folder, and open the .targets-file found there. Locate the "TokenReplacementFileExtensions" node, and add "svc" to the processed extensions.

This will essentially make .svc files eligible for replacements such as described in http://msdn.microsoft.com/en-us/library/ee231545.aspx. Which means that your .svc files can now include:

<%@ ServiceHost
Factory="..."
Language="C#"
Service="Namespace.ServiceClass, $SharePoint.Project.AssemblyFullName$"
%>

The full assembly reference will then be filled in upon build.

2: Use a Factory, rather than an explicit web.config file alongside your .svc

This is an excerpt from a ReSharper live template I setup in my own dev environment, which is merged with the ServiceHost block above:

Factory="Microsoft.SharePoint.Client.Services.$FACTORY$,
Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c"

Where $FACTORY$ is either:
  • MultipleBaseAddressBasicHttpBindingServiceHostFactory for a SOAP service.
  • MultipleBaseAddressWebServiceHostFactory for a REST service.
  • MultipleBaseAddressDataServiceHostFactory for an ADO.NET Data Service.

To provide a MEX endpoint for your service, add an "[BasicHttpBindingServiceMetadataExchangeEndpoint]" attribute to your service implementation. This is defined in the assembly Microsoft.SharePoint.Client.ServerRuntime. The namespace is Microsoft.SharePoint.Client.Services.

Also make sure it has "[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]", otherwise it won't run at all. This is found in the System.ServiceModel assembly, which is required for WCF in general.

3: Deploy using Visual Studio 2010

Using one of the new Visual Studio 2010 project templates:
  1. Add your service code
  2. Right-click the project node and add a mapped SharePoint folder, such as LAYOUTS or ISAPI
  3. Deploy your .svc file(s) to a project folder within the mapped folder
  4. Hit build, deploy and take it for a spin.

Monday, April 26, 2010

My Visual Studio 2010 Theme: Son of Obsidian

Inspired by the good old Obsidian theme, it's meant to be easy on the eyes.


Download available at studiostyles.info.

SP2010 Deployment: Beware of "Deployment Conflict Resolution Behavior"

Having finally gotten around to test drive SharePoint 2010 properly, I set out to create a quick site definition. To lay the basis for structure to come, as well as upgradability, I wanted to do as I've usually done with SP2007: leave the site definition next to empty, and attach features to it to do the dirty work. This means that I'd have separate features to deploy files such as a custom master page, default.aspx and stylesheets.

The most interesting part here is the default.aspx file. After whipping up the Site Definition project in Visual Studio 2010, I added a feature and a Module project item. I then moved the default.aspx file from the site definition item to the new module.


This left me with a project structure as shown above. Clean and simple, with the site definition activating the layout feature, which would go on to provision the default.aspx file. Nothing fancy; easy to grasp. Or so you'd think.

Next I went on to compile and deploy the package to my local test site. Visual Studio is nice enough to open the "New Site" page when you debug site def projects, so that was truly painless. I then verified that my new sub web worked, and tried returning to the root site.

Bam. 404 - Not Found. Huh?

I opened SP Designer and checked the root site. Indeed, there was no default.aspx there. I even checked to see that my layout feature hadn't been enabled for the root site - it hadn't. Having redeployed a few times, it dawned on me that the retraction or deployment process was to blame, not SharePoint itself.

This took me a whole lot of digging through the Visual Studio 2010 + SharePoint 2010 integration model to figure out - Reflector be praised - but in the end the answer turned out to be pretty simple: Deployment Conflict Resolution. Having first found a reference to this concept in one of the VS.SharePoint deployment command dlls, I did a Google search and found it mentioned in brief in this article.

Sure enough, flipping the switch for my module item worked. VS2010 will now deploy the solution, without deleting my root default.aspx file - a conflict it had no business solving in the first place. Even though I happen to be deploying a default.aspx file; I'm not necessarily in the mood to delete all other default.aspx files in the site collection.