The integrated architecture means that the webapplication and WebSync Server run in the same IIS pool. In Azure this means you can spin up a new instance when the running instance(s) run out of resources.

Isolated Application Architecture:

Img 02: Isolated Application Architecture WebSync

The isolated architecture means that the webapplication and WebSync Server run in separate IIS application pools. At this moment in time we implemented the integrated architecture, but we are debating if we need to go for the isolated architecture, we think it is more robust and gives us the opportunity to decouple the real-time, or notification logic even more.

ROBIN Deployment Architecture We have the following deployment architecture:

Img 03: ROBIN Deployment Architecture

As image 03 shows we use the integrated architecture, realtime is part of our Process Services layer. In our Frontends, API’s and Background Worker layers we leverage Websync to do the real-time handling for us.

Storage ProviderWebSync needs storage, and supports the following providers out-of-the-box:

Sticky Providers

In Memory Provider (Default)

Sticky Sql Provider

Stateless Providers

Stateless Sql Provider

Azure Table Provider

We use the Stateless Sql Provider, because it is the fastest provider WebSync supports that works on Azure. We already had an on premise working version that used the Sticky SQL Provider, switching seemed the easiest. We think switching to the Azure Table Provider will be easy and we will do this if we need it for scalability reasons, we would like to avoid this because we want the best performance possible.

Database deployment script (we do not want WebSync to generate the tables it needs in our production environment)

Configuration (web.config for the most part, we really want to leverage Azure’s ServiceConfiguration for this, but webSync does not support it at this moment)

Server-side publishing

Client real-time handling

Database deployment script and configurationThe database deployment was easy, because WebSync can generate the tables for you (default). The only thing we had an issue with, is that if you do not want WebSync generating the tables, but create them yourself, you have to add that in config. you have to use the manageSchema atrribute:

Server-side publishingOn the server-side we lean heavily on Inversion of Control or Dependency Injection. We find it is real helpfull to compose our objects as we see fit, and it also helps tremendously in our TDD workflow. Because we need to support al kind of clients (webapplications, iPhone, other mobile devices) we evolved to the following (simplified) implementation:

Ofcourse, our implementation consists of more, but this, in short, is how we wrap WebSync. We got a RealtimeService (which implements IRealtimeService)and have the notion of 'Publisher', for every frontend (webapplication, device) we have a Publisher implementation, we inject these using Dependency injection. It makes us really flexible. For every new Publisher type we only have to create a new Publisher implementation, or leverage an existing one.

Client real-time handlingOur main webapplication has a ‘one page architecture’, we have a single page and use Javascript to show different parts of the application on that page. We use module and jquery widget factory patterns. We are looking into backbone, ember and knockout. We have the notion of a ‘Communicator’ in our clientside architecture. In the Communicator we handle the subscriptions and all incoming real-time (push) messages.

As you can see in listing 04 the communicator also uses a jQuery plugin for pub/sub. This plugin makes it possible to use the publish-subscribe pattern throughout our modules and widgets. This plugin uses topics to differentiate between publications. Whenever a real-time message is pushed from the server, a $.publish(…)event for a particular topic is fired and all subscribers to this topic will recieve the message.

I made the listings as small as possible, to show the intend. The WebSync client api is clean and self explaining. You have to init, than connect and subscribe. We have lots of advantages from using WebSync, the administration of what clients are connected to which subscriptions is abstracted away for the most part. The way WebSync handles all browsers is a big benefit also, we implemented WebSockets ourselves and had to do all that work manually untill now.

At Trinicom, the place I work, we are creating a new customer experience product. We lean heavily on good engineering practices and use Scrum as our development process. For the application we defined cornerstones, or fundamentals: usability being one of them. Because our application needs to be zero footprint web based, we use JavaScript a lot, mostly JQuery actually. We structure our JavaScript code using module and jquery widget patterns. We are thinking about implementing an mvc framework for Javascript, or use something like knockout.js, because we depend on real-time data. Our application needs real-time info and because we develop for the future we are leveraging Websockets to make the real-time updates a reality. As I mentioned we lean on good engineering practices, TDD is important for our C# code, so because we develop more and more JavaScript code, we are using TDD for our client-side code also.

QUnitWe use QUnit for our JavaScript unit tests. We use Continuous Integration and run our unit tests at every check-in, on TFS 2010. We wanted that for our JavaScript unit tests also. So we started searching for information, there was very little. It seems that most ASP.NET devs do not integrate JavaScript unit tests into their builds, or do not unit test their JavaScript at all.

Web Client Developer Guidance The Web Client Developer Guidance from Patterns & Practices on Codeplex provides some information on how to integrate QUnit unit tests into a TFS 2008 build. The problem was, that the guidance is incomplete and unclear. The P&P group created the QUnitExtensions.js that provides the familiar Asserts C# developers know and love, isTrue, isFalse, areEqual, IsNull, isNotNull, isUndefined, isNullOrUndefined, isNotNullNorUndefined. The guidance exist of a ASP.NET MVC app that takes JSON and serializes that to some xml format. The xml format is than persisted on disk. The JSON is provided by the QUnit testrunner that is extended and uses the url to a Controller of ASP.NET MVC app that takes JSON. The extended testrunner serializes the testresults into a hidden formfield and submits the contents of the field to the MVC app’s controller.

The format that was persisted to disk is unfamiliar and does not seem to map to any TFS format. The guidance says all you have to do is write the xml file to disk and tell the buildserver where it is by using an msbuild script and the result is written to the buildlog etc. That did not do the trick for us.

Workflow Activity We created a Workflow activity that we use in our build workflow.

The activity takes a file and deserializes the xml into objects, it than uses the object graph to report into the buildlog if the unit test where succesfull, or not.

TestRun Domain objects

Img 1: The TestRun domain

Image 1 shows the domain objects of the TestRun. A TestRun has one or more TestCases and a TestCase can have an Output that is of the ErrorInfo type. A TestCase has an OutCome and a StatusPassed, if an Exception was thrown, the details of that Exception are found in the Output property. The TestRun has three properties that hold the result for the run, how many Tests where run (TestTotal), how many Test failed (TestFailed) and how many tests passed (TestsPassed). The Activity ofcourse uses the three properties of the TestRun to decide wether the Run was succesfull or not. When the TestRun is not successful, the TestCases that failed are written to the buildlog and the build will fail.

ITestResultSerializer interface The Web Client Developer Guidance contains an MVC application that uses an interface named: ITestResultSerializer. I wrote our own implementation that is simpler than the implementations provided by Patterns & Practices. They use XmlTextWriter to write out the xml, I just serialize the objectgraph to xml.

The TfsTestResultSerializer writes the xml to a location on disk. The build workflow knows this location and picks the xml up and the Activity publishes the results to the buildlog of our TFS 2010 TeamBuild.

Workflow – BuildTemplate

To make it possible to run JavaScript unittests in an TFS 2010 Teambuild, I made some changes to the workflow of the BuildTemplate.

ArgumentsIn the workflow I defined a few Arguments, that can be set in the builddefinition. The arguments are:

In the default BuildTemplate there is an Activity that is called: “Run Tests”. You can find it if you follow the default BuildTemplate and click your way through the following path in the workflow:

Process > Sequence > Run On Agent > Compile, Test, and Associate Changesets and Work Items > Sequence > Compile, Test, and Associate Changesets and Work Items > Try Compile and Test > Compile and Test > For Each Configuration in BuildSettings.PlatformConfigurations > Compile and Test for Configuration > If Not DisableTests > Run Tests

Below the “If Then” Activity: “If Not TestSpec Is Nothing” I add my own “If Then Activity” and call it: “If RunJavascriptUnittests is True”.

Img 3: Run Tests Sequence Build Workflow

In the If I check a boolean Argument I added to the builddefinition (as stated in the Arguments section above), that is used to specify if we want to run JaveScript Unittests in the build.

Img 4: If RunJavaScriptUnitTests is set to true

If this argument is set to true, the “Then” branche in the If then Activity is folllowed. In the “Then" part I add a Sequence called: “Run Javascript Unittests”.

In the “ForEach” Activity all strings in the “JavascriptUnittestBrowserFiles” argument are iterated over, these strings hold the path and name of the executable of a browser on the buildserver (for example “C:\users\username\AppData\Local\Google\Chrome\Application\chrome.exe”). Inside the Body another “ForEach” activity “Foreach testRunner in JavascriptTestRunnerFiles” exists.

Sequence

Img 7: For each testrunner in argument

This “ForEach” Activity will iterate over all strings in the Argument: “JavascriptTestRunnerFile”, this is so that we can have more than one html file containing Javascript unittests. Inside the body I put another Sequence activity (img 8).

Img 8: Sequence that does the work

WriteBuildMessageThe “WriteBuildMessage” only writes to the buildlog for debugging purposes, also it comes in handy when someting goes wrong in a build sometimes.

Listing 4 shows how the Arguments are built up: It tells the browser to open the “JavascriptTestRunnerFile” which holds the html filename in our project as a file on the filesystem, we use the “"BuildDirectory” variable and the kwoledge where the websites are published in this directory to point to the right file. Next we add querystring variables and values so the testrunner javascript file knows where to send the results of the tests and which build we run, what solutionconfiguration we are building etc .

browserFile.Substring(0, browserFile.LastIndexOf("\"))

Listing 5 Working Directory

Listing 5 shows the value for the Working directory property.

FindMatchingFilesThe next step is to check if the results are written to disk as expected, with the “FindMatchingFiles” activity using the MatchPattern shown in Listing 6:

Now the circle is full, and the results can be written to the buildlog.

Img 14: Passed unittests in log details

Of course when a test fails the build fails partially (like normal unittests) and the result shows in the buildlog summary, the results like shown in img 14 are only visible in the details (diagnostics) part of the buildlog.

Ever since ASP.NET MVC Framework 2.0 has released I did not have a change to work with the new validation logic. The DataAnnotations that are the only place where you have to keep logic related to validation, no more having to write the same logic in several places.

Today I wanted to give it a try, since I can delete lots of code from my views, if it works as promised. I want to use jquery.validate.js (ships out of the box with Visual Studio 2010 and ASP.NET MVC Framework 2.0. But to my surprise only files that support the MicrosoftMvcValidation.js are available with the project template for a ASP.NET MVC 2 Web Application.

MicrosoftMvcJQueryValidation.jsWith the ASP.NET MVC 2 RTM release a file named MicrosoftMvcJQueryValidation.js was shipped. I downloaded the RTM once again and got the MicrosoftMvcJQueryValidation.js file.

In my view I now add the following script tags:

Listing 1: Script tags

Enable validation on a view clientside
Than below script tags, I put the following call to enable validation on the client.

<% Html.EnableClientValidation(); %>

Listing 2: Html.EnableClientValidation

This call (listing 2) bubbles up the validation rules as Json data, the MicrosoftMvcJQueryValidation.js leverages jQuery to do the client side validation.

I added the code from listing 1 and 2 onto the logon.aspx from a vanilla ‘file > new project > ASP.NET MVC 2 Web Application’ and it worked as I expected.

Contents MicrosoftMvcJQueryValidation.js
Because it took me some effort to get the MicrosoftMvcJQueryValidation.js I will put the code here:

I used to like Syntaxhighlighter, but when I started using blogengine.net I did not implemented it. In blogengine.net a plugin is available from manoli.net. The bad part is, that I have to go to the manoli.net website and generate html from my C#, SQL, Javascript and other code, every time I want to use code in my posts.

So I started to look into Syntaxhighlighter again. It matured quite a bit, but still lacks type support (manoli also does not support this, by the way!). Still, I like it a lot, I suppose it can save me lots of time.

Beauty of Code jQuery plugin

Lars Corneliussen wrote a jQuery plugin for SyntaxHighlighter and it makes the process of incorporating it on a html page a lot smoother. I used this with my first tryout to use the plugin in blogengine.net. I think it is an elegant way to use syntax highlighter, so i want to share, how it works. Ofcourse you have to reference jQuery in the head element of your page. In addition to that we add a reference to the jquery.beautyofcode.js (the code written by Lars).

Listing: 1

To initialize the highlight functionality, you have to add the following javascript code to a page:

The point is that my blog does not accept the pre tags with a nested code tag that has a class attribute. TinyMCE is used and somehow it strips the entire class attribute, thus the highlighting never takes place…

I am now using the default way, without jQuery. This works niceley, with a caveat: XML tags (html) are transformed to uppercase, when saving a post through the TinyMCE standard blogengine.net manner of creating and editing posts, but also when using Windows LiveWriter. I will try to find out more about this, because I really do not like uppercase tagnames!

The default syntax highlighter configuration

First you need to reference the scripts and stylesheets syntax highlighter needs to do the job, so in the head of the page you need to highlight code on, you add the following js and css references:

Listing: 4

Of course you only need to add the the brushes that you really use.

Next you need to instantiate the javascript object, you need to add the following javascript in a script block (also in the head of the page):

The clipboard.swf (Flash file) is used to make it possible for the user that visits your site, to copy the code to his or her clipboard, without an alert from the Operating System. The .all() method initializes takes care of the actual highlighting.

Now I can use it, by letting syntax highlighter know what brush to use, like this:

alert('Hi, I love highlighted syntax!');

Listing: 6

The next few posts, I will try it out some more, but the first impression is a positive one.

Doing a MS CRM 4.0 project, where the requirement is to create a toolbar button on a detailform.
This button needs to open a window (prefferably a modal window). In this window users can make some selections and when submitting, some processing will be done using these selections, this is not important for this post.

When thinking about this requirement, I really wanted to use something like the ASP.NET AJAX Control ToolKit's Modal Popup. Also I am really impressed by jQuery, a JavaScript library, that is an elegant and easy to use abstraction over JavaScript. It simplifies document traversing, event handling, animation and Ajax interactions. I knew about jqModal a jQuery plugin that simplifies display of dialogs and modal windows.

NOT FULLY SUPPORTEDIf you are a developer working with MS CRM, you know that it is higly customizable, but within it's own boundries. An important matter on this project particularly is that customizations need to be supported by Microsoft. What I am about to explain is NOT FULLY SUPPORTED, because I will use external.js files, using a link element to import it in the page. But I want to explain also, that it is possible to do this without using external files, you could paste the contents of the 'jquery-1.2.6.min.js' file into the onload function of the detailform's property window.

I wanted to give it a try, because, well just think about the possibilities for a while. If you can use jQuery in CRM development, a lot of possibilities open up.

FIRST STEPS
So the first thing to do is to put the 'jquery-1.2.6.min.js' file in a '_customscript' folder in the CRMWEB root folder. Next I need a way to reference the file, so it's contents can be called from the page. Like I already posted in my blogpost External js file and CRM, I like to do this using the Msxml2.XMLHTTP object. The function reads the contents of a file and imports all functions found into the current namespace, so they are accessible.

1: function load_script (url)

2: {

3: var x = new ActiveXObject("Msxml2.XMLHTTP");

4: x.open('GET', url, false); x.send('');

5: eval(x.responseText);

6: var s = x.responseText.split(/\n/);

7: var r = /^function\s*([a-z_]+)/i;

8: for (var i = 0; i < s.length; i++)

9: {

10: var m = r.exec(s[i]);

11: if (m != null)

12: window[m[1]] = eval(m[1]);

13: }

14: }

15:

16: load_script("/_customscript/jquery-1.2.6.min.js");

17: load_script("/_customscript/jqModal.js");

18: load_script("/_customscript/jqDnR.js");

19: load_script("/_customscript/customscript.js");

Listing 1

As you can read in listing 1, the 'jqModal.js' file is also referenced, this holds the jqModal library, I also load 'jqDnR.js' a jQuery library that supports dragging and resizing. I also load 'customscript.js', this is a custom javascript file that will hold the function that is called when the button on the details window is clicked.

CSS STYLESHEETBecause we do not want to mess with the stylesheets used by CRM we also need to add a stylesheet containig the modal window's styles to the filesystem. I made a css folder below the _customscript folder, the folder where I put the javascript libraries. You could add these styles through Dom manipulation in JavaScript also, to keep the customization supported by Microsoft!
I use the following code, you can do this in the OnLoad function of the details form, or in a separate function, that you call from the Onload function. I use the function that also checks if the reference exists already, but for simplicity put this in the On Load after listing 1.

CREATE DIV (MODAL WINDOW)Next we need to add the div to CRM's details page. I wanted to this using the DOM, but for some reason it would not work. If anybody knows the reason why, please let me know!
Instead i used the following approach, again: you can do this in the OnLoad function of the details form, or in a separate function, that you call from the Onload function.
In the real world project I use the function, but for simplicity in this example, I just put this in the On Load after listing 2.

1: // Not using dom to add new elements, because for some reason that does not work!

As you can read in listing 4 first I get the body element and assign it to the 'body' variable. Than I create two div elements, the reason I do not create a div element and use setAttribute to set the attributes, but create the element in one line using a string containing the whole tag is that I could not get it to work, again let me know if you do! The first div will be our modal window. The second with id 'jqmTitle' is the header. Next I Create a span that will contain the text for the header, a (close) button that will be placed in the header on the right side.
And an iframe, in this iframe any (custom) page can be loaded.

INITIALIZE MODAL WINDOW USING jQUERYTo initialize the modal window, we have to add listing 5 to the OnLoad function of the details form in CRM after listing 4.

1: $().ready(function() {

2: $('#dialog').jqm();

3: $('#dialog').jqm().jqDrag('#jqmTitle');

4: });

Listing 5

In Listing 5 we use jQuery syntax. We attach the code to the OnReadyState eventhandler of the document. when the document is fully loaded the element with id 'dialog' will be registered as a jqModal window by line 2. Line 3 registers the dragging functionality of the element with id 'jqmTitle' inside the modal window (our header div).

CUSTOMIZE ISV.CONFIG XMLNow we only have to do two more things, the first is that we have to change isv.config.xml to create the button on our detail form, I use the contact and need the modal window functionality on the contact entity's form. I made the following change to the isv.config.xml:

Listing 6 displays part of the xml, the IsvConfig element holds an element configuration , which holds the Entities element. I need the contact Entity. The MenuBar element holds CustomMenus, which holds Menu. I added a Menu element with Title "Documenten" (LCID="1043" which means dutch). The Menu element holds MenuItem elements. I added a MenuItem element With a dutch Title and a JavaScript attribute that has the value 'ShowModalWindow()'. When we import the isv.config.xml and publish the customization changes, we see the menuitem is added.

CREATE JAVASCRIPT FUNCTION THAT SHOWS MODAL WINDOWIn listing 1 on line 19 we saw that the external javascript file 'customscript.js' is loaded in the OnLoad function of the details form. 'customscript.js' is a custom javascript file that holds the 'ShowModalWindow()' function.
As I mentiod earlier we had to do 2 more things, the first was the customization of the isv.config.xml and the second is to create this function:

Addition:

I added line 1 after Imane pointed out the variable customPagesVirtualDir was not declared, thanks for telling me!

Listing 7 displays the 'ShowModalWindow()' function, the crmForm.ObjectId is assigned to a variable contactId. A variable popupUrl is filled with the url to a custom aspx page. Line 7 is jQuery syntax and assigns the url to the src attribute of the iframe inside the modal window. Line 8 opens the modal window and assigns true to the modal property, So the behaviour of the dialog will be like a modal dialog.

EXAMPLE

Picture 1: Contact details form

In the menu a button is added:

Picture 2: Menu item

When a user clicks on the menu-item, the function ShowModalDialog is called in the external js file that is referenced in the OnLoad function of the page where the jQuery plugin loads the modal window (client-side!) and the users sees picture 3:

Picture 3: jQuery and jqModal in action on a contact details form

CONCLUSIONPersonally I think this is awsome, jQuery is real easy to use and complex matters seem simple. It is a joy to use jQuery with CRM. This combination opens up a world of possibilities. Ofcourse CRM is a web application and customizable, so you could expect external libraries targeted to web applications to work with it. But for me the experience to open a modal dialog like this on a CRM details window without hacking CRM code...
Well I will stop rambling, you can judge yourself.