One of the nicer features that SharePoint 2010 brought with it was the Client Object Model. Previously, all custom code had to either run on the server, using the SharePoint API. As an alternative, you could call the SharePoint SOAP web services from a client application, but in many cases, they left a little to be desired. The client object model brings the richness of the SharePoint API to client side development using either the full .NET framework, Silverlight, or jQuery.
Why is client side development important? Well, simply put, if you want to write an application or an add on for SharePoint, and you want it to run in both on-premise installations and in Office 365, it’s pretty much your only option, because you can’t deploy custom code to SharePoint Online. (OK, you can run sandboxed code in the cloud, but that brings its own set of severe limitations).
There are some great tutorials out there about working with the SharePoint Client Side Object Model (CSOM), so I’m not going to go into that here, but Tobias Zimmergren has an excellent getting started post – Getting Started With The Client Object Model. His example outlines using it with with the .NET CLR version, which is almost identical to Silverlight. As always, it’s the almost part that gets you. But more about that later.
There are a number of extra considerations when using the CSOM with an anonymous site. Since the code is executing on the client side, obviously the data needs to be accessible anonymously. Before we even touch the code, there are a number of things to check on the site itself.
1. Ensure that anonymous access is enabled
This may seem obvious, but it’s worth stating. Anonymous access needs to be enabled at both the web application level, and at the site collection level. One less that clear thing is that the option for enabling it at the site collection level does not even appear until it has been enabled at the application level. Randy Drisgill has an excellent post on how to do this here. As a best practice, I maintain one zone (usually the default) that uses Windows authentication, and my external zone, which allows ONLY anonymous access.
2. Turn off the ViewFormPagesLockDown feature
SharePoint publishing sites are designed to serve up pages, and to ONLY serve up pages to anonymous users. Standard SharePoint list items and forms cannot by default be accessed by anonymous users. This behaviour is controlled by the ViewFormPagesLockdown feature. This feature is enabled by default for publishing sites.
If the Silverlight application will be accessing any SharePoint list data, we will need to turn this feature off. Keep in mind that anonymous users will then have access to content stored in the site if they know how to access them, so you may want to use distinct anonymous access levels on some of your lists/libraries.
To turn off this feature, open a command prompt on your SharePoint server, and enter the following (replacing urlofsite with your url):
stsadm -o deactivatefeature -url http://urlofsite -name ViewFormPagesLockDown
Once you perform this step, you may need to re-set the anonymous access level for the site collection, as it doesn’t always pick up right away.
3. Allow GetItems() calls
For some bizarre (in my opinion…) reason, calls to the GetItems function is disabled by default for anonymous users. Waldek Mastykarz has a post about this issue, and what to do about it, which boils down to the following 3 lines of Powershell.
1: $wa = Get-SPWebApplication -Identity "http://sharepoint"
2: $wa.ClientCallableSettings.AnonymousRestrictedTypes.Remove([Microsoft.SharePoint.SPList], "GetItems")
This will remove this restriction. Replacing “Remove” with “Add” will add it back.
4. Run the Application in Context
In order to work with the CSOM you will need to instantiate an SPContext object. This is the starting object for working with SharePoint objects. You can do this one of two ways. If you’re running the Silverlight application directly from a client (likely in development mode) or out of browser, you use its New constructor with the URL of the site as an argument.
_Context = New ClientContext(_URL)
If, However, you’re running from a SharePoint page, or a web part, you can use the current context.
_Context = ClientContext.Current
In Tobias’s tutorial mentioned above, he indicates that you can control the authentication mode through the AuthenticationMode property of the SPContext object. Possible values are Anonymous, Default, and Forms. As luck would have it, this property is not available to the Silverlight implementation of the SPContext object.
When working as an authenticated user, both options are available to you, but anonymous access only works with the second option. This makes debugging with anonymous sites difficult, as you need to either use a web part project, or copy your compile XAP file to the server manually. However, it’s only one line of code to change, so its entirely feasible to almost all of the development on the internal zone, and remember top change the mechanism before deploying to the anonymous zone.
5. Ensure That All of Your Resources Are Available.
If you’ve ever worked with an external site you’re familiar with the need to check in and approve all public facing content. It’s no different here. You need to ensure that all of the resources used by your application are available to anonymous users. I normally just try to load them all manually in a browser.
Once all of these steps are completed, you should be good to go with your anonymous site.
I wanted to add one other pointer here, although it has nothing to do with anonymous access. When you’re working with the CSOM, all of your calls are made asynchronously. This means that you make a request, and the result calls back into another method of your code. If you’re data binding, and showing results on screen, you will want to show the result as soon as it comes back. The problem is that many calls happen on a background thread, and when the try to access a data bound object, you’ll get the following error:
UnauthorizedAccessException: Invalid cross-thread access in Silverlight application
The trick is to force the update to happen on the UI thread. Steve Willcock at StackOverflow answered a similar question that includes a handy little helper object for forcing execution on the UI thread.
You don’t have to do client side development with SharePoint, but there are many advantages to doing so. The coming release of Office 365 makes it that much more compelling.