Customer Engagement & Dynamics CRM Forum

Custom Azure Service Bus Messages from CRM

  • 1.  Custom Azure Service Bus Messages from CRM

    Posted 11 days ago
    If you want to send a message from CRM to an Azure Service Bus (ASB) topic or queue, you can use the built-in feature of registering an ASB endpoint and then register an entity action such as Create or Update against this endpoint. You also have the option of creating a plugin and passing the service endpoint GUID into the plugin and using the ServiceEndpointNotificationService to post the plugin execution context to that endpoint. This can work fine for some processes, but the context may contain a lot of things you don't need or want in a message, or it may not contain some data you need. Wouldn't it be great to be able to create a completely custom message and post it to an ASB topic? Well, you can.

    I researched a lot about this and found very little in the way of solutions. A couple of solutions seemed way harder than they should be and some involved ILMerge which is not supported in CRM plugins. I was trying to do a simple HTTP POST operation with a string message and it wasn't working because I was using a sample I found provided by Microsoft that uses a few helper class files and the System.Web.HttpUtility.UrlEncode method which is not supported in CRM. A colleague of mine found a way to get this to work that is very straightforward and simple using System.Net.Http.HttpClient and System.Uri.EscapeDataString. I was ready to give up on custom messaging and then she gave me this sample code.

    Your plugin will need the following references and using statements, all of which are supported. Note that through testing I found that CRM version 9 only supports up to .NET framework 4.5.2 and I haven't seen when it will support 4.6 and above. The sample code below works fine if your plugin project targets the 4.5.2 framework.

    References: System.Net, System.Net.Http
    Usings: System.Net, System.Net.Http, System.Security.Cryptography, System.Globalization

    The hardest part is getting the token. After that, it's as simple as:

    1. create an HttpClient
    2. add the token to the header
    3. create an HttpRequestMessage with the string content and the URL where you want to post
    4. send the request

    In this sample code, I have built up a string variable named json that is the JSON message I want to post. Then, I do the following:

    string asbUri = "https://<azurenamespace>.servicebus.windows.net/<topicname>/messages";
    TimeSpan ts = new TimeSpan(0, 0, 90);
    string sasToken = GetSASToken("sb://<azurenamespace>.servicebus.windows.net", "<nameofSASkey>", "<SASKeyValue>", ts);

    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Add("Authorization", sasToken);
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, asbUri)
    {
    Content = new StringContent(json, Encoding.UTF8, "application/json")
    };
    HttpResponseMessage response = client.SendAsync(request).Result;

    private static string GetExpiry(TimeSpan ttl)
    {
    TimeSpan expirySinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1) + ttl;
    return Convert.ToString((int)expirySinceEpoch.TotalSeconds);
    }

    public static string GetSASToken(string resourceUri, string keyName, string key, TimeSpan ttl)
    {
    var expiry = GetExpiry(ttl);
    //string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
    //NOTE: UrlEncode is not supported in CRM, use System.Uri.EscapeDataString instead
    string stringToSign = Uri.EscapeDataString(resourceUri).ToLowerInvariant() + "\n" + expiry;
    HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));

    var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
    var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}",
    Uri.EscapeDataString(resourceUri).ToLowerInvariant(), Uri.EscapeDataString(signature), expiry, keyName);
    return sasToken;
    }

    ​​

    ------------------------------
    Andy Arndt
    Minitab, Inc.
    State College PA
    ------------------------------