CRM 2011 Web Resources: Simulating Directories and the Importance of Relative Paths

Feels good to be back. After ~2 weeks of vacation I’m back to the office and felt like blogging a bit he he. Let’s see if you find this post interesting.

By now many of you had already had the chance to play with CRM 2011 Beta. One of the most useful extensibility features that we incorporated into this release is Web Resources. In a nutshell Web Resources allow you to store client side code (Silverlight Apps, JavaScript, HTML, CSS, etc.) on the CRM server and reference that code in multiple places such as CRM forms, navigation links etc. A simple analogy is that CRM 2011 now allows you to store selected file types on the server and you can consume those files in multiple places. 

However web resources are NOT generic catch all file storage, they were designed specifically to support client side code. Also web resources are organization owned which means that a particular web resource cannot be associated exclusively to a single record, instead the whole organization (anybody with read privilege on the web resource entity to be precise) will be able to read the resource. While we designed the feature to shine with client side code I’m sure that developers will find very creative ways of pushing it to its limits :)

The SDK contains most of the details but I wanted to spend some time illustrating a fact that might not be evident at first sight; with web resources you can actually simulate directory structures. When you create a web resource you have to supply a couple of properties the key one being the unique name which can be roughly compared with the “filename” of the web resource. The important piece is that the unique name of a web resource (unlike a windows file) actually accepts the forward slash character, hence the following unique name is a valid one: “myprefix_/directory1/directory2/mypage.html”. What this means is that when you are developing your web resource locally on your machine you can maintain a clean directory structure that can be later replicated on the CRM server. Neat huh?

When you reference a web resource you should always use the appropriate mechanism to do so. Again, the SDK contains the details but in summary:

  • Referencing web resources from one of our designers is straight forward and the designer will take care of doing the right thing when referencing the web resource
  • Referencing web resources from CRM component that don’t have a designer (e.g. Ribbon, Sitemap) should always use the $webresource directive
  • Referencing web resources from other web resources (e.g. an html page referencing a js library) should always use RELATIVE paths.

All the above boils down to one important fact; depending on the deployment type (and other configuration such as domain name, caching, etc) that CRM is running the absolute URL of a web resource will be different. Simple example, a web resource whose unique name is “myprefix_/mypage.html” will translate into the following URLs:

So now you see why is so important to reference web resources appropriately. Both the CRM designers and the $webresource directive will take care of constructing the correct URL (and will also provide buil-in caching capabilities). As for referencing one web resource from another as long as you use relative references you should be fine. Just remember that any directory below /Webresources is out of your control. In the example if myprefix_/mypage.html wants to reference a js file under the custom scripts directory (e.g. the web resource unique name of the js file is ”myprefix_/scripts/myscript.js” the code would look like this

<html>
<head>
<script src=”scripts/myscript.js”
</head>

</html>

Notice how I referenced the script file using relative URLs, this would cause the browser to traverse forward and find the correct js file on the scripts directory (simulated using the name of the script file). The above will work for all CRM deployments without having to change a single line of code.

Happy coding