Using CRM from an external website – part 4: Demo “Web API”

Originally posted on 25 August 2015 by Bas van de Sande on JourneyIntoCRM.com

Welcome to the next episode in the “Using CRM from an external website” series. In my last article, I described the Web API scenario. The Web API scenario is the first step in the journey and depends on Microsoft Infrasctrucure ( I need a .Net/Mono framework and an Internet Information like server).

In this scenario I hook up a web page to a Web API controller. The model behind the controller is responsible for getting the data from the back end CRM. As the Web API controller and the model are running in a .NET context, we simply can use the Dynamics CRM object model to get and set the data from CRM.

I Use javascript on the web page to make the REST calls. For data retrieval (Select and SelectList) I use a GET method. For Data manipulation (Insert, Update, Delete) I use a POST method. The javascript conducting the calls to the Web API controller are the bridge between the client side context and the server side context.

Webapi

In this article I’ll show you the main concepts on passing data from the client side context to the server side context and vice versa. For the sake of simplicity the model class is not conducting any operation towards CRM.

MVC

The Web API scenario is based on the MVC principles. We work with a single controller or multiple controllers (to define the actions) and with a model or multiple models (containing the data).
Using MVC we need to specify where our controllers can be found. This has to be done in a RouteTable.  In the RouteTable you can specify how your URL’s should look like.

The RouteTable is specified in the global.asax file in the web project.

Webapiglobalasax

Model

The basis of the Web API scenario is the model. In the model we define how the data should look like. In my implementation I use the model in a fashion that I can pass the model outside the boundaries of the assembly and still keeping full control over the behaviour of the class. I specified public properties and internal methods.

The public properties can be get and set by anyone. The internal methods can only be called within the context of the assembly (read: controller).

The idea of using a model is to simplify the transport of data over the server side and client side context.

Webapimodel

Controller

The controller acts like a façade (gateway) between the client side and server side context. As you can see all functions are decorated with two attributes.

  • HttpPost / HttpGet
    This attribute defines in what context the function is called. By either a HttpGet or a HttpPost method.
  • ActionName
    This attribute defines the name of the function to the outside world. This way we can give meaningfull names to our get and post methods and we can have multiple get and post methods within the controller.

To simplify communication between the server side and client side context, we try to work as much as possible with simple data types (like string etc), instead of using complex objects. However, when you look at e.g. the Insert() function, you see that we pass in a string representing a model.
The model is deserialized and instantiated into our strong typed model class.

Once instantiated we can call the appropriate method on the model to conduct the action we desire. On the other hand we can return complex objects back to the client side context by simply using the object.  The javascript JSON call handles all serialization and deserialization for us. *nifty*

Webapicontroller

Javascript methods

On the web page we have basically two kinds of methods. Either a GET or a POST method.

Looking at the GET method, we simply specify the URL in the format defined in the RouteTable. We have to omit the word “Controller”, that is handled by MVC.

Our url looks like:

“api / [name of the model] / [method on the controller] / ?[parameter]”.

Please note that method names and parameters are case sensitive. Once the data is retrieved, we simply can use the properties defined in the model (case sensitive)

Webapi-get

Looking at the POST method, we have to a a bit more work.
First of all we have to fill a JSON object and stringify it (encode it for transport).
Then we pass it to our url in a parameter. Our url is enriched with a string representing our model. In the controller we deserialize the string and turn it into a .NET object.

Webapi-post

This is in a nutshell all technology you need to integrate your CRM environment in your website. As I mentioned before, this is only the first step. In this example I trust on the security mechanisms offered by the .NET framework and the Microsoft infrastructure. My ultimate goal is to be able to integrate my CRM environment with a non Microsoft environment.

Filed under: Other

How to automatically refresh your Dynamics 365 Dashboard in UCI

Procedure:

1. Create an html web resource and add the following script in it:

<html><head>
     <title></title>
     <script type="text/javascript">

         // add visual timer just because we can
         var d = new Date();
         document.write(d.toLocaleTimeString());

         // refresh parent (dashboard) every 30 seconds
         // (timeout is in milliseconds)
         setTimeout("window.parent.document.getElementById('RefreshDashboard').click();", 30 * 1000);
     </script>
   <meta><meta><meta><meta><meta></head>
   <body>
</body></html>

2. Add the html web resource to a dashboard.

3. Click on “Edit Component” and make sure the web resource’s “Visible By Default” property is unchecked.

Explanation:

On the dashboard, there is a button called “Refresh Dashboard”. The ID of this button is RefreshDashboard. The script above clicks this button every 30 seconds. You can change the button to put in another value for seconds.

Filed under: Other

Structured Content: Creating a template for Open Content

Open Content is a great tool giving inexperienced users a simple solution to maintaining small amounts of content.

Consider the scenario; you build a nice new website for a client who has no technical knowledge of websites. On launch day it is pixel perfect and the client is happy, hopefully. A couple of days later you get a call to say the website is broken. You go to the website and discover that the user has edited an HTML module, in source mode of course, and removed some mark-up; what a mess. All he wanted to do was add another line in a table.

How much easier would it be if all he had to do was click a + icon, enter the text he required into a nice form and click save? That is where Open Content helps and here I will show how to create such a template.

Requirement

Create a template to allow a website admin to build a tabbed element with a table on each tab. Each table will consist of rows containing columns for Description and Dates.

Template

Open Content does not, at this time, have a template to achieve this. However, it does have a template for tabs. We can use this template as the basis for a new template.

Start by placing an instance of Open Content on a page. It should look like:

Choose Create a new template, marked in yellow above.

Give your new template a name and click Save.

Schema

A schema is what drives Open Content. The schema defines your data structure. In this example, the schema contains a Module Title and an array of Tabs. Each Tab contains a table with an array of RowItems. Each RowItem consists of two columns, Description, and Dates.

Open Content uses JSON notation to define a schema. The schema for the example is shown below.

{ “type”: “object”, “properties”: { “ModuleTitle”: { “title”: “Module Title”, “type”: “string” }, “Tabs”: { “type”: “array”, “items”: { “title”: “Tab”, “type”: “object”, “properties”: { “tabName”: { “title”: “Tab Name”, “type”: “string” }, “RowItems”: { “type”: “array”, “items”: { “title”: “Row Item”, “type”: “object”, “properties”: { “description”: { “title”: “Description”, “type”: “string” }, “dates”: { “title”: “Dates”, “type”: “string” } } } } } } } } }


Quite often errors in Open Content are the result of incorrectly formed JSON. Usually a missing { or }. A useful site for checking a schema is http://jsonlint.com/

To edit a schema choose Edit Template Files from the module’s Actions menu.

Because a new template was created from an existing BootstrapTabs template the schema will need to be updated. Copy the schema above and paste it into the Schema text box. Click Save.

Building a Template

The next step is to build a template that will be used to display the data. Select Template from the dropdown. Once again the template shown will be for BootstrabTabs and will need to be updated to reflect the new schema.

The surrounding pair of {{#each Tabs}}  …  {{/each}} will loop through the data and for each Tab will insert a li with tabName from the schema.

Note: Because this template was created by copying an existing template there is an important change required. The original template BootstrapTabs had a Layout option of Tabs or Pills. This is used in the template to set a class of nav_tabs or nav-pills depending upon the setting. This can be seen on the ul tag as class=”nav nav-{{Settings.Layout}}s”. In the new template, only tabs will be used:

<div role="tabpanel">

    <!-- Nav tabs -->
    <ul class="nav nav-tabs" role="tablist">
        {{#each Tabs}}
      <li role="presentation" {{#if @first}}class="active"{{/if}} ><a href="#tab{{@index}}" aria-controls="tab{{@index}}" role="tab" data-toggle="tab">{{tabName}}</a></li>        
        {{/each}}
    </ul>

    <!-- Tab panes –>
    <div class="tab-content">

    </div>
</div>

Click Save & Close then click Edit Content to see the data entry form.

Enter a title for the module and then click the + icon to add tabs.

Enter a Tab name.

To add more tabs click the  icon just above the tab to the right. A UI of nested boxes shows the nesting of Row Items within Tabs.

Tabs and Row Items may be ordered using the and arrows.

Add Tab One, Tab Two and Tab Three and you should see

Next, add the HTML to the template for the table on each tab.

{{#each Tabs}} 
<div role="tabpanel" class="tab-pane {{#if @first}}active{{/if}}" id="tab{{@index}}">
    <div class="table-responsive">
        <table class="table">
	{{#each RowItems}}
            <tr>
		<td>{{Description}}</td>
		<td>{{Dates}}</td>
	    </tr>
	{{/each}}
	</table>
    </div>
</div>
{{/each}}

Once again {{#each Tabs}} is used to iterate through each tab in the array and within each tab {{RowItems}} is used to iterate through each row in the array of rows.

The result is a set of tabs with a table on each that makes life easy for site admins:

Further Reading:

http://alpacajs.org/

http://getbootstrap.com/components/#nav-tabs

http://handlebarsjs.com/

This article was written by Declan Ward on November 13, 2015 at 14:42. Since the original site is down, the intent of this article is to preserve content rather than copying it.

Filed under: DNN