Free Web Part – Security Aware Silverlight SharePoint Web Part With Auditing

Just want the code? :

**Tested In SharePoint 2007 & SharePoint 2010**

While working at a new SharePoint client, one of the issues I was made aware of was that for new development Silverlight was being leveraged across both the legacy SharePoint 2007 and newly staged SharePoint 2010 instance for custom applications. While this wasn’t a strict standard to maintain the application in accordance with potential ongoing maintenance making use of Silverlight was the best approach.

The being said, I went off and delivered a series of applications that were built on Silverlight, hosting them in the pretty much default manner using the built-in SharePoint 2010 facilities. However, there are two huge, noticeable gaps with this:

1) There is no way to audit application invocation / what .XAP files were being used I think this is kind of a drag. It makes more sense to maintain a collated list of all the Silverlight files being invoked in a SharePoint environment, which would immediately require a new type of host that would provide such a holistic view into the Silverlight / SharePoint environment.

2) Security Configuration Being Internally Managed It seemed that while there were ways to tap directly into the SharePoint OM and inject resultant queries into Silverlight code, such a generic application didn’t lend itself well to an ad-hoc configuration basis. That sounds terrible. Since the container for users in the environment is well defined (i.e. relying on SharePoint to provide that through user profiles, user information list, etc.) this code can be super generic.

Expanding on the aforementioned concepts, it is easy to grasp some baseline requirements that must be present for the new Silverlight application host to be successful.

For Auditing –

1) When a new .XAP file is invoked through the host, this information must be sent to a retrievable medium that is easy to view and access. So a SPList object should be leveraged.

2) For matrix-based SharePoint taxonomies, the host must be a site collection-by-site collection basis since divisions while have different site collection administrators that are responsible for collating and analyzing the information. Rolling this information up can simply lean on baked-in CQWP features or a custom rollup.

3) The information collected should be:

a. .XAP invoked
b. SPWeb Title
c. Page (SPItem) Title
d. Full (Absolute) URL to the hosting page
e. Last Modified Date (if the WebPart is ever placed in edit more).

4) Auditing has to be dynamic in the sense that if the WebPart is modified, this event is recorded so that the information does not grow stale and unusable.

5) An email should be sent to a user specified in the host when a new file is invoked.

6) All required content placeholders should be generated automatically.

For Security –

1) Simply put, security settings on the corresponding audit entries should naturally flow to the Silverlight application so that a developer can easily read the past in roles. Since an SPListItem is a SecurableObject, it makes sense to just compartmentalize the permissions corresponding between Silverlight and the SPListItem.

2) Since permissions set on the SPListItem will translate to those read from the Siverlight application, an event receiver to do group membership checks for configured administrators should be implemented.

3) The roles and current user should be available as parameters to the Silverlight application.

The code is deployed as a regular good ol SharePoint Feature:

At first the site collection will have no lists:

Activate The Feature:

A WebPart Instances List Will Be Generated At The Root Of The Site Collection:

These columns will be provided by a specialized content type, while the default item content types is removed:

The Instance Content Type is programatically created by the feature (select for a larger image):

The event receiver to protect unauthorized changes is wired in the same method:

Each Of The Items Is Represented As A WebPartIntance Type:

Each Of these values is hydrated using save methods of SPListItem objects:

And at the end of the day, the parameters are sent to the developer to consume (select for a larger image):

That’s a pretty good overview of the holistic application architecture. From an interface perspective, the first thing the WebPart is going to execute before performing any auditing events is check whether proper properties have been set (select for a larger image):

This is simply indicating that a Silverlight container and corresponding have not yet been selected:

The files themselves are trimmed according to silverlight extensions (select for a larger image):

Once all the requisite properties are set, you will see your Silverlight files running:


Quick Tip: Cross Domain Policy Problems With Web Services / Silverlight

More a note to myself more than anything. If you have a Silverlight application that is invoked from a domain and then making calls to a SharePoint web service in a different domain, you may encounter the following error:

An error occurred while trying to make a request to URI ‘http://sharepoint/stuff/morestuff/superservice.svc’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

The fix is to place copies of the crossdomain.xml and clientaccesspolicy.xml files in the root application folder. Works fine afterwards.


Fix Unhandled Error in Silverlight 2 Application Invalid cross-thread access error

Had a support call from a client today regarding a problem them were running into with Client OM access from a Silverlight application. The exact error was “Invalid cross-thread access”. Sitting down with the developer at the site I determined that this problem can be caused by two issues:

1) Your XAP is not copied into the right location. It is supposed to go into the 14 hive ClientBin directory under LAYOUTS. If the XAP is not present, this error can occur.

2) Objects in code and not being loaded correctly (this turned out to be the primary issue for my particular problem). Consider the following simply ListItem update code:

private void UpdateData()
ClientContext clientContext = new ClientContext(“url”);
Web web = clientContext.Web;
ListCollection listCollection = web.Lists;
list = listCollection.GetByTitle(“TestList”);
ListItem li = list.GetItemById(1);
li[“Title”] = “My new item”;
clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);

private void onQuerySucceeded (object sender, ClientRequestSucceededEventArgs args)
// I am not displaying show ShowMessage, but assume that it writes the list title to standard output
UpdateUIMethod updateUI = ShowMessage;

private void onQueryFailed (object sender, ClientRequestFailedEventArgs args)

Now, looking back at the error, what’s missing in the above code is the load! The objects will not be initialized with this code, which can cause that particular error.
To fix it, include the load, such as (fully qualified instantiation demoed, you would obviously use your own object conventions):
list => list.Title);
before executing the query, and the error should go away!