Click here to Skip to main content
15,881,801 members
Articles / Containers / Virtual Machine
Article

Connecting SharePoint to Windows Azure with Silverlight Web Parts

12 Jan 2011CPOL14 min read 20.4K   7  
How to integrate SharePoint apps with cloud-based technologies.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Microsoft SharePoint 2010 is enjoying much-deserved praise as a solid developer platform. Augmented with new services, APIs, data programmability, and UI support via the dialog framework and Silverlight, many options exist for developers to really sink their teeth into this evolved platform.

With the growing interest in cloud computing, though, I increasingly get questions about how developers can integrate their SharePoint apps with cloud-based technologies. As a platform, many of the aforementioned features can be integrated with Windows Azure in some way. Further, you can integrate SharePoint with the cloud through a host of other technologies such as OData, REST, Web 2.0 social APIs for applications like Twitter or Facebook, and, of course, through a service-oriented architecture using SOAP or Windows Communication Foundation (WCF) services.

Knowing that there’s broad integration potential between the cloud and SharePoint, in this article I’ll explore some specific integration points between SharePoint and Windows Azure. Along the way I’ll walk through the steps for creating your first integration.

Platform Basics

The Windows Azure platform is made up of three parts. First, Windows Azure itself provides data and management capabilities. Second, SQL Azure provides highly available and transactional data in the cloud. Third, Windows Azure AppFabric provides a service bus for more advanced, direct service call scenarios.

Using Windows Azure, you can support a number of different types of integration. For example, you can build and deploy a WCF service to the cloud, then integrate that service within SharePoint. Or you can consume data from Windows Azure, modeling that data within SharePoint. Further, you can use the Windows Azure AppFabric Service Bus to generate more complex service scenarios that connect SharePoint Online with SharePoint on-premises.

With any integration, you need to understand the possibilities. Figure 1 provides a starting point, listing the different ways in which you can integrate SharePoint with Windows Azure. This table is specific to SharePoint 2010, and some of these options require more coding than others.

Azure IntegrationHow
SharePoint Client Object ModelInteract with Windows Azure data in a list.
Business Connectivity Services (BCS)Model data from Windows Azure or build external list to SQL Azure.
SilverlightCreate UI against Windows Azure services or data.
Sandboxed Solutions/ SharePoint OnlineSilverlight application leveraging Windows Azure deployed to site collection.
Office Custom ClientConsume data directly from Windows Azure or BCS list exposing data.
Standard/Visual Web PartsLeverage services and data from Windows Azure.
Open XMLManage Windows Azure data in a document.
RESTUse REST to interact with Windows Azure data to integrate with SharePoint.
Office Server ServicesCombine with Open XML to auto-gen docs (such as PDFs) on a server.
Workflow/ Event ReceiversState or events that tie into Windows Azure services, workflows or data.
LINQUse for querying Windows Azure data objects.
SearchFederate search to include Windows Azure data.
Figure 1 Common Integration Points

Whatever integration you choose, it’s important to note that in this article, when integrating with Windows Azure, SharePoint is consumptive and not being hosted. In other words, SharePoint is not a service that is hosted by Windows Azure, but rather an application that consumes Windows Azure data or services. Windows Azure provides applications or resources that will be consumed by SharePoint artifacts such as a Web Part or Silverlight application. In this article, you’ll see a specific example of how you integrate a Silverlight application within SharePoint that leverages a custom WCF service deployed to Windows Azure.

If you’re starting fresh, you’ll need to make sure you have an appropriate development environment set up. Your development environment will, at the least, include the following:

  • Visual Studio 2010
  • Windows Azure SDK and tools
  • SharePoint Server 2010
  • Office 2010 Professional Plus
  • SQL Server 2008 R2
  • Silverlight runtime, SDK and tools

For Windows Azure, you’ll need to make sure you have a developer account set up so that you can create a developer portal to manage your cloud applications, data and services. You can find all of the Windows Azure tools that you’ll use to build these applications and services at microsoft.com/windowsazure/getstarted. Note that you can install the items listed earlier on your existing development machine or you can download a pre-configured virtual machine that has everything except the Windows Azure tools from tinyurl.com/33bgpy6. (Also, you can optionally install the Silverlight Web Part Visual Studio extension available at code.msdn.microsoft.com/vsixforsp.)

When you’ve got your development environment set up, you can get started developing your first integration. In this article, I’ll work through three steps:

  1. Create and deploy the custom Windows Azure WCF service.
  2. Create a Silverlight-enabled Web Part that can consume the custom Windows Azure service.
  3. Deploy and use the Silverlight-enabled Web Part in your SharePoint site.

Let’s walk through each of these steps.

Creating the WCF Service

Imagine you want to deploy a service to your entire sales organization, but you want to host that service in the cloud. The service will retrieve competitor information and will support two methods: It will enable you to get specificcompetitor information, and it will return a list of all competitor information. You’ll create both methods, but will implement only the bulk return of competitor information. You can extend the code after reading this article to leverage the request for specific competitor information.

To create the WCF service, open up Visual Studio 2010 and start a new project. In the New Project wizard, select the Cloud template. Provide a name for the project (I called mine Competitors) and click OK. Select the WCF Service Web Role project and click OK.

Visual Studio creates a new solution with a number of resources, which include Windows Azure role configuration files and your WCF service code and contract. You’ll use an in-memory object in this example, so right-click the WCF project, select Add, then select Class. Provide a name for the class (Competitor), and add the following code to the class file:

C#
namespace WCFServiceWebRole1 {
  public class Competitor {
    public string svcCompeteID { get; set; }
    public string svcCompeteName { get; set; }
    public string svcCompeteFY09 { get; set; }
    public string svcCompeteFY10 { get; set; }
  }
}

The code includes four properties (a competitor ID, name, and sales for fiscal year 2009 and fiscal year 2010).

Because you’ll also be using Silverlight as your presentation layer, you’ll need to add a client access policy file to the project to support Silverlight calling the Windows Azure service across domains. To do this, right-click the WCF project, select Add, then click New Item. In the New Item dialog, select the Data category and select XML. Name the new file clientaccesspolicy.xml and click Add. Replace the XML code in the new file with this code:

XML
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="SOAPAction">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

Next, create the service contract for your WCF service. For this example, you’ll keep things simple and just include two operational contracts. The first operation will get a single competitor (the getACompetitor method) and the second operation will get all competitors (getAllCompetitors method). Note that you’ll need to pass an ID (custID) if you want to return a specific competitor record. Figure 2 provides a summary of the contracts.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
 
namespace WCFServiceWebRole1 {
  [ServiceContract]
  public interface IService1 {
    [OperationContract]
    string[] getACompetitor(string custID);
 
    [OperationContract]
    List<Competitor> getAllCompetitors();
    }
}
Figure 2 Service Contract

With the contracts complete, you can now add some code that implements the contracts. The service code that corresponds to the service contract is shown in Figure 3. This code includes a method to get a single competitor record (getACompetitor), another to get all competitor information (getAllCompetitors) and a third to generate the competitor information (generateCompeteData). The code is straightforward, leveraging in-memory data structures such as list collections and arrays along with LINQ to create and pass data back to the calling application. In this example, the calling application is a Silverlight application that will be deployed into SharePoint.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
 
namespace WCFServiceWebRole1 {
  public class Service1 : IService1 {
    List<Competitor> myCompetitors = new List<Competitor>();
 
    public string[] getACompetitor(string custID) {
      generateCompeteData();
 
      string[] returnCompete = new string[4];
 
      var returnListOfData = (
        from compete in myCompetitors
        where  compete.svcCompeteID  == custID
        select compete).ToArray();
 
      foreach (var competeRecord in returnListOfData) {
        returnCompete[0] = competeRecord.svcCompeteID;
        returnCompete[1] = competeRecord.svcCompeteName;
        returnCompete[2] = competeRecord.svcCompeteFY09;
        returnCompete[3] = competeRecord.svcCompeteFY10; 
 
      };
 
      return returnCompete;
    }
 
    public List<Competitor> getAllCompetitors() {
      generateCompeteData();
      List<Competitor> returnlistOfCompetitors = 
        new List<Competitor>();
 
      var returnListOfData = (
        from customer in myCompetitors
        select customer).ToArray();
 
      foreach (var compete in returnListOfData) {
        Competitor tempCompeteRecord = new Competitor();
        tempCompeteRecord.svcCompeteID = compete.svcCompeteID;
        tempCompeteRecord.svcCompeteName = compete.svcCompeteName;
        tempCompeteRecord.svcCompeteFY09 = compete.svcCompeteFY09;
        tempCompeteRecord.svcCompeteFY10 = compete.svcCompeteFY10;
        returnlistOfCompetitors.Add(tempCompeteRecord);
      };
 
      return returnlistOfCompetitors;
    }
 
    private void generateCompeteData() {
      Competitor compete1 = new Competitor();
      compete1.svcCompeteID = "BR-CAN-8909";
      compete1.svcCompeteName = "Bauer - Canada";
      compete1.svcCompeteFY09 = "$45,093,028.00";
      compete1.svcCompeteFY10 = "$50,493,820.00";
      myCompetitors.Add(compete1);
 
      Competitor compete2 = new Competitor();
      compete2.svcCompeteID = "NK-USA-8665";
      compete2.svcCompeteName = "Nike - USA";
      compete2.svcCompeteFY09 = "$50,492,331.00";
      compete2.svcCompeteFY10 = "$52,019,828.00";
       myCompetitors.Add(compete2);
 
      Competitor compete3 = new Competitor();
      compete3.svcCompeteID = "GF-EU-9912";
      compete3.svcCompeteName = "Graf - Europe";
      compete3.svcCompeteFY09 = "$24,403,920.00";
      compete3.svcCompeteFY10 = "$24,001,926.00";
      myCompetitors.Add(compete3);
 
      Competitor compete4 = new Competitor();
      compete4.svcCompeteID = "CCM-USA-8843";
      compete4.svcCompeteName = "CCM Hockey";
      compete4.svcCompeteFY09 = "$12,209,105.00";
      compete4.svcCompeteFY10 = "$10,092,813.00";
      myCompetitors.Add(compete4);
 
    }
  }
}
Figure 3 Service Code

At this point, you’ve now created the WCF service and you’re almost ready to start the SharePoint part of this integration. Before you can do that, though, you need to deploy the service to Windows Azure.

To deploy the service, you must have a Windows Azure developer account set up and ready to go. Assuming you have this, you simply right-click the Windows Azure project and select Publish.

Publishing your service invokes a dialog box where you can provide your credentials. You can see in Figure 4 that you have the choice to create a service package only (Visual Studio creates the two core files that need to be added to your Windows Azure developer portal in a local folder) or to deploy your service automatically using the pre-configured information. In this example, click Create Service Package Only and click OK.

image: Service Publishing Options

Figure 4 Service Publishing Options

Two files, Competitors and ServiceConfiguration, will be created. Competitors is a service package file—essentially a resource archive—and ServiceConfiguration is an XML configuration file.

You can now navigate to your Windows Azure developer portal and add these files to your service. To do this, navigate to your service and click Deploy (or if you’ve deployed already and are upgrading the service, click Upgrade as shown in Figure 5). You can then browse to the two files and click OK. You’ll want to give your service files a few minutes to upload.

image: Manually Deploying Services to Windows Azure

Figure 5 Manually Deploying Services to Windows Azure

When you see the Ready message, you can click the link that’s displayed on the same Web page to test the service endpoint. Note that you’ll likely have to add the service name at the end of the service URL like so:

http://serviceendpoint.azure.com/Service1.svc.

At this point, you can now put Windows Azure aside and move on to SharePoint.

Creating the Silverlight-Enabled Web Part

You can create the Silverlight Web Part for SharePoint in a couple of ways. One way is to simply create a Silverlight application in Visual Studio, deploy the XAP file to SharePoint (by uploading it to a document library, for example), and using the native Silverlight Web Part in SharePoint 2010 to load your Silverlight application. This is the quickest way to deploy the Silverlight application to SharePoint, and requires less coding.

A second, slightly more interesting way is to use the Silverlight and SharePoint Web Part project template (code.msdn.microsoft.com/vsixforsp). This automatically wraps a Silverlight app with a Web Part, which means you simply create the Silverlight application and deploy it as a Web Part to SharePoint. You have a little more control over your code, plus you’re deploying a real Web Part to SharePoint.

To use the template, navigate to the Codeplex site, click the Silverlight and SharePoint VSIX link, download and unzip the files. After you unzip the files, simply install the .vsix file by double-clicking it, then restart Visual Studio 2010.

After you install the Silverlight Web Part template, return to your Visual Studio solution and click File | Add | New Project, and select Add to Solution in the Solution field. Navigate to the SharePoint 2010 folder and select the Silverlight Web Part project template. Provide a name for your Web Part (I used CompetitorSPWebPart) and click OK.

After you click OK, you’ll be prompted for a SharePoint site URL. Add your site URL here and then select Deploy as Farm Solution. You’re next prompted for a number of items, including the name for the Silverlight project, version, location to deploy the XAP file, title for your Web Part and description for your Web Part (see Figure 6). Click Finish when you’ve completed this part of the wizard. (Note that you can use Silverlight 3 or 4 with the project template, and Microsoft is currently upgrading the template for re-release on Codeplex.)

image: Configuring the Silverlight Web Part

Figure 6 Configuring the Silverlight Web Part

Now you have a SharePoint Web Part that wraps a Silverlight application, and you can use the Silverlight application to build out the UI and functionality of the Web Part.

First, in the Silverlight project, add a reference to the Windows Azure service by right-clicking References and selecting Add Service Reference. Provide a name for the namespace for your service (in my case, GetCompeteAzureService) and click OK. This is the same as consuming any other service reference in an application, except in this case the endpoint is pointing to a Windows Azure service.

At this point, you can code against the Windows Azure service. As mentioned earlier, you’ll leverage the getAllCompetitors method in the SharePoint application.

You’ll need a UI for your application. I created a simple UI that will render the data returned from the call to the Windows Azure service. The core control is a listbox control with a couple of images added for flair. See the code download for this article for details.

Next, add a custom class called Competitor to the Silverlight application. Competitor has four properties that correspond to the competitor data defined for the service code in Figure 3:

C#
namespace CompetitorDisplayApp {
  public class Competitor {
    public string competeID { get; set; }
    public string competeName { get; set; }
    public string competeFY09 { get; set; }
    public string competeFY10 { get; set; }
  }
}

In the XAML code-behind, you can now add some code that will implement the getAllCustomers method. In Figure 7, you can see that I’m using a list collection called myCompetitors to store the data being returned from the service call to Windows Azure. There isn’t a lot of heavy lifting here at all; the code is using the Competitor object to help populate the myCompetitors list collection, which is then bound to the listbox (competeList).

C#
using CompetitorDisplayApp.GetCompeteAzureService;
 
namespace CompetitorDisplayApp {
  public partial class MainPage : UserControl {
    public string SiteUrl { get; set; }
 
    List<Competitor> myCompetitors = new List<Competitor>();
 
    public MainPage() {
      InitializeComponent();
 
      this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }
 
    void MainPage_Loaded(object sender, RoutedEventArgs e) {
      LoadAzureData();
    }
 
    private void LoadAzureData() {
      GetCompeteAzureService.Service1Client azureSvcProxy = 
        new Service1Client();
      azureSvcProxy.getAllCompetitorsAsync();
      azureSvcProxy.getAllCompetitorsCompleted += 
        new EventHandler<getAllCompetitorsCompletedEventArgs>(
        azureSvcProxy_getAllCompetitorsCompleted);
    }
 
    void azureSvcProxy_getAllCompetitorsCompleted(
      object sender, getAllCompetitorsCompletedEventArgs e) {
 
      var competeData = e.Result;
      foreach (var item in competeData) {
        Competitor tempRecord = new Competitor();
        tempRecord.competeID = item.svcCompeteID;
        tempRecord.competeName = item.svcCompeteName;
        tempRecord.competeFY09 = item.svcCompeteFY09;
        tempRecord.competeFY10 = item.svcCompeteFY10;
        myCompetitors.Add(tempRecord);
      }
 
      competeList.ItemsSource = myCompetitors;
    }
  }
}
Figure 7 Custom Competitor Object

At this point, you’re finished with your coding. However, it’s worth taking a quick look at the default code that’s created by the Silverlight Web Part template to show why it can be more useful than just using the default Silverlight Web Part that ships with SharePoint.

Figure 8 shows the default Web Part code that’s created when Visual Studio creates the Silverlight Web Part project. You can see the wrapper code where a SilverlightPluginGenerator object is created and properties are set for your Web Part. These are properties that are managed at design time (as opposed to opening the Web Part, for example, and editing the height and width through the Tools pane in SharePoint). Further, you can avoid copy and paste, given this Web Part is deployed into the Web Part gallery—with the stitchwork already in place to render the Silverlight application.

C#
[ToolboxItemAttribute(false)]
public class SilverlightWebPart : WebPart {
  private SilverlightPluginGenerator _silverlightPluginGenerator = null;
 
  public SilverlightWebPart() {
    this._silverlightPluginGenerator = 
      new SilverlightPluginGenerator {
 
      Source = new Uri(
        "/XAPS/Silverlight/CompetitorDisplayApp/CompetitorDisplayApp.xap",
        UriKind.Relative),
        Width = new Unit(400, UnitType.Pixel),
        Height = new Unit(300, UnitType.Pixel),
        BackGround = Color.White,
        Version = SilverlightVersion.v3,
        AutoUpgrade = true,
        OnError = "onSilverlightError",
    };
  }
 
  protected override void CreateChildControls() {
    base.CreateChildControls();
 
    this.Controls.Add(new LiteralControl(
      @"<script type=""text/javascript"">" + 
      Resources.onSilverlightErrorHandler + 
      "</script>"));
 
    this._silverlightPluginGenerator.InitParams.Add(new InitParam(
      "SiteUrl", SPContext.Current.Site.Url));
 
    this.Controls.Add(new LiteralControl(
      this._silverlightPluginGenerator.ToString()));
  }
 
  protected override void RenderContents(HtmlTextWriter writer) {
    base.RenderContents(writer);
  }
}
Figure 8 Default Web Part Code

Finally, the properties of the Web Part were set when you walked through the initial configuration wizard. For example, if you open the .webpart file, you’ll see the name and description of the Web Part (which you can change here if you wanted):

XML
<?xml version="1.0" encoding="utf-8"?>
<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metadata>
      <type name="CompetitorSPWebPart.SilverlightWebPart.SilverlightWebPart, 
           $SharePoint.Project.AssemblyFullName$" />
      <importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>
    </metadata>
    <data>
      <properties>
        <property name="Title" type="string">Compete Information</property>
        <property name="Description" 
          type="string">This Web Part provides compete information.</property>
      </properties>
    </data>
  </webPart>
</webParts>

With the Silverlight Web Part complete, you’re now ready to deploy the Web Part to SharePoint for use.

Deploying the Web Part

To deploy, right-click the Web Part project (CompetitorSPWebPart in my example) and select Deploy. When you deploy the Web Part, the Silverlight application is deployed into the XAPS document library, and a link to that XAP file is automatically generated within the Web Part. (If you chose to use the Silverlight application instead of the Silverlight Web Part template, then you’d simply upload the XAP file into the XAPS document library and then use the native Silverlight Web Part in SharePoint.)

Now open your SharePoint site and navigate to (or create) a new Web Part page. (Note that you can create a new Web Part page by clicking Site Actions | View All Site Content | Create | Web Part Page.) Click Site Actions | Edit Page | Add a Web Part. Navigate to the Custom category, then select the Web Part (which is called Compete Information in this example), and click Add. When added, click Stop Editing. You should have something similar to what’s shown in Figure 9.

Figure 9 Final Silverlight Web Part Calling Windows Azure Service

Wrapping Up

SharePoint and Windows Azure integration is new and the opportunities are plentiful. In this example, I showed you how to create a custom Windows Azure service and then leverage that service from a custom Silverlight-based Web Part. Just in this simple example you can see the potential for much more sophisticated solutions in both Windows Azure services and the Web Parts that consume them.

For more samples and walkthroughs, you can check out my blog at blogs.msdn.com/b/steve_fox. Look out for more code and documentation on how to integrate SharePoint and Windows Azure.

Steve Fox is a senior evangelism manager at Microsoft. He’s worked in IT for 15 years, 10 of which have been spent at Microsoft across natural language, search, and SharePoint and Office development. Fox has authored many articles and books, including the recently released “Beginning SharePoint 2010 Development” (Wrox, 2010).

Thanks to the following technical expert for reviewing this article: Paul Stubbs

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --