This is Part 2 of 2 of the Dynamics Solution Installer App series. So if you are following along, you will remember the original requirements for this application, ie. to create a really simple way that anyone in the business could setup a dynamics 365 custom solution for a customer.
Here’s Part 1 incase you missed it – Part 1 of 2 Dynamics 365 Solution Installer App.
As I mentioned in part 1, once the windows version of the application was developed and tested successfully, we wanted to iterate on this and see if we could move the custom solution installation process to the cloud.
This is the kind of challenge I relish as it required researching into what technologies would be best suited to deliver the requirements.
So one of the things I started looking into was if I should move over to using the newer dynamics 365 WEBAPI endpoints to perform the solution install & data import functionality from the cloud.
However, trying to pin down documentation and forum comments that allowed this type of functionally was hard to find so I assumed it wouldn’t be possible to perform from the WEBAPI endpoints at the time.
I did initially have concerns of the sdk endpoints being deprecated so I spent some time researching into this area to see if I needed to upgrade the system to using the webapi endpoints. However after much research I came to the following conclusions:
Hence, the backend WEBAPI code to interface with Dynamics 365 using the SDK remained the same as this already performed the bulk of the operations.
I already had experience with AngularJs from working on a mobile app to replace a paper-based workflow from a previous project so I started to do some research in this area to see if I could utilise existing skills that I could build upon to deliver a front-end ui that would communicate with the .net WEBAPI.
Like most technologies, angularjs has iterated on several versions since I used it from 2014 which was great to learn and use (Angular.js 1). However, now there was a newer way to write Angularjs since Angular 2.0 was released which was a complete re-write in the way applications were architected, which in my opinion felt rather bloated and overkill for what I required i.e. a UI to interface with WEBAPI endpoints and receive server-side notifications.
However, I had never looked at ReactJS but had heard lots of great things of how it was a minimal framework used just for building user interfaces.
As I started playing around with the framework, I got up and running very quickly and the framework felt like it wasn’t bloated with lots of things that I didn’t need. I looked up npm packages that were available that could help me achieve the desired UI and a simple to use library to receive data from WEBAPI.
For WEBAPI calls I came across react-axios which was perfect for handling Async Http communication in addition I found the following progress component react-sweet-progress that i felt would work perfectly to receive server-side notifications.
As you can probably guess, I choose ReactJS to so I could get going with the project.
The next challenge was to figure out how to setup server-side push notifications in real-time so that the user would be kept up to date with the progress of installing the dynamics solution and importing of data.
On my initial thoughts I thought I needed some type of polling mechanism from the client to request information on an interval, however this wouldn’t have been an efficient solution as it would be using too many resources on the client-side and also would have got messy. So I searched for a better solution.
Continuing on the learning journey I then came across Pusher [link out] which was very much what I wanted as it allowed data transfer from the server to client, but also client to server using a single connection. This was a better solution than the previous polling method as it didn’t need to keep asking the server for a reply.
However i did feel that this might be a little overkill for what I needed as it was both a paid solution after a certain time and I didn’t feel comfortable building a key feature on a 3rd-party platform incase there were issues. However, although I had my reservations i continued to research thinking that there must be another library that’s pusher is using to achieve this type of functionality.
Now this is were i feel Google is actually broken as it failed to return me the exact solution that I required to solve the following search term “server-side push c#”.
The top result for this should have been SignalR!
SignalR was the solution I needed to push data back to the client in real-time so I could keep the user updated on progress of their dynamics 365 installation.
In a nutshell, SignalR creates a connectionid for each instance of a client-side connection. This connection remains open and the server can push notifications via this connection to the client. Perfect, so what I did was setup a playground project to get a proof of concept working which I could understand.
It did what I needed so I put that into my toolbox for use later on when I needed to integrate it into my app.
I will write a little more about SignalR and how it works and link back to it from here, at some point!
In the windows application the dynamics solution was stored inside the application and uploaded to the CRM.
However, as we were using the cloud I needed an alternative method to store the document files required by the application.
To solve this after some research and testing, the solution was simple, store the documents in Azure and grab them from there for further processing.
As I mentioned earlier, the bulk of the functionality was already written in the windows application to perform the CRM tasks.
Therefore, in-order to utilise the existing code, it was transferred into WEBAPI controllers which could then be called from the front-end using ReactJS.
The other additional bit was to integrate SignlR so that the WEBAPI could send notifications back to the client on its progress.
So there you have it – a windows application converted to a version that works in the cloud.
That’s all for now, thanks!