Coding in the Cloud with Office 365

SharePoint Online expands your design horizon

The cloud environment represents an important change in the way we share information—and one that could prove to have a dramatic effect on the IT industry. When we think about SharePoint, there is a definitive shift underway to tap into the cloud to deploy, host, and manage collaborative-based solutions.

For SharePoint Server 2010 or for other on-premises versions of SharePoint, the cloud is a place of convergence and intersection. That is, cloud-based resources and applications can be integrated with SharePoint Server to offload data management, augment solution capabilities, and more generally enrich the on-premises experience by using open APIs and applications or services that are deployed to the cloud. However, the SharePoint game is both changing and expanding as Microsoft rolls out Office 365—the successor technology to the company's Business Productivity Online Suite. BPOS is a Software as a Service (SAAS) cloud offering that combines products as a package. The question is, how does this changing environment affect the SharePoint developer?

Office 365 represents a cloud-based and subscription-based productivity suite that’s managed by Microsoft (or by Microsoft partners and resellers). The suite includes four core components: Office Pro Plus, SharePoint Online, Exchange Online, and Lync Online. The broad developer story within these offerings is compelling. It not only cuts across the Office extensibility story (Ribbon, custom task panes), but also includes a significant Exchange developer story and provides a way to deploy solutions to SharePoint. Let’s look beneath the surface to better understand what building SharePoint solutions for Office 365 really means.

 

Developing for SharePoint Online

SharePoint Online offers a similar developer paradigm to SharePoint Server (the on-premises version of SharePoint) in the following ways:

•     It offers you customization/personalization opportunities through the browser by way of its out-of-the-box capabilities.

•     It supports customization through SharePoint Designer 2010.

•     It supports custom solutions that are built by using Visual Studio 2010.

 

Table 1 provides a high-level overview of the SharePoint Online developer capabilities.

With its out-of-the-box capabilities, SharePoint Online offers very much the same experience that you’d have in the on-premises version of SharePoint. One of the key differences is the administration of the Office 365 portal. Because SharePoint Online brings together multiple subscription-based services, you have a common administration portal. However, you have many of the same site settings that you would expect to find at the site collection level.

If you use SharePoint Designer, there’s quite a bit that you can do with SharePoint Online. For example, you can use native workflows or create declarative workflows in SharePoint Designer, then deploy these to SharePoint. You can also customize master pages and site pages, and more generally edit and manage the look and feel of your site by using SharePoint Designer.

To interact with SharePoint Designer, click Site Actions, then select Edit. The editing window shows many of the standard capabilities available to you. For example, Figure 1 shows how you can create a new list by using the Custom List functionality named Store Locations. After you click OK, the list becomes available through the browser or through SharePoint Designer. Let’s take a look at how you might interact with this list programmatically in SharePoint Online.

 

Client Object Model in a Sandboxed Solution

Creating artifacts in SharePoint Designer can dovetail into more code-intensive solutions, such as creating applications to populate the Store Location list. To manage list data in SharePoint Online, for example, you can use the client object model. You run the code to do this in a partial-trust code environment known as a sandboxed solution. Sandboxed solutions are applications that run in a special SharePoint worker process, SPUCWorkerProcess. This process is regulated by a set of resource measures that can automatically shut down malicious code. Notably, you can run sandboxed solutions either on-premises or in the cloud. The solutions are then deployed at the site collection level. If you’re unfamiliar with sandboxed solutions, the following article presents a good developer-centric introduction: msdn.microsoft.com/en-us/magazine/ee335711.aspx.

Sandboxed solutions that are employed in concert with the client object model can be quite powerful. For example, the code in Listing 1 illustrates how the client object model programmatically adds a record to the list that we created previously. The client object model enables you to move data into a list from outside SharePoint. It also enables you to read data from a Silverlight application, then plot that list data on a Silverlight-based Bing Map.

When you think about sandboxed solutions for the cloud, you should take note of some of the boundaries. For example, although you can leverage native SharePoint web services, you can’t make external Web service calls from the sandboxed solution out to the wider web. This also applies to SQL connection strings, REST calls, and so on. Thus, your service design in the cloud (at least in the context of the sandboxed solution) is limited to a set of native SharePoint services, such as the Lists.asmx web service. You also can’t deploy assemblies to the GAC or to access server file and folder resources because, as a multi-tenant on a SharePoint cloud instance, you don’t have access to those resources.

Yes, there are some restrictions on the sandboxed solution, but don’t fret: You can access many developer scenarios that will result in interesting SharePoint solutions. For example, the SharePoint client object model can be called from JavaScript, from Silverlight, and from the .NET Framework. Thus, by using just JavaScript and Silverlight, your custom development possibilities open up considerably to solutions that are built and deployed in the cloud. For example, you can begin to use jQuery and the SharePoint client object model to interact with lists and libraries, and you can also leverage the power of the SharePoint ECMAScript object model. Think about updating a view of a financial model by using JavaScript, jQuery, and Excel Services! The point is that you shouldn’t feel as though the cloud unnecessarily restricts the creation of rich solutions.

 

Client Object Model and Silverlight

For Silverlight, your opportunity for custom development opens up even more: Not only can you integrate Web service calls into your application (and deploy them to SharePoint Online), you can also leverage the client object model and integrate cloud-based services such as Azure or Bing Maps into your application. For example, you can use the client object model to load the list that we created earlier named Store Information. The list contains information about the store; but what is necessary for Bing Maps is the Longitude and Latitude values so that a pushpin object can be created. You can see in the GetListData method in Listing 2 that you’re retrieving the items from the list, then calling the ExecuteQueryAsync method. In the OnStoreRequestSucceeded event, on the other hand, you call the FillStorelist method. By populating a list collection with data from the SharePoint list, you can then use that list collection to create a set of pushpin objects that are specific to the Bing Maps API.

The result of the integration between Silverlight, SharePoint, and Bing maps provides a way to dynamically map objects on a map. Not only can you programmatically populate the list in SharePoint Online, but you can also retrieve the data and plot by using Bing Maps. Figure 2 shows this integration after the code has been deployed to SharePoint Online by using the built-in Silverlight Web Part. (For a more complete walkthrough of the Bing Maps sample, visit tinyurl.com/24acy8e.)

Your ability to leverage Silverlight as, in some sense, an intermediary and then use it to call services helps expand your options. Furthermore, the client object model enables you to interact, in both a read and write capacity, with your SharePoint lists. Here again, you’ll be able to create some interesting applications.

To learn more about SharePoint and about how to develop in the cloud, check out my blog, blogs.msdn.com/b/steve_fox. You can also check out these other resources for Office 365 and SharePoint development:

•     Office 365 website, http://office365.microsoft.com/en-US/online-services.aspx

•     Chris Mayo’s blog, http://blogs.msdn.com/b/cmayo

•     The SharePoint Online Developer Guide, www.microsoft.com/downloads/details.aspx?FamilyID=D007F35E-375C-4B11-BC40-BC9082BB224A&displaylang=ja&displaylang=en

 

A World of Opportunity

The paradigm for developing in the cloud is a shift from on-premises development. But developers have many opportunities in this new environment. Developing for SharePoint cuts across the out-of-the-box functionality to SharePoint Designer and, ultimately, to Visual Studio 2010. And by combining the client object model with sandboxed Web Parts or with Silverlight, you can build very interesting and compelling solutions.

It's also exciting that the subscription-based offering for Office 365 comes in multiple flavors: one for small business, one for the enterprise, and one for education. For the strategic developer, this means that you have to design applications only one time for deployment across multiple sectors.

 

 

Listing 1: Code for Adding a List Item to a List Programmatically

 

SPSite siteCollection = SPContext.Current.Site;

SPWeb mySite = SPContext.Current.Web;

SPListItemCollection listItems = mySite.Lists\\[“Store Locations”\\].Items;

SPListItem item;

item = listItems.Add();

item\\["Title"\\] = "1";

item\\["StoreName"\\] = "Contoso Seattle No.1 Store";

item\\["StoreAddress"\\] = "East Queen Anne Mall, Seattle, WA, , 97001";

item\\["StorePhone"\\] = "206-555-0195";

item\\["Latitude"\\] = "47.627499999999998";

item\\["Longitude"\\] = "-122.352";

item\\["Hours"\\] = "12";

item.Update();

 

 

 

Listing 2: Code for GetListData Method

 

        private void GetListData()
\\{

            using (ClientContext clientContext = new ClientContext("http://contoso"))

            \\{

                web = clientContext.Web;

                clientContext.Load(web);

                var bcsListFromAzure = web.Lists.GetByTitle("Store Locations");

                CamlQuery query = new CamlQuery();

                IQueryable<ListItem> bcsListItems = bcsListFromAzure.GetItems(query);

                bcsList = clientContext.LoadQuery(bcsListItems);

                clientContext.ExecuteQueryAsync(OnStoresRequestSucceeded, OnRequestFailed);

            \\}

        \\}

        private void OnStoresRequestSucceeded(object sender, ClientRequestSucceededEventArgs e)

        \\{

            Dispatcher.BeginInvoke(FillStoreList);

        \\}

        private void FillStoreList()

        \\{

            storeDetailsList.Clear();

 

            foreach (var x in bcsList)

            \\{

                StoreDetails objStoreDetails = new StoreDetails();

                objStoreDetails.StoreName = x.FieldValues.ElementAt(3).Value.ToString();

                objStoreDetails.StoreAddress = x.FieldValues.ElementAt(4).Value.ToString();

                objStoreDetails.StorePhone = x.FieldValues.ElementAt(5).Value.ToString();

                objStoreDetails.StoreHours = x.FieldValues.ElementAt(8).Value.ToString();

                objStoreDetails.StoreLocation = new Location(Convert.ToDouble(x.FieldValues.ElementAt(6).Value.ToString()), Convert.ToDouble(x.FieldValues.ElementAt(7).Value.ToString()));

                storeDetailsList.Add(objStoreDetails);

            \\}

            AddStoresToMap();

        \\}

        private void AddStoresToMap()

        \\{

            PushpinsLayer.Children.Clear();

            for (int i = 0; i < storeDetailsList.Count; i++)

            \\{

                string description = "Store: " + storeDetailsList\\[i\\].StoreName

                                 + "\nAddress: " + storeDetailsList\\[i\\].StoreAddress

                                 + "\nPhone: " + storeDetailsList\\[i\\].StorePhone

                                 + "\nHours: " + storeDetailsList\\[i\\].StoreHours;

 

                CreatePushpin(storeDetailsList\\[i\\].StoreLocation, description);

            \\}

        \\}

        private void CreatePushpin(Location location, string description)

        \\{

            Pushpin pushpin = new Pushpin();

            pushpin.Width = 22;

            pushpin.Height = 20;

            pushpin.Tag = description;

            pushpin.Location = location;

            PushpinsLayer.AddChild(pushpin, location, PositionOrigin.Center);

        \\}

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish