RIA Technologies: Benefits, Tradeoffs, and Considerations
For the most part, developing Ajax or Silverlight components for the SharePoint platform is no different from developing Ajax or Silverlight components for any other platform. In this topic we look at some of the criteria that will help you decide whether Ajax, Silverlight, or traditional server-side controls best meet your requirements in a variety of scenarios. We also examine specific aspects of the SharePoint platform that can have a bearing on the suitability of each approach.
When you design and build a user experience, you need to think about whether all your end users have an environment that supports your chosen approach. Users in a tightly controlled environment may not be able to download or use the plug-ins required to support technologies such as Silverlight or Flash. Older web browsers, or browsers with high security settings, may prevent web pages from executing script. Older web browsers, in particular, may provide a more idiosyncratic interpretation of cascading style sheet (CSS) files and non-standardized HTML constructs. Essentially, web UI technologies present a tradeoff between reach and capability, as illustrated by the following diagram.
Web UI technologies—reach versus capability
Like other similar multimedia technologies, users must install a plug-in—the Silverlight runtime—in order to view Silverlight content. The installed base of Silverlight has grown quickly, so you can increasingly depend on it already being installed on client machines. However, as described previously, users in some environments may be unable or unwilling to download and install a plug-in in order to view your content. A common solution is to provide alternative HTML content, within the object tag that hosts the Silverlight control, for users who have not installed the Silverlight runtime. This content can either point users to the download location for the Silverlight plug-in, or provide a plain HTML alternative rendering of the Silverlight content. If your applications increasingly rely on multimedia content, or you need to perform increasingly complex logic with large datasets, you may find that Silverlight is the right solution.
Performance is an important consideration when you design a web-based UI, as users quickly lose patience with web pages that are slow to load or slow to update. Each approach to user experience has benefits and drawbacks for particular aspects of performance. However, there are also various strategies—such as caching, delayed loading, predictive loading, and minifying—that you can use to mitigate some of the potential performance issues associated with each technology. The sections that follow examine these aspects of UI design in more detail.
Initial Load Time
You can also minify CSS files.
If you are creating a sandboxed solution, you must deploy your resources to a SharePoint library as you do not have access to the file system on the server. You may also have to manage without BLOB caching, depending on administrative policy and whether you are able to request changes.
When you work with Silverlight, you can use application library caching to improve load times on pages hosting multiple Silverlight applications and for subsequent visits to your web page. When you enable application library caching for a Silverlight project in Visual Studio, library assemblies (such as System.Xml.Linq.dll) are packaged separately from your application assemblies, which are included in the XAP file. Each library is packaged as a zip file—for example System.Xml.Linq.zip—in the output directory of your project. This approach allows client browsers to cache system libraries separately from your XAP files. As library assemblies such as these are often used by multiple Silverlight controls, application library caching can substantially reduce total download sizes. For example, in the Client reference implementation, removing the shared resources reduced the size of the XAP file by over 97 percent, from 500KB to 11KB once SharePoint libraries were included. Visual Studio determines whether or not to separate out an individual assembly based on an external mapping file, which is unique to a particular assembly. The SharePoint client assemblies—Microsoft.SharePoint.Client.Silverlight.dll and Microsoft.SharePoint.Client.Silverlight.Runtime.dll—do not have an external mapping file. In order to separate these assemblies from your XAP file, you need to add an external mapping file for each assembly to the ClientBin folder within the SharePoint root folder on your server file system. The naming convention for the external mapping file is the assembly name with an .extmap.xml extension, such as Microsoft.SharePoint.Client.Silverlight.extmap.xml. The following example shows the external mapping file that instructs the compiler to separate out Microsoft.SharePoint.Client.Silverlight.dll into a zip file if application library caching is configured for a project that uses the assembly.
<?xml version="1.0"?> <manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <assembly> <name>Microsoft.SharePoint.Client.Silverlight</name> <version>14.0.4762.1000</version> <publickeytoken>71e9bce111e9429c</publickeytoken> <relpath>Microsoft.SharePoint.Client.Silverlight.dll</relpath> <extension downloadUri="Microsoft.SharePoint.Client.Silverlight.zip" /> </assembly> </manifest>
A similar file is also then defined for Microsoft.SharePoint.Client.Silverlight.Runtime.dll.
To use application library caching for a SharePoint Silverlight client, you would do the following:
- Configure your Silverlight project to use application library caching. To do this, select Reduce XAP size by using application library caching on the properties page of your project.
- Rebuild the application.
Once you rebuild your solution, you will see zip files in the output directory for each system assembly. If you also added the external mapping files for the SharePoint client assemblies, you will see a zip file for those assemblies. You should also notice that the size of your XAP file has been reduced substantially. The application manifest embedded in the XAP file instructs the Silverlight runtime to download these assemblies separately. For example, the following code shows the application manifest contained in the Client.CSOM.Silverlight.xap file, from the Client reference implementation, after rebuilding the solution with application library caching turned on.
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="Client.CSOM.Silverlight" EntryPointType="Client.CSOM.Silverlight.App" RuntimeVersion="4.0.50401.0"> <Deployment.Parts> <AssemblyPart x:Name="Client.CSOM.Silverlight" Source="Client.CSOM.Silverlight.dll" /> </Deployment.Parts> <Deployment.ExternalParts> <ExtensionPart Source="Microsoft.SharePoint.Client.Silverlight.zip" /> <ExtensionPart Source="Microsoft.SharePoint.Client.Silverlight.Runtime.zip" /> <ExtensionPart Source="System.ComponentModel.DataAnnotations.zip" /> <ExtensionPart Source="System.Data.Services.Client.zip" /> <ExtensionPart Source="System.Windows.Controls.Data.zip" /> <ExtensionPart Source="System.Windows.Controls.Data.Input.zip" /> <ExtensionPart Source="System.Windows.Data.zip" /> <ExtensionPart Source="System.Xml.Linq.zip" /> </Deployment.ExternalParts> </Deployment>
Once this is completed, you will need to deploy these zip files alongside the XAP file to your SharePoint environment. The zip files and the XAP file must be in the same location, regardless of whether that location is a physical folder on the server or a document library. If you deploy all of the Silverlight applications on your site collection to the same library, then you only need to include a single zip file for a particular assembly, even though multiple Silverlight applications use the assembly. If BLOB caching is enabled, each zip file will only be downloaded once. This significantly reduces download times and bandwidth utilization.
An alternative to deploying the zip files alongside the XAP files is to deploy the zip files to one central location. In this case, you must define the URL of this location in the external mapping file for each assembly, as illustrated by the following example. The extension element indicates the location of the zip file.
<?xml version="1.0"?> <manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <assembly> <name>Microsoft.SharePoint.Client.Silverlight</name> <version>14.0.4762.1000</version> <publickeytoken>71e9bce111e9429c</publickeytoken> <relpath>Microsoft.SharePoint.Client.Silverlight.dll</relpath> <extension downloadUri="http://contoso/XAP/Microsoft.SharePoint.Client.Silverlight.zip" /> </assembly> </manifest>
As a result, the application manifest will include a reference to the full URL from which to download the zip file. The following code shows the resulting application manifest file after we updated the external mapping file for the Microsoft.SharePoint.Client.Silverlight assembly. As you can see, the assembly is now referenced by a fully qualified URL.
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="Client.CSOM.Silverlight" EntryPointType="Client.CSOM.Silverlight.App" RuntimeVersion="4.0.50401.0"> <Deployment.Parts> <AssemblyPart x:Name="Client.CSOM.Silverlight" Source="Client.CSOM.Silverlight.dll" /> </Deployment.Parts> <Deployment.ExternalParts> <ExtensionPart Source="http://contoso/_layouts/XAP/Microsoft.SharePoint.Client.Silverlight.zip" /> <ExtensionPart Source="Microsoft.SharePoint.Client.Silverlight.Runtime.zip" /> <ExtensionPart Source="System.ComponentModel.DataAnnotations.zip" /> <ExtensionPart Source="System.Data.Services.Client.zip" /> <ExtensionPart Source="System.Windows.Controls.Data.zip" /> <ExtensionPart Source="System.Windows.Controls.Data.Input.zip" /> <ExtensionPart Source="System.Windows.Data.zip" /> <ExtensionPart Source="System.Xml.Linq.zip" /> </Deployment.ExternalParts> </Deployment>
One of the drawbacks of this approach is that you must modify the external mapping files for the system assemblies, which by default are located at C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client. Since these URLs are embedded in the application manifest files, you will likely need to rebuild your Silverlight applications for production environments. As such you would need to implement a policy for building XAPs for specific environments, or configure development and test environments to mimic production URLs. The advantage of this approach is that you can define a single download location for your entire organization. As a result, the assemblies are cached by browsers for all of the Silverlight applications built with application library caching within your organization.
For more information on application library caching, see How to: Use Application Library Caching on MSDN.
Ajax and Silverlight clients offer many inherent benefits over traditional thin clients in the area of responsiveness. A thorough understanding of these benefits can help you to take maximum advantage and provide a slick, responsive user experience.
Asynchronous Execution Model
Ajax and Silverlight clients typically have a higher initial load cost compared to traditional thin client approaches. However, in most cases you will more than compensate for that load cost through enhanced UI responsiveness. Since the UI is controlled from the client, in many cases the client can react locally to user interaction without communicating with the server. When the client needs to send or retrieve information from the server, the communication takes place asynchronously and the UI remains responsive. The ability to build more capable UIs that run on the client also means that you can include more functionality on a single page. This compensates for the slower initial page load time, as pages typically need to be loaded far less frequently.
Local Processing Power
In almost all web UI models, the operations that take the most time are those that require communication with the server. Both Ajax and Silverlight allow you to take advantage of client-side processing, which reduces the number of round-trips to the server. When communication with the server is required, the data exchange is restricted to only what is necessary for the operation. This contrasts with the traditional server controls approach, in which every request from the client results in the server building and resending the entire page—even if many areas of the page remain unchanged. This increases the load on the server, increases the volume of network traffic—the average page size is several orders of magnitude larger than the average asynchronous data request—and results in a somewhat disjointed user experience.
Client-side Data Caching
RIA clients such as Ajax and Silverlight can maintain state information on the client. This contrasts with traditional thin client approaches, where state must be maintained on the server and tracked through cookies or posted back and forth with every request through view state. Data retrieved from the server can be retained in memory and reused across different operations. For example, suppose a manager must approve 20 orders once a day. With a thin client (server control) model, the manager navigates into an order, reviews the line items, and approves the order. Each time the manager approves an order, he or she is redirected back to the order list. The remaining orders are reloaded on the server, which rebuilds the page and sends it back to the browser. With an RIA approach, the orders are retrieved once and stored on the client. As the manager navigates into each order, the line item details are retrieved asynchronously from the server, and approvals are sent asynchronously back to the server. In this case the orders have only been retrieved once, and the client is far more responsive since it can cache the information in memory and avoid unnecessary round-trips to the server.
Predictive loading approaches anticipate the actions of a user to make the client seem even more responsive. Building on the previous example, you could assume that managers will work through approvals in the order in which they are listed in the UI. The client might then anticipate that the order which appears after the order being currently viewed will be viewed next. As such, the client could retrieve the details of the next order in advance, in order to avoid any delay in retrieving the information from the server. However, if the manager chooses to view a different order next, they will incur the usual delay while the data is retrieved asynchronously from the server. The disadvantage of this approach is that you are performing additional server-side processing that may not be used. As such, you should use this approach when you can predict the actions of the user to a fairly high degree of accuracy.
For more details on these concepts, see patterns & practices Web Client Developer Guidance.
In traditional, server control-based user interfaces for SharePoint applications, security concerns were largely managed for you by the server environment. Authentication was managed by IIS (for Windows credentials) or by an ASP.NET authentication provider (for forms-based authentication). The SharePoint environment would then apply authorization rules to the authenticated credentials for each server resource. When you move to a client-based, RIA user interface, there are some additional aspects to managing security that you will need to consider.
Each of the client-side programming models provided by SharePoint 2010 is underpinned by a secure web service.
- The REST interface is provided by the listdata.svc WCF service.
- Backward-compatible client-side access to various resources is provided by ASP.NET (ASMX) web services.
When you develop Ajax and Silverlight clients that run within a SharePoint web page, the client-side object model and the REST interface will by default inherit the security credentials that were used to authenticate the browser session. In this way, Ajax and Silverlight will support any mechanism with which you can authenticate a browser session, including Windows authentication, forms-based authentication, and claims-based authentication.
When you use the managed client API for stand-alone clients, you can specify the authentication mode and other security details through the ClientContext instance. For example, the following code example configured the ClientContext instance to use forms-based authentication and specifies a user name and password.
ClientContext context = new ClientContext("http://contoso/sites/manufacturing"); context.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication; context.FormsAuthenticationLoginInfo = new FormsAuthenticationLoginInfo(myUsername, myPassword);
The ClientContext class is discussed in more detail in Data Access for Client Applications.
You can also use claims-based approaches to authentication from a stand-alone client, although this is more complex and is not within the scope of our guidance. For more information on security for the .NET managed client API, see Authentication in the Managed Client Object Models on MSDN. For more information on using claims-based authentication with a stand-alone client, see the blog post Using the Client Object Model with a Claims Based Auth Site in SharePoint 2010.
When you access SharePoint ASP.NET web services that are secured with forms-based authentication from a Silverlight client, you must call the Authentication web service and provide your credentials. The Authentication web service returns a cookie, which you can supply to the other SharePoint web services in order to authenticate your requests. For more information, see Authentication Web Service on MSDN®.
Cross-Domain Data Access and Client Access Policy
Both Ajax and Silverlight clients are subject to certain restrictions and caveats when it comes to accessing data from a different domain. Cross-site scripting (XSS) attacks were one of the most prevalent threats to web applications, so modern browsers now prevent scripts from making calls across domain boundaries. As a result, Ajax clients have traditionally been unable to access resources on a different domain. Developers often worked around this limitation by including a proxy on the web server that retrieves data from external services. However, emerging standards allow script calls across domain boundaries if those calls are explicitly permitted by the server hosting the web page. This is based on the W3C draft specification Cross-Origin Resource Sharing (CORS). The most recent versions of the major browsers support CORS, although not in entirely consistent ways. Implementing CORS is beyond the scope of this guidance. For more information, see AJAX - Introducing Cross-domain Request (XDR) on MSDN.
In the case of Silverlight clients for SharePoint 2010, there are two key cross-domain data access scenarios that you need to consider:
- When a Silverlight application on a SharePoint page needs to access data from an external (non-SharePoint) service on another domain.
- When a Silverlight application on any page, SharePoint or otherwise, needs to access data from a SharePoint web application on another domain.
Silverlight considers different ports, different protocols, and different sub-domains to represent different domains. For example, https://services.contoso.com, http://services.constoso.com, http://www.constoso.com, and http://services.contoso.com:8080 are all considered different domains.
In the first scenario, the fact that the Silverlight application is hosted on a SharePoint page is irrelevant. Silverlight looks for a client access policy file (clientaccesspolicy.xml) on the external domain to determine whether it is allowed cross-domain access to resources on that domain. The client access policy should be located at the root of the site you are attempting to access on the external domain. Silverlight can also use an Adobe Flash cross-domain policy file (crossdomain.xml) if the client access policy is not present. This scenario is illustrated by the following diagram.
Cross-domain access to non-SharePoint resources
Essentially, the service owner modifies the client access policy to specify which domains are allowed cross-domain access to which resources. For more information, see Making a Service Available Across Domain Boundaries and HTTP Communication and Security with Silverlight on MSDN. The Client.ExtService.Silverlight project in the client reference implementation also demonstrates how to use a client access policy to permit access to cross-domain resources from a Silverlight application.
In the second scenario, a Silverlight application needs to access SharePoint data on a different domain. This could be a Silverlight application running in a standard web page, running as a stand-alone application, or running in a SharePoint web page from a different web application. In this case you need to take a different approach, as modifying the client access policy in a SharePoint environment is not supported. Instead, SharePoint 2010 provides a framework named Silverlight Cross-Domain Data Access, or Silverlight CDA, that allows farm administrators to manage access to resources from clients on other domains. This scenario is illustrated in the following diagram.
Cross-domain access to SharePoint resources
Configuring Silverlight CDA is beyond the scope of this guidance. However, you can find detailed guidance at Web Parts that Host External Applications Such As Silverlight on MSDN.
For more information on cross-domain data access, see What's New: Silverlight Integration and Cross-Domain Data Access on MSDN. For more information on Silverlight security in general, see Silverlight Security, Silverlight Security Overview, and Security Guidance for Writing and Deploying Silverlight Applications.
Overcoming Sandbox Restrictions
As described in Execution Models in SharePoint 2010, SharePoint 2010 restricts the functionality of solutions that are deployed to the sandbox environment within a site collection. One way to address the limitations of sandboxed solutions is to implement the restricted functionality in your client-side logic. Sandboxed solutions can include both Ajax and Silverlight components that run in the client browser. Scenarios in which you might choose to implement functionality in client logic include the following:
- When you need to access data from an external service. The sandbox environment does not permit server-side code to call external services. However, an Ajax component or a Silverlight application can call an external service and retrieve data directly from the client.
- When you need to access data across site collection boundaries. The sandbox environment does not allow you to access data from outside the site collection in which the solution is running. However, an Ajax component or a Silverlight application can use the client data access mechanisms to access data from any site collection where the user has sufficient permissions.
- When you need to access more advanced capabilities, such as the user profile service, that are not available with the sandbox environment. However, you can use the SharePoint ASP.NET Web Services to access these capabilities.
When you access SharePoint data, each client-side data access mechanism is secured by the SharePoint environment. As such, users can only access resources on which they have the necessary permissions, and security is maintained. A more important consideration is the processing load that you place on the client. The sandbox environment prevents you from performing expensive, process-intensive operations in server-side code in order to maintain the performance of the server as a whole, so circumventing these safeguards by moving process-intensive operations to the client is likely to result in a poor user experience. For example, aggregation across site collection boundaries is an expensive operation and should be used judiciously from client-side code.
In more complex scenarios, you can use Ajax and Silverlight to build composite client UIs that bridge SharePoint data and external data. For example, you might retrieve a list of statements of work from a SharePoint document library. When the user selects a statement of work in the user interface, an Ajax or Silverlight client can then retrieve information for that vendor from a vendor management system. In this way, the client is bridging the SharePoint environment and the external service to provide a composite data application.
Clearly, when you bridge services in this way you need to consider how to authenticate to each service. The Client reference implementation demonstrates how to bridge services using Windows authentication. The use of other authentication techniques, such as claims-based authentication, is beyond the scope of this guidance. For an example of how to use claims-based authentication with Silverlight, see the Silverlight and Identity Hands-on Lab in the Identity Developer Training Kit.