Click here to Skip to main content
15,885,032 members
Articles / Programming Languages / C# 5.0

Real-time development with SignalR and Dynamics CRM

Rate me:
Please Sign up or sign in to vote.
3.00/5 (2 votes)
1 Sep 2015CPOL5 min read 25.9K   8   5
This tutorial shows how to create Microsoft Dynamics CRM extensions that use ASP.NET SignalR to provide real-time messaging functionality

Introduction

This tutorial shows how to create Microsoft Dynamics CRM extensions that use ASP.NET SignalR to provide real-time messaging functionality. You will write plugin and JavaScript extensions to log in real-time changes to Contact entity.

Background

ASP.NET SignalR is a library that facilitates development of real-time web functionality. It allows bi-directional communication between client and server. SignalR uses Web Sockets where available and falls back to other transport techniques for older browsers. The library is based on OWIN (Open Web Interface for .NET), which defines abstraction layer between web application and server. Thanks to that SignalR can be self-hosted in your own process.

Create the server<o:p>

First you will set up server hosted in ASP.NET MVC 5 application.

  1. Open Visual Studio 2015 and create new empty ASP.NET MVC 5 project.

Image 1

  1. Using Nuget or Package Manager Console Microsoft.AspNet.SignalR package.

Image 2

To your solution should be added Script folder with SignalR and jQuery scripts.

  1. In Solution Explorer right-click on the project and Add | New Item. Select SignalR Hub Class (v2) and create new hub named LogHub.cs

Image 3

  1. Replace code in the file with following code.
C#
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

namespace SignalRHost
{
    [HubName("logHub")]
    public class LogHub : Hub
    {
        public void Send(string name, string message)
        {
            Clients.All.addLog(name, message);
        }
    }
}

Here you defined hub interface that clients will use to call your server.

  1. Again right-click on the project and Add | New Item. Select Owin Startup Class. Set up startup class as in the following snippet.
C#
using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(SignalRHost.Startup))]

namespace SignalRHost
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR(new HubConfiguration
            {
                EnableJSONP = true
            });
        }
    }
}

EnableJSONP paremeter enables JSOP for Cross Domain Calls on the server side. 

  1. Create new HTML file named LogPanel.html and copy the following code.
HTML
<!DOCTYPE html>
<html>
<head>
    <title>Dynamics CRM Log Panel</title>
    <meta charset="utf-8" />
    <style>
        table, th, td {
            border: 1px solid black;
            border-collapse: collapse;
        }

        th, td {
            padding: 10px;
        }

        td {
            text-align: center;
        }
    </style>
</head>
<body>
    <div>
        <h2>Dynamics CRM Log Panel</h2>
        <table border="1" id="logtable">
            <tr>
                <th>Name</th>
                <th>Modified On</th>
            </tr>
        </table>
    </div>

    <script src="/Scripts/jquery-1.6.4.min.js"></script>
    <script src="/Scripts/jquery.signalR-2.2.0.min.js"></script>
    <script src="http://serverurl/signalr/hubs"></script>
    <script src="LogPanel.js"></script>
</body>
</html>

Through this page you will be able to see logs send from clients. Replace serverurl with address of your SignalR server.

  1. Create a new JavaScript file named LogPanel.js and copy the following code.
JavaScript
$(function () {
    // Reference the auto-generated proxy for the hub.
    var logPanel = $.connection.logHub;
    // Create a function that the hub can call back to display messages.
    logPanel.client.addLog = function (name, date) {
        $('#logtable').append('<tr><td>' + name
            + '</td><td>' + date + '</td></tr>');
    };

    // Start the connection.
    $.connection.hub.start().done(function () {
        //calback
    });
});

In the code you first reference auto-generated proxy to your hub. Then you create call-back function that can be triggered by the hub to display message. Next you start the connection, you can also add code to .done() callback function that will be triggered after connection is started.

JS extension for Dynamics CRM

In this section, you will create JavaScript form extension that will be triggered onSave event on the Contact form. We will assume here that SignalR server is in different domain as this would be often the case in professional projects.

  1. In Dynamics CRM create a new solution and name it SignalR.
  2. Add to the Solution Contact entity and  following files.

Image 4

New_jquery represent jQuery library used in the Hub project, new_signalr.js represents SignalR library from the same project.

  1. In the SignalR solution add new Web Resource named new_hubs.js. Go to the following url.
http(s)://serverurl/signalr/hubs

Copy content of this file into new_hubs.js resource in Dynamics CRM. This file contains auto-generated Hub proxy, that will enable you to make a call to server with API you defined in Hub project.

  1. Create a new Web Resource in SignalR solution and copy the following code.
C#
function OnSave() {

    var connection = $.connection('http://serverurl/signalr');
    $.connection.hub.url = 'http://serverurl/signalr/hubs';

    var loghub = $.connection.logHub;

    $.connection.hub.start({
        jsonp: true
    }).done(function () {
        var fullname = Xrm.Page.getAttribute("fullname").getValue();
        var date = new Date().toLocaleString();

        loghub.server.send(fullname, date);
    });
}

In the first two lines you define connection to SignalR server and provide URL to the auto-generated hub. Next you create Hub object. As you can see hub has name defined by HubName parameter in the SignalRHost project. Last thing to do is to open connection between client and server. As it is Cross Domain Call, JSONP is enabled in connection parameters. In Callback function you call the server through Send method defined in LogHub.cs.

  1. In the SignalR solution open Contact | Forms | Contact (main form) | Form Properties. In Form Libraries add following JavaScript files (order is important).

Image 5

  1. In the Event Handlers section add OnSave event.

Image 6

  1. Now whenever you modify one of the contacts you will see new entry in the LogPanel.html.

Image 7

JavaScript client extensions works for Dynamics CRM On-Premise as well as Online version.

Plugin extension for Dynamics CRM

In this section, you will implement plugin that will log changes to Contact records from the server side.

  1. In the Visual Studio right-click on the solution and Add | New Project. Select Class Library and name it SignalRPlugin.
  2. Using Nuget or Package Manager Console Microsoft.AspNet.SignalR.Client package.

Image 8

  1. Using Nuget or Package Manager Console MSBuild.ILMerge.Task package

Image 9

In Dynamics CRM whenever you reference external libraries you have to make sure they are available from within Dynamics CRM. There is few methods to do this. In this tutorial you will merge external libraries into plugin DLL with ILMerge tool. Thanks to MSBuild.ILMerge.Task package we can automate the whole process and merge libraries during project build.

  1. In order for SignalR to work in plugin you have to merge two libraries: Microsoft.AspNet.SignalR.Client and NewtonSoft.Json. ILMerge will automatically merge all the libraries that have Copy Local property set to true. For the rest of assemblies Copy Local property should be set to False.

Image 10

  1. Right-click on the project Add | New Class and add new class named SignalRPlugin. Copy the following code into the file.
C#
using Microsoft.AspNet.SignalR.Client;
using Microsoft.Xrm.Sdk;
using System;

namespace SignalRPlugin
{
    public class SignalRPlugin : IPlugin
    {
        private string _serverUrl;

        public SignalRPlugin(string serverUrl)
        {
            if (String.IsNullOrEmpty(serverUrl))
                throw new InvalidPluginExecutionException("serverUrl");

            _serverUrl = serverUrl;
        }

        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            IPluginExecutionContext context = (IPluginExecutionContext)
                serviceProvider.GetService(typeof(IPluginExecutionContext));

            if (context.PostEntityImages.Contains("PostImage") &&
                context.PostEntityImages["PostImage"] is Entity)
            {
                var entity = (Entity)context.PostEntityImages["PostImage"];

                try
                {
                    var hubConnection = new HubConnection(_serverUrl);
                    IHubProxy logHubProxy = hubConnection.CreateHubProxy("logHub");
                    hubConnection.Start().Wait();
                    logHubProxy.Invoke("Send", entity["fullname"], 
                        DateTime.Now.ToLocalTime().ToString());
                }
                catch (Exception e)
                {
                    tracingService.Trace("Exception: {0}", e.ToString());
                    throw;
                }
            }
        }
    }
}

Similar to JavaScript implementation, first you have to establish connection with SignalR server and create object for LogHub proxy. Once connection is established you are ready to send data to the hub. Server URL is provided through constructor, which enable you to set it up during plugin registration process.

  1. Sign plugin project with the strong name key file. Only signed plugin assemblies can be executed by Dynamics CRM.

Image 11

  1. Once you have built plugin project, open Plugin Registration Tool from Dynamics CRM SDK and register plugin for Update step on Contact entity. Add SignalR server url to Unsecure Configuration box.

Image 12

  1. Register Post Image for Update step on Contact entity. You want to be sure that contact name is always available.
  2. Update one of you contacts to perform test, you will see new entry in LogPanel.html table.

Image 13

SignalR plugin extension works only for Dynamics CRM On-Premise as plugin assembly have to be registered outside Sandbox.

Summary

This tutorial shows two ways of utilizing SignalR in Dynamics CRM. Examples introduced in the article demonstrate how to easily provide real-time functionality in CRM system, both from server and client side. SignalR provides bi-directional communication between client and server, hence this study could be extended with functionality that receives messages on Dynamics CRM end.

You can find the entire project with the latest updates on my github repository.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United Kingdom United Kingdom
CRM Specialist focused on Dynamics CRM and .NET development.

Comments and Discussions

 
QuestionDynamics 365 Online Pin
HowlingMad212-Feb-18 7:33
HowlingMad212-Feb-18 7:33 
QuestionPlugin throwing Error Pin
deepumehta15-Sep-15 20:54
deepumehta15-Sep-15 20:54 
AnswerRe: Plugin throwing Error Pin
Michal Sobieraj15-Sep-15 22:33
Michal Sobieraj15-Sep-15 22:33 
GeneralRe: Plugin throwing Error Pin
deepumehta16-Sep-15 17:06
deepumehta16-Sep-15 17:06 
GeneralRe: Plugin throwing Error Pin
deepumehta16-Sep-15 17:12
deepumehta16-Sep-15 17:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.