Category Archives: SharePoint 2013 and Office 365 Apps

Introducing Azure Functions for SharePoint

I’m excited to announce the first public release of Azure Functions for SharePoint, a powerful but inexpensive to operate open source backbone for SharePoint add-ins. We’ve been using Azure Functions in production for a while now, and I love it!

I’ll be speaking about Azure Functions next Saturday, January 21, 2017 at Cloud Saturday Atlanta. You should come!

About Azure Functions for SharePoint

AzureFunctionsForSharePoint is a multi-tenant, multi-add-in back-end for SharePoint add-ins built on Azure Functions. The goal of this project is to provide the minimal set of functions necessary to support the common scenarios shared by most SharePoint provider hosted add-ins cheaply and reliably.

Features include:

  • Centralized Identity and ACS token management
  • Installation and provisioning of add-in components to SharePoint
  • Remote event dispatching to add-in specific back-end services via message queues including
    • App installation
    • App launch
    • SharePoint Remote Events

Navigating the Documentation

These documents consist of articles that explain what the functions do, how to set up the hosting environment, and how to use the functions in your add-ins and API documentation for .NET developers linked to the source code in GitHub.

A Note on Terminology

These documents use the term client to refer to a given SharePoint add-in. A client is identified using its client ID which is the GUID that identifies the add-in’s ACS client ID in the SharePoint add-in’s AppManifest.xml.

Functions

There are three functions in this function app.

  1. AppLaunch
  2. EventDispatch
  3. GetAccessToken

Setup Guide

We’re working on full automation with an ARM template, etc. The Visual Studio Solution includes a PowerShell script you can use with Task Runner Explorer and Command Task Runner. Until then, create a function app and copy the contents of this zip file into the function app’s wwwroot folder.

Configuring the Function App

Until the automation is fully baked, you can use this video to guide you through the relatively easy setup of the function app.

Configuring SharePoint Add-ins to use the Function App

Azure Functions for SharePoint is multi-tenant in that it can service add-ins installed broadly across SharePoint Online and also because the back-end processes that respond to client specific events in SharePoint or rely on Azure Functions for SharePoint for security token management can be located anywhere with a connection to the Internet.

See the Client Configuration Guide for more information.

Using the Function App to Support Custom Back-ends

It is possible to use Azure Functions for SharePoint to deliver pure client-side solutions, i.e. HTML/JS. However, many add-ins must support scenarios that are difficult or impossible to achieve through pure JavaScript. Azure Functions for SharePoint supports custom back-ends in two ways:

  1. Notification of add-in and SharePoint events via Azure Service Bus queues via the EventDispatch Function
  2. A REST service that provides security access tokens for registered clients via the GetAccessToken Function

In both cases the client back-end receives all the information it needs to connect to SharePoint as either the user or as an app-only identity with full control. The function app does the actual authorization flow and its client configuration is the only place where the client secret is stored.

Your custom back-ends can live anywhere from the same Function App where you deployed Azure Functions for SharePoint to completely different Azure tenancies or on-premises servers. All that is required is that the back-end can read Azure Service Bus Queues and access the REST services via the Internet. Aside from these requirements, the back-end can run on any platform and be written in any language.

That said, if you are using .NET, this project included an assembly named AzureFunctionsForSharePoint.Common that you can use to make things even easier!

API Docs

Complete documentation of the Azure Functions for SharePoint API see the API Guide.

Want to Contribute to this Project?

We’re still working on that too, but please reach out to me if you want to help!

–Doug

A Tool that Answers the SharePoint Development and Provisioning Riddle

Solving the SharePoint App/Add-in Problem

Today I’m excited to be on the Office 365 Developer Podcast with Jeremy Thake to talk about the release of IQApp Central beta!

IQApp Central is the product of a multi-year effort to build a platform that makes creating, deploying, and managing SharePoint customizations easier. The goal is ambitious – to change the way people build SharePoint farm solutions, apps, and add-ins by offering better tools than they have ever along with a process that works the same on premises as it does in SharePoint Online. IQApp Central codifies everything I and others learned doing and teaching others about SharePoint for the last 8 years and what we at InstantQuick learned developing, maintaining, and operating our popular Instant Consulting Practice and Instant Legal Practice add-ins in the Office 365 Store.

Core to IQApp Central is the IQApp Editor, a set of tools that let you use SharePoint to create reusable solutions and components that are easy to deploy and track. IQApp Editor is backed up by an advanced provisioning platform that provides visibility into what packages are in use, where they are used, and how they are licensed.

Think I must be exaggerating? You can try IQApp Central for free, or watch the getting started videos. There are 6 and it takes less than 45 minutes to watch them all.

Design Tips for SharePoint 2013 Apps on Tablets and Subnotebooks

If you’ve ever thought about doing a startup you are probably familiar with the idea of the minimal viable product. For Instant Legal Practice and Instant Consulting Practice we decided that this meant focusing on a great experience within Office 365 and Microsoft Office and on some sophisticated backend designs that make it possible for us to be nimble and continuously improve the products. What we want to know is if there is a viable business in Office 365 apps and if our ability to continuously update the products will give us a strong competitive advantage.

Knowing our goals we decided early on that we were not going to invest heavily in different form factors beyond the desktop but that it would be good if we could make the products usable on tablets. Both products are tested and work on IPad 2 (and later), Nexus 7, Galaxy Tab, and Windows Surface. On the IPad they work in Safari. On the Android tablets they work in Firefox and Dolphin, but surprisingly not Chrome for Android which is a shockingly bad browser.

Tip 1: Responsive Design

If you are working on a publishing site or you intend to make big changes to the look and feel, a responsive design is your best bet. Here are a couple of links to get you started: Pro SharePoint 2013 Branding and Responsive Web Development and http://responsivesharepoint.codeplex.com/.

This was not a viable option for us because we don’t use a custom master page as a principle for compatibility with other apps and because our apps depend on list views and the ribbon for much of the user interface. It is probably something that could be made to work for us, but I think it would be a major effort and it is pretty far down the roadmap.

Tip 2: Keep required width to a minimum

This one is pretty obvious. On these devices the base resolutions vary in landscape mode, but most are 980 pixels wide. There are meta tags, CSS, and JavaScript techniques that allow some control over the viewport and zoom behaviors, but as I said we want to keep our initial investment to a minimum and so we focused on making sure the columns in our tabular layouts look good in no matter the width of the browser.

Tip 3: Use CSS effectively

The detail pages for different entities like clients and matters consist of a table at the top and often a set of tabs at the bottom that show related data.

The number of columns in the header varies by entity and also based on the data. In the case of the Clients view the Phone Numbers, Address, and Notes columns are hidden if there is no data.

The tables present challenges because the browser width varies and the width required to display specific data inside the tables also varies. However, using the base of 980 pixels wide gives us a lower bound and we set the min-width of the main content area to 900px and the width of the table to 97%. Finally, in the subordinate elements the vertical alignment is top, there is explicit padding, and the word-break is normal. All, in all, pretty basic stuff.

Tip 4: Leverage the ‘Focus on Content’ Button

The Focus on Content button is located in the upper-right hand corner of the page.

By default, when you click it, it hides all of the chrome including the menus and focuses on the content.

Not focused on content

Focused on content

This could be a great feature, but it was apparently designed by the same folks who figured app webs don’t need menus! It would be better if you didn’t have to continuously touch the button to navigate between pages.

The other day I wrote about Custom Navigation in App Webs. In that post I showed how we use JavaScript to supply menus in the apps. The same script has a monkey-patch to intercept the Focus on Content button and ensure that the primary navigation remains visible.

This is the normal view on an IPad2:

Not focused on content

It is usable if you scroll, but it works much better if you focus on content:

Focused on content

The script is fairly simple.
var oSetFullScreenMode; //Stores the original function in the SharePoint libraries

//If the function exists assign it to the variable for the original function
if (typeof (SetFullScreenMode) !== 'undefined') {
   oSetFullScreenMode = SetFullScreenMode;
}

//Replace the function with a new function
SetFullScreenMode = function (fEnableFullScreenMode) {
   //If the user is enabling full screen mode

   if (fEnableFullScreenMode) {
      //Add some margin to the top of the content area
      $('#contentBox').attr('style', 'margin-top: 20px;');

      //And put the menu into the content area as its first element
      $('#contentRow').prepend(nav);
   }
   else {
      //Otherwise remove the margin and the menu
      $('#contentBox').attr('style', 'margin-left: 220px;');
      $('#contentRow').find('#DeltaTopNavigation').remove();
   }
   //And then run the original function so SharePoint can take care of the rest
   if (oSetFullScreenMode !== undefined) {
      oSetFullScreenMode(fEnableFullScreenMode);
   }
};

//When the page loads, check to see if it is already in fullscreen mode based on the pressence of the ms-fullscreenmode
//if the page is not a dialog add the marging and insert the menu
var bodyElement = document.body;
if (bodyElement != null) {
   if ($(bodyElement).hasClass('ms-fullscreenmode') && !window.location.search.match("[?&]IsDlg=1")) {
      $('#contentBox').attr('style', 'margin-top: 20px;');
      $('#contentRow').prepend(nav);
   }
}

 

Tip 5: Don’t put options in the quick launch that aren’t available elsewhere

The presumption is that if you are using a tablet you will stay focused on content. On our billing pages, the Generate Invoices link is only on the quick launch and therefore obscured to tablet users. We will move it in an upcoming update.

Tip 6: Turn off Minimal Download Strategy

This is not a concern if you are in an app web, but in host web scenarios, this feature created the most compatibility issues in the browsers we tested. Fortunately it is easy to detect and disable minimal download strategy with CSOM.
clientContext.Load(clientContext.Web.Features);
clientContext.ExecuteQuery();
var mds = clientContext.Web.Features.GetById(new Guid("87294C72-F260-42f3-A41B-981A2FFCE37A"));
if (mds != null)
{
   clientContext.Web.Features.Remove(new Guid("87294C72-F260-42f3-A41B-981A2FFCE37A"), true);
        clientContext.ExecuteQuery();
}

Tip 7: Size dialogs dynamically on open

The above tips dealt with width, but you also need to worry about height if you are using the dialog framework. When you show the dialog set the options based on the page’s natural height.
var options = {
   url: lps.WebUrl + '/FormsAndDialogs/Matter/NewMatter.aspx',
   title: 'New Matter',
   allowMaximize: false,
   showClose: true,
   height: 576,
};
SP.UI.ModalDialog.showModalDialog(options);

Then resize it by calling the following function from the page contained in the dialog.
function resizeDialogWorkspace() {
   //If the dialog is taller than the window make it shorter than the window
   if (window.innerHeight < jQuery('#s4-workspace').height()) {
      jQuery('#s4-workspace').height(window.innerHeight - 6);
   }
}

This is what the dialog looks like on a Nexus 7.

Custom Navigation in App Webs

Of the things that I most dislike about app webs is the lack of support for navigation. There is no provision for a top link bar or quick launch and if you try to add items to the web’s Navigation collection you will get an error. Fortunately it is easy to create these menus with a little JavaScript.

Don’t Touch the Master Page

Like most folks in SharePoint land we use jQuery in Instant Legal Practice and Instant Consulting Practice whenever we need to change what SharePoint serves. We could have used a custom master page, but one of our guiding principles is to avoid such customizations of the host environment because an app that requires modification of global resources, like master pages, will not coexist well with other apps. Therefore none of our apps touch the master page and we always attack these sorts of problems in the client with script.

Know your URL

Generating a site’s navigation on the server has certain advantages. One is that SharePoint automatically produces correct links based on the web’s server relative URL. You need this information to do this work on the client, but figuring it out programmatically on every page load is inefficient. Therefore one of the things we provision when the user installs the app is a dynamically created JavaScript file that contains this sort of environmental information used throughout our scripts.

Getting the HTML and Making it Seamless

Although we go out of our way not to customize global resources we always want it to look like we did. Normal users should not be able to tell what is custom and what is not – we want everything to be seamless and feel like a natural part of the platform. Because of this, when we need HTML we almost always derive it from the original using Firefox or Chrome. Prior to IE 11, IE’s developer tools aren’t good for this task because the DOM inspector doesn’t show dynamic content and the menus are dynamic.

To get the HTML, simply select the element and copy the HTML to the clipboard.

Getting the navigation HTML with Firebug

This technique ensures that the resulting menu will look stock and will also respond to custom themes and design packages.

Putting it together

Once you have the HTML and the current web’s URL the rest is easy. Simply modify the HTML to include the desired menu items with a token for the web URL, replace the token with the actual URL, and insert the HTML into the page.

The end result looks like this:

The creation of the custom quick launch uses the same basic techniques.

Author: Doug Ware

How to Install and Uninstall Apps from the SharePoint Store on Office 365

The other day I was giving a friend of mine who has an existing Office 365 subscription a tour of Instant Consulting Practice. I was a bit surprised that he had never installed an app nor did he know how or what it would do to his site.

Adding an App

There are two ways to add an app. Select Add an app from the gear dropdown or navigate to the Site Contents page and click the add an app icon.

Method 1 – from the gear dropdown

Method 2 – from the Site Contents page

In either case you will see a list of all the various built-in apps available on your SharePoint site. To see the apps available on the marketplace click the SharePoint Store link located on the left side of your screen.

There are many apps in the store organized by category. Select the category from the list on the left and then select the app – in this case Instant Consulting Practice.

Don’t be scared!

Clicking an app doesn’t add it to your site; it takes you to a page where you can learn more about the app before you commit to the installation. Once you feel comfortable, and you are ready, click ADD IT.

 

You still have a chance to change your mind. Every app contains a policy that tells you what permissions you are giving the app in your site. Instant Consulting Practice and Instant Legal Practice both use the minimum available permissions. To begin the actual installation of the app click Trust It.

The Site Contents page loads and shows that your app is installing. You can still cancel the install if you change your mind!

Once the app package is installed on your site the icon will become solid and you can click it to launch the app.

Some apps need to do additional setup before you can use the app. The Instant Practice Manager products do additional work when the app is launched for the first time and occasionally to deploy updates and fixes.

Once the app is ready the home page displays and you can use the app.

What if I don’t like the app I just installed?

Installing an app from the store is safe because it doesn’t change the site where you install it. Instead, it gets its own site. To get rid of the app, click the link in the upper-left corner of the page to return to your site and then navigate to the Site Contents page.

Next, hover over the app icon, and click the ellipses to display the hover card, click its ellipses, and click Remove.

Warning!

Removing the app will remove everything you put in the app including any documents you uploaded! You will receive a warning and there is no going back.

Conclusion

If you are into SharePoint you may have read articles or blog posts about the app model. For better or worse most of the restrictions Microsoft has in place in the store are there so that you can feel comfortable installing an app and know that it won’t mess up your site. If you’d like to give it a try, why not go install Instant Consulting Practice or Instant Legal Practice for free?

Sandbox Solutions – Not Completely Dead

Recently Richard diZerega (whose blog you should be reading) wrote a post called SharePoint Sandbox isn’t Dead…UserCode is wherein he explained that the use of sandbox solutions for declarative provisioning via CAML with features is not deprecated but that the use of procedural code within the sandbox user code host is deprecated. This got some folks talking because none of the official Microsoft docs make this clear.

Today I was part of a large email thread where Iouri Simernitski from the Visual Studio Tools for Office team said the same thing. When asked if that was the official word he said that it was and that this fact was not secret or subject to any NDA’s – we should feel free to share this information publicly.

So, if you have a sandbox solution and you want to maintain it going forward in a supported way, keeping your modules, fields, content types, list instances, etc. in CAML is an option. You can migrate the procedural code to CSOM, JSOM, or REST as needed. It won’t be compatible with the Office 365 marketplace but it will be supported.

Author: Doug Ware

Host Web versus App Web Case Study – Clients

App Web versus Host Web in Office 365 Apps

Chris O’Brien and I have had a running conversation about the merits of using the host web versus the app web as the container for app functionality. If you’d like to catch up on the conversation, it has gone thusly so far:

In Chris’s last post he softened his position a bit. This post is an actual example that compares the client management features in the free trial versions of Instant Practice Manager (the ones in the marketplace) which use app webs to the standard versions which use host webs (which we sell directly because they use a higher level of permissions than the marketplace allows).

Office Integration

On the surface the two versions are hard to tell apart, but in a ghetto web app web there are no rich client integration features like Outlook and document library synchronization and this difference has a profound effect on the user experience.

Clients view in app web

 

Clients view in host web

When Outlook is available you can connect the list to Outlook and create or edit clients in Outlook as well as perform mail merges.

Not to mention features for individual contacts.

You get similar benefits with the calendar and task features.

Document Synchronization

Document synchronization is another major advantage of a host web compared to an app web. The screen shots below show the Documents tab in the app web version and in the host web version.

App Web

Host Web

 

A synchronized document library is a huge time saver, especially if you have folder structures you always want to copy or many documents that you need to file.

Working with the client’s documents in Windows Explorer

Synchronized with the client in SharePoint

This synchronization capability is something that can be leveraged in so many cases. It works particularly well when combined with a document scanner like the Fujitsu ScanSnap.

There are many more advantages to using a host web (and upgrading to the standard edition of Instant Practice Manager) that I won’t go into here, but hopefully this will convince Chris that choosing an app web over a host web is not something you should do automatically. The choice will make a big difference to your users!

Technical Notes

There is only one code base. All provisioning is done via CSOM in processes hosted in a Windows Azure worker role. The architecture is fairly complex, but the code itself is relatively simple. The key is that using features in an app package is to be avoided because they only support app web deployments.

I will be announcing public training classes soon and as always, we’d love to hear from you if you need consulting help or would like to license the framework. If you are interested in either please send us an email at info@instantquick.com.

Author: Doug Ware

Screen Scraping – the Last Best Option

I have a confession to make. I am a people pleaser. I really want people to like the software I write and I agonize over the possibility that someone somewhere is muttering obscenities as they use something I wrote. When I write a blog post I compulsively look at analytics stats for the next couple of days wondering ‘did they like it?’ ‘how long did people spend reading it?’ ‘how many people read it?’ ‘where did they come for?’ ‘what about now?’ ‘how many people are reading it right now?’ ‘what about now?’
‘what about now?
‘what about now?’

It’s truly pathetic.

This need to please translates to a need to write software that works just right and doesn’t needlessly suck or waste your time. I want you to smile, or at least not scowl, when you use it and be glad that I wrote it.

It means that once I’ve set my mind on having functionality that works a certain way I’ll hack away until I am satisfied with no regard to the opinions of the product’s vendor whatsoever.

The platform will obey me.

…If I recall correctly, at some point I mentioned that I’ve been building some Office 365 apps.

Overall I find the experience to be most pleasing and that the API’s Microsoft has given us are adequate to build anything you might desire, almost. However, every once in a while you’ll come across a need that isn’t directly supported by these API’s, or maybe it is supported but you don’t know it or can’t figure out how to do it even after thorough researching and tinkering. When this happens you have a choice: you can give up and make your audience sad, or you can get out your hacksaw, blowtorch, and duct tape and make them clap.

Screen scraping using JavaScript is a great example of duct tape. With it, you can make your code do for the user anything she can do manually through the browser subject to her permissions within your site’s domain. It is why cross site scripting attacks are so dangerous – if you can get JavaScript into a user’s page, you can do anything the user can do and because of the way the web works there is very little the vendor can do to stop it. It is the reason we have app webs and app parts – to keep your JavaScript out of the SharePoint page and the SharePoint site’s home domain by isolating your app in its own domain.

The jQuery library makes screen scraping really easy, but it should always be a last resort because the vendor will not support you nor can you expect it to work in the next version (although most of the pages you’d want to scrape in SharePoint haven’t changed for several versions).

The Scenario – Creating a OneNote 2013 Notebook in Office 365

I was surprised to discover recently that a OneNote notebook is a special type of folder in SharePoint 2013 that contains documents that comprise the notebook’s individual sections. The SharePoint folder is associated with OneNote via its ProgId property. Unfortunately I couldn’t find a way create a OneNote notebook directly or a way to set this property to turn a folder into a notebook via the client object model, but it can be done with very little screen scraping code.

Some pseudo code for this JavaScript is…

  1. Try to get the notebook folder
  2. If there is an error, the folder wasn’t found. Call the function to create it, otherwise there is nothing to do
  3. Issue an HTTP GET request to the CreateNewDocument page specifying at a location and document type 4 (OneNote notebook)
  4. Parse the content of the GET response to create a new HTML document
  5. Find the input element for the file name and set it to the name of the new notebook
  6. Find the input element that specifies the name of the control that caused the ASP.NET post back event and set it to the name of the OK button
  7. Serialize the HTML document’s form to get the post data
  8. Post the form to create the notebook

Figuring this out

This example solution relies on JQuery to talk to SharePoint and illustrates the use of the ajax(), get(), and post() methods to communicate with a web server of any type. Understanding these is to almost all web communication scenarios. It also relies on jQuery for parsing and document manipulation. The robustness of jQuery makes screen scraping a web site palatable because it doesn’t rely on complex and fragile parsing of the document as raw text. It’s also easy to read.

The other tool I used is one I consider essential to modern development, Fiddler Web Debugging Proxy from Telerik. All I have to do is turn it on, do the operation I am interested in, and record the results. Once I have the results I can use Fiddler’s inspectors to see what I need to put in my script.

The pictures below show these steps in action.

Remember that this is a last resort technique! Don’t overuse it! Be prepared to fix it as the target platform evolves!

Happy coding and don’t hurt yourself!

–Doug

Writing screen scraping code step by step.

Step 1. Start Fiddler (if the site is https you’ll need to do a little configuration to decode the traffic)

 

Step 2. Do the work manually and trace the traffic

 

Step 3. Inspect the trace information to get the required query string parameters and form fields

Step 4. Create the script

Author: Doug Ware

Cross Domain Communication in SharePoint 2013 Apps

I believe that the most common types of apps people will build will be either provider-hosted or hybrid apps that include important server-side components. These server side components will manipulate content inside of SharePoint based on actions performed in the browser and on-demand based on scheduled jobs or in response to input from other parts of the overall system.

How this communication takes place and the overall architecture is of primary importance in any distributed app architecture and it is something on which I spent the most time figuring out as I built out my current reference architecture. I tried many options before settling on a final strategy. This post is about the various options, strengths, weaknesses, and my current implementation.

Goals

I’ve built many distributed systems over the years using a variety of technologies. If the experience has taught me anything it’s that it is critical to minimize dependencies between subsystems – this includes dependencies between user interfaces and application services.

In past projects it has often been the case that the purpose of the distributed architecture is to provide services to multiple UIs built on heterogeneous technologies. This is increasingly the case as we deal with phones, tablets, and other form factors. So, the second goal of this architecture is to support multiple user interfaces. This means that the data services and business logic belong in one or more app servers and not in JavaScript in the client.

In any distributed system there may be operations that take more time than a typical page load. This is especially common in SharePoint solutions because provisioning is comparatively slow. The third goal is that the architecture must support long running transactions.

Sometimes an operation will face problems. When this happens the system must be robust enough to identify the issue and compensate to recover. The fourth goal is that the architecture allows complete control over the manipulation of data and other artifacts.

To sum up the goals, the application services need to support an arbitrary set of UI technologies and ensure data integrity for short running and long running transactions.

Options

Remote Event Receivers

I was very excited by the concept of remote event receivers when I first learned about apps, but I had a very hard time getting them to work because of bugs in the beta and quirks in the early Visual Studio tools. I am happy to report that both problems were addressed and now it is pretty easy to create and handle remote events.

The data flow for a remote event receiver looks like this:

Note the question marks: remote event receivers are not reliable. If your listener is not available to handle the event or the call is not successful, your app won’t handle the event and SharePoint won’t retry the notification. Worse yet, there is no direct mechanism available to the client to determine the ultimate success or failure of the event.

Finally, the use of remote event receivers makes the application server reliant on SharePoint for part of what should be atomic operations and creates a dependency between the app services and SharePoint. I still envision scenarios where remote events are helpful, but they will need to be augmented by background jobs that sweep up any missed events.

Verdict: Remote event receivers do not meet the goals.

Others have suggested that workflows are good alternative because the workflow engine can deal with transient errors in service calls, but that approach fails to minimize dependencies between my tiers and cedes the critical functionality of one subsystem to another… not good. But I freely admit that I don’t know enough about this approach to dismiss it generally. In my case, lack of time to investigate the possibility was the biggest reason I didn’t investigate this option.

At this point I realized that I needed to put all of my data processing into my application server and orchestrate my transactions from there.

Web Proxy / Remote Endpoints

Clearly what I needed to do was call services on my app server from the browser that could take charge of a complete transaction. The challenge here is that the app server is always on a different domain and that cross-site scripting restrictions exist. Fortunately SharePoint includes a couple facilities to enable this sort of interaction. One facility, the SharePoint Web Proxy, is for scenarios where the page is in SharePoint and the service is in another domain, the second, the cross domain library, is for the inverse and is primarily for communicating with SharePoint from pages contained in App Parts.

In my architecture the pages are stored in SharePoint and so I began working with the web proxy. The web proxy requires RemoteEndpoint elements in your app manifest that identify domains you are allowed to call. Calls are sent using the SP.WebRequestInfo object to SharePoint which forwards the request to the actual service.

I had a few problems with this approach. The first is that it is inflexible and creates a dependency between my app manifest and my services. What if I want to move the services around? The location is baked into the manifest. However, the deal-breaker was that the Web Proxy enforces certain timeouts and other settings that you can neither view nor change. It is possible for the Web Proxy to report an error to the client in cases where the application server received and processed the message.

I first encountered this problem with a long transaction before the worker role was in place – the timeout appears to be 30 seconds, but I also had transient issues that I can’t explain. Sometimes it just reported a failure even though the request made it to my server and was processed successfully. The web proxy is a black box and there appears to be no facility for troubleshooting.

Verdict: The Web Proxy does not meet my goals.

Cross Domain Library

The cross domain library uses an HTML 5.0 feature called postMessage via SP.RequestExecutor.js. I quickly realized that this was the mechanism I needed to use, but that I couldn’t use the cross domain library itself because it goes from a remote page to a SharePoint service and I needed to go from a SharePoint page to a remote service.

Verdict: Not applicable

Custom postMessage Implementation and JSONP

In the end I wound up building a custom postMessage implementation for my complex flows. My services are implemented as generic ASP.NET handlers. My pages in SharePoint use a custom function that adds an iframe to the page which receives the script that ultimately calls the custom service and proxies the reply back to the SharePoint page.

This mechanism meets all of my goals and it has an added advantage in that it allows me to implement additional security. Complete control over the communication lets me to easily share my context token cookie, support deep links, and implement a digest to prevent man in the middle attacks.

For simpler interactions, like the service that supports my autocomplete fields I am simply using jQuery with JSONP.

Verdict: Winner!

Happy architecting!
–Doug

Author: Doug Ware

Using the Web and Folder Properties Collections with CSOM (2013)

One annoying thing about CSOM in SharePoint 2010 is that there is no way to add persisted items to Web.AllProperties or Folder.Properties. This deficiency is fixed in 2013 but the way it works is not obvious because if you look at the objects (and you are me) you’d guess that the way to set a property is to manipulate the PropertyValues.FieldValues collection and you’d be wrong!

Here is a working example in C#.

var props = clientContext.Web.AllProperties;

 

props["propertyName"] = "Value";

 

clientContext.Web.Update();

 

In JavaScript use props.setItem("propertyName", "Value");

Happy coding!
–Doug

Author: Doug Ware