Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Wednesday, May 6, 2015

Microsoft Dynamics AX 2012 – Calling SOAP Web Services from JavaScript

Microsoft Dynamics AX 2012 – Calling SOAP Web Services from JavaScript
 
Purpose: The purpose of this document is to illustrate how to call Microsoft Dynamics AX 2012 SOAP Web Services from Windows 8 application using JavaScript.
 
Challenge: Application Integration Framework (AIF) supports Web services for Windows Communication Foundation (WCF). In AIF, each document is represented by a service that can be exposed from an integration port. To consume services over the Internet, you must host services on Internet Information Services (IIS). AIF uses standard WCF processing to receive and process SOAP requests. Please find more info on AIF and Services here: https://technet.microsoft.com/en-us/library/gg731810.aspx. For the purposes of POC or app development you may need to consume Microsoft Dynamics AX 2012 SOAP Web Services from Windows 8 application using JavaScript
 
Solution: In this walkthrough I'm going to deploy an instance of Microsoft Dynamics AX 2012 R3 in the Cloud on Windows Azure using Microsoft Dynamics AX Lifecycle Management Services (LCS), write my own Custom WCF Web Service exposing business data and call this SOAP-based Web Service from Windows 8 application using JavaScript WinJS.xhr (XML Http Request) object. Please find more info about asynchronous programming, WinJS promises and xhr (XML Http Request) object here: https://msdn.microsoft.com/en-us/library/windows/apps/br229787.aspx
 
Walkthrough
 
First of all I'll deploy an instance of Microsoft Dynamics AX 2012 R3 using LCS. Please visit http://lcs.dynamics.com to access LCS Cloud service
After successful deployment I'll be able to access my Demo VM on Azure portal
What I'll need to do for my walkthrough is to enable HTTP/HTTPS endpoints for my Demo VM so I can reach out to my Web Service over internet
 
Endpoints
 
 
Please note that enabling HTTP/HTTPS endpoints for Demo VM is suitable for the purposes of POC, but it is not secure and not suitable for production applications accessing Microsoft Dynamics AX 2012. In order to build production application securely accessing Microsoft Dynamics AX 2012 please utilize Windows Azure Service Bus. Please find detailed guidance on how to leverage Windows Azure Service Bus to establish secure cross-domain connection to Microsoft Dynamics AX 2012 here: http://www.microsoft.com/en-us/download/details.aspx?id=38413
 
Continuing in this walkthrough I'll focus on mechanics of what's going on with Web Service request behind the scenes. But before we get there I'll do some necessary plumbing  
 
My plan is to expose custom business data based on newly created table. Please see the structure of my project below
 
Code
 
 
By using my simple WCF Custom Services Class Wizard (http://ax2012aifintegration.blogspot.com/2014/11/microsoft-dynamics-ax-2012-custom-web.html) I quickly created Data contract and Service contract classes to expose necessary business data
 
Data Contract
 
[DataContractAttribute]
public class AlexTableContract
{
    AlexName    Name;
    AlexID      ID;
}
[DataMemberAttribute]
public AlexID ID(AlexID _ID = ID)
{
         ID = _ID;
         return ID;
}
[DataMemberAttribute]
public AlexName Name(AlexName _Name = Name)
{
         Name = _Name;
         return Name;
}
 
Service Contract
 
public class AlexServiceContract
{
}
[AifCollectionTypeAttribute('return', Types::Class, classStr(AlexTableContract)), SysEntryPointAttribute(true)]
public List getList()
{
    AlexTable           alexTable;
 
    AlexTableContract   alexTableContract;
 
    List                list;
 
    list = new List(Types::Class);
 
    while select alexTable
    {
        alexTableContract = new AlexTableContract();
 
        alexTableContract.ID(alexTable.ID);
        alexTableContract.Name(alexTable.Name);
 
        list.addEnd(alexTableContract);
    }
 
    return list;
}
 
Then I will wrap up my classes with Microsoft Dynamics AX Service (AlexService) and execute right click > Add-ins > Register service command for AlexService

At this point I'll populate my table with a few records using Table Browser

Table browser
 
 
Next I'll create Inbound port for newly created Web Service using HTTP adapter
 
Inbound port
 
 
Then I will add AlexService.getList operation to the Web Service
 
Select service operations
 
 
As the next step I'll write a simple Windows Console client application to better understand how my Web Service request looks like behind the scenes when I call my Web Service. As I create new Windows Console application I will need to add Web Service Reference as shown below 
 
Add Service Reference
 
 
The code for the client looks like below
 
Code
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConsoleApplication1.ServiceReference1;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
 
            AlexServiceClient client = new AlexServiceClient();
 
            CallContext context = new CallContext();
            context.Company = "usmf";
 
            client.ClientCredentials.Windows.ClientCredential.UserName = "Admin";
            client.ClientCredentials.Windows.ClientCredential.Password = "pass@word1";
 
            AlexTableContract[] list = client.getList(context);
 
            foreach (AlexTableContract item in list)
            {
                Console.WriteLine(item.ID + ": " + item.Name);
            }
 
            Console.ReadLine();
        }
    }
}
 
As the result I'll output the list of values from my table
 
Result
 
 
Now the most interesting part. Before I ran my client program to fetch the data from Microsoft Dynamics AX 2012, I launches Fiddler to listen to HTTP/HTTPS traffic and see HTTP/HTTPS requests and responses taking place. You can download Fiddler from here: http://www.telerik.com/download/fiddler
 
Fiddler
 
 
In Fiddler I can clearly see how HTTP/HTTPS request and response looked like when I execute my client application and called Microsoft Dynamics AX 2012 Web Service
 
Request
 
 
Content-Type: text/xml; charset=utf-8
VsDebuggerCausalityData: uIDPo9P2U4sA1ENFu3GK474gpEsAAAAA7d1xyqrazUe5zAsDszpG8Js/kfbqE3NPrANxMKaGnFUACQAA
Accept-Encoding: gzip, deflate
Authorization: Negotiate TlRMTVNTUAADAAAAGAAYAHQAAABWAVYBjAAAAAAAAABYAAAACgAKAFgAAAASABIAYgAAABAAEADiAQAAFYKY4gYDgCUAAAAP4smxKQqDAj833urXTwSs6kEAZABtAGkAbgBBAFgAMgAwADEAMgBSADIAQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK1LD71uLVVMkxHvfFgRwwAQEAAAAAAABOi3kxVIjQAcS5+RmOrRhQAAAAAAIADgBDAE8ATgBUAE8AUwBPAAEAEgBBAFgAMgAwADEAMgBSADIAQQAEABYAYwBvAG4AdABvAHMAbwAuAGMAbwBtAAMAKgBBAFgAMgAwADEAMgBSADIAQQAuAGMAbwBuAHQAbwBzAG8ALgBjAG8AbQAFABYAYwBvAG4AdABvAHMAbwAuAGMAbwBtAAcACABOi3kxVIjQAQYABAACAAAACAAwADAAAAAAAAAAAQAAAAAgAADeJ7ljj7kKuEdzr8/a6bURMeu7wAp6EgJ5THCXwCzf3QoAEAAAAAAAAAAAAAAAAAAAAAAACQA0AEgAVABUAFAALwBhAHgAMgAwADEAMgByADIAYQAuAGMAbwBuAHQAbwBzAG8ALgBjAG8AbQAAAAAAAAAAAAAAAACX0gZZ9yPRi0zt4hbarMLO
Host: ax2012r2a.contoso.com
Content-Length: 595
Expect: 100-continue
 
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><h:CallContext xmlns:h="http://schemas.microsoft.com/dynamics/2010/01/datacontracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><h:Company>usmf</h:Company><h:Language i:nil="true"/><h:LogonAsUser i:nil="true"/><h:MessageId i:nil="true"/><h:PartitionKey i:nil="true"/><h:PropertyBag i:nil="true" xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/></h:CallContext></s:Header><s:Body><AlexServiceGetListRequest xmlns="http://schemas.microsoft.com/dynamics/2008/01/services"/></s:Body></s:Envelope>
 
 
Please note that POST method was used to call Web Service. Also appropriate envelope was added to the request
 
The response is returned in form of structured XML also wrapped with envelope

Response
 
 
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><AlexServiceGetListResponse xmlns="http://schemas.microsoft.com/dynamics/2008/01/services"><response xmlns:b="http://schemas.datacontract.org/2004/07/Dynamics.Ax.Application" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><b:AlexTableContract><b:ID>1</b:ID><b:Name>Alex</b:Name> </b:AlexTableContract><b:AlexTableContract><b:ID>2</b:ID><b:Name>Test><b:Name> </b:AlexTableContract></response></AlexServiceGetListResponse></s:Body></s:Envelope>
 
At this point I have enough knowledge to call my Web Service from Windows 8 application using JavaScript WinJS.xhr object. WinJS is a Windows library for JavaScript which implements Windows look and feel for your apps as well as a lot of useful objects such as xhr (XML HTTP request). Please find more info about WinJS here: https://dev.windows.com/en-us/develop/winjs
 
In order to create my Windows 8 app I'll use JavaScript Hub App template as shown below
 
Hub App (Windows)
 
 
For my app I'll implement a simple HTML page List.html to display the list of records from Microsoft Dynamics AX 2012 after calling Web Service. Here's how related List.js file looks like which implements business logic calling Web Service using WinJS.xhr object 
 
List.js
 
(function () {
    "use strict";
 
    WinJS.UI.Pages.define("/pages/list/list.html", {
        // This function is called whenever a user navigates to this page. It
        // populates the page elements with the app's data.
        ready: function (element, options) {
        }
    });
 
    function doClickSync() {
 
        var data = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><h:CallContext xmlns:h="http://schemas.microsoft.com/dynamics/2010/01/datacontracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><h:Company>usmf</h:Company><h:Language i:nil="true"/><h:LogonAsUser i:nil="true"/><h:MessageId i:nil="true"/><h:PartitionKey i:nil="true"/><h:PropertyBag i:nil="true" xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/></h:CallContext></s:Header><s:Body><AlexServiceGetListRequest xmlns="http://schemas.microsoft.com/dynamics/2008/01/services"/></s:Body></s:Envelope>';
        var options = {
            url: "http://ax2012r3-demo.cloudapp.net/MicrosoftDynamicsAXAif60/AlexWebServices/xppservice.svc",
            type: "post",
            headers: {
                "Content-Type": "text/xml; charset=utf-8",
                "SOAPAction": "http://schemas.microsoft.com/dynamics/2008/01/services/AlexService/getList"
            },
            user: 'Admin',
            password: 'pass@word1',
            data: data
        };
 
        WinJS.xhr(options)
            .done(
            function (request) {
                var dataItems = [];
                var xmlResponse = request.responseXML.documentElement;
 
                var fullNodeList = xmlResponse.getElementsByTagName("b:AlexTableContract");
 
                for (var i = 0; i < fullNodeList.length; i++) {
                    var dataItem = { id: fullNodeList[i].childNodes[0].textContent, name: fullNodeList[i].childNodes[1].textContent };
                    dataItems.push(dataItem);
                }
 
                var dataList = new WinJS.Binding.List(dataItems);
                var alexView = document.getElementById('alexList').winControl;
                alexView.itemDataSource = dataList.dataSource;
            },
            function (error) {
            },
            function (progress) {
            });
    }
 
})();
 
Please note that I included envelope and passed it as data into WinJS.xhr. Also I used post method to call Web Service, explicitly defined SOAP Action, provided authentication details as a part of request (please take into account security concerns when developing your apps, for the purposes of POC and simplicity I just hard-coded authentication details into the request). Finally when I receive asynchronous response I'll need to parse it out using XML DOM model and re-assign the data source for List element in HTML
 
As the result I successfully display the list of records from Microsoft Dynamics AX 2012 in my app
 
Result
 
 
Similarly you can implement not only data retrieval scenarios but also data manipulation scenarios calling Microsoft Dynamics AX 2012 Web Services. For example, creation of Sales order or creation/posting of General journal or Inventory journal
 
Summary: In this walkthrough I illustrated how to call Microsoft Dynamics AX 2012 SOAP Web Services from Windows 8 application using JavaScript and shed some light into what's happening behind the scenes when you call Web Service, how request and response look like and what you have to do to successfully call Microsoft Dynamics AX 2012 SOAP-based Web Services.
 
Tags: Microsoft Dynamics AX 2012, Custom Web Services, Data Contract, Service Contract, X++, Windows 8 App, JavaScript, WinJS, XHR, XML HTTP Request/Response, Fiddler.
 
Note: This document is intended for information purposes only, presented as it is with no warranties from the author. This document may be updated with more content to better outline the issues and describe the solutions.
 
Author: Alex Anikiev, PhD, MCP

Thursday, March 20, 2014

Rapid Business Apps Development Series – Part 3 (Project Siena)

Rapid Business Apps Development Series – Part 3 (Project Siena)
 
Purpose: The purpose of this series is to illustrate how to rapidly build business applications integrated with Microsoft Dynamics AX 2012. In this document we'll focus primarily on User Interface, other documents in this series will cover Web Services and Communication Infrastructure, and more.
 
Challenge: Small and large companies in the world have employees who use IT systems on a daily basis. These people are Users, Power Users, Business Analysts, etc. Often times they don't have development skills or know a little about it. Would it be great if *I*, for example, as a Business Analyst who understands business inside-out were able to quickly build Windows 8 Apps for business? Probably I would demand this experience to be as simple as just to use Microsoft Excel, for example. I this walkthrough we will consider one of Manufacturing industry workloads for Production Manager who wants to review the list of Production orders to be aware of what's going on while he/she is on the go (away from the desk) inside or outside of facility and potentially take some actions.    
 
Solution: Microsoft has a variety of Windows 8 Apps integrated with Microsoft Dynamics AX 2012 available in the Store, as well as published a detailed guidance on how to develop secure mobile apps integrated with Microsoft Dynamics AX 2012. In this document I'll look at things from customer perspective who may have people with in depth understanding of the business, but maybe without any development skills. In this walkthrough I'll try to be one of those Business Analysts who wants to develop a concept modern Windows 8 App for Production Manager described above within 10 mins or so. All I need in this particular case is a PC running Windows 8.1 and Project Siena App installed on it. Microsoft Project Siena (code name) is a new technology for business experts and other app imagineers. Now, without any programming, you can create apps that harness the power of corporate data and content, and web services.
 
Please note that in this document I assume that the reader may not have any development skills, but certainly has a desire to quickly build modern Windows 8 App for business.
 
Please find more info about Project Siena here: http://www.microsoft.com/en-us/projectsiena/default.aspx
 
Walkthrough
 
Let's begin!
 
In the previous walkthrough (Part 1) we have defined a business scenario for Production Manager App.
 
Now since we know what we want to build, we can discuss what we will be using to do that
All I'll be given is Windows 8.1 PC. And in order to start building my App I'll need to install Project Siena App from Windows Store. Please find more info about Project Siena App here: http://apps.microsoft.com/windows/en-us/app/microsoft-project-siena/5ae47651-e8f3-4e41-aab7-e19ab1b80180
 
In Project Siena I as Business Analyst will be able to design screens for my App, define the data to work with and much more. My goal is still to do this within 10 minutes
 
Let's get to work now
 
First step will be to launch Project Siena App. The first thing you will see will be a blank Screen 1 inviting you to add your first visual element to the App.
 
Screen 1 – Add Visual
 
 
Project Siena provides a wide range of User Interface controls at your fingertips. You can find everything from a simple text label to camera and video player control.
 
Visuals
 
 
Project Siena also provides an extended list of Galleries in order to display and work with lists/groups of items
 
Galleries
 
 
As well as a long list of shapes as described below. Please note that among these shapes we also have "Back arrow" and "Next arrow" to facilitate the organization of navigation
 
Shapes
 
 
Before we get to the actual design of the App screen we'll first define our data set. For the sake of simplicity I'll be using Excel file with information about Production orders as described below. In next walkthroughs we'll cover aspects of how to import and export data to/from Microsoft Dynamics AX 2012 in more details.
 
Data
 
 
Please note that I created Excel table which is currently required so Project Siena Importer can import the data into the App
 
Once Excel file is ready to go we can now Import data into the App using Excel Data Source
 
Data Sources
 
 
Once the data gets imported you can also review it in Project Siena
 
Excel tables (Importer)
 
 
Now it's time to design screens for our App.
 
It is very easy to build the App in Project Siena using its very intuitive drag-n-drop User Interface. So after a few minutes of designing this is what I've got. As you can see I used number of Labels, Image for Hero graphics, Custom Gallery to represent the list of Production orders, and another image and rectangles to design how each list element will look like
 
Manufacturing Companion – Screen 1
 
 
It will also take me only few minutes to design Screen 2 with the details of selected Production order. In this case I used image in Overview section, 2 Labels as section headers and number of Labels with specifics about Production order
 
Manufacturing Companion – Screen 2
 
 
In order to implement navigation from Screen 1 to Screen 2 when particular Production order is selected all you need to do is to define OnSelect behavior (in this case I defined it on image object). You typically don't need to type much because Project Siena will try to suggest you appropriate selections depending on the situation (for example, from the drop-down list) 
 
Behavior
 
 
Another typical task would be to take into account a context – selected list element – in order to display appropriate Production order details. This is very easy to do as well by defining Label Text property based on elements of your data set
 
Dynamic data
 
 
There're couple of things left before our App will become operational. One of them is to provide a "Back button" in order to navigate from Production order Details screen back to Production orders List screen. In this case we'll use "Back button" from the list of Shapes. Similar to our previous example we'll override OnSelect behavior by specifying what Screen we have to navigate to
 
Navigation (Shapes > Back button)
 
 
Finally we'll use Excel-like aggregate function to display statistics about how many Production orders we currently have on the screen ("4 Current orders"). For this task we will override Text property of Label control using "CountRows" built-in function
 
Statistics 
 
 
As the result within 10 minutes we have our Production Manager App ready!
 
When you are ready to publish your App you can use File > Publish function which will create a Published Package to use for App installation. 
 
At the end of this walkthrough we'll also review an anatomy of Project Siena artifacts (more from Developer point of View)
 
Project Siena file contains all info about the structure of you App
 
Project Siena file (App1)
 
 
After you Publish your App the system will create a PublishedPackage folder which will have a subfolder with all necessary artifacts as well as InstallApp file used to install your App on a target machine
 
PublishedPackage folder
 
 
Here's how a typical contents of Artifacts folder looks like
 
SienaApp1 - Artifacts
 
 
If we come back to App1 Project Siena file it is an archive which contains a number of files
 
App1 - Archive 
 
 
For example, Properties.json file contains a general info about your App
 
Properties
 
 
Similarly InstallApp is another archive which contains a number of files
 
InstallApp
 
 
Now you can also compare Project Siena file structure with typical Visual Studio 2013 Windows 8 App file structure in order to see some similarities and differences
 
App1 – Visual Studio 2013 Windows 8 HTML5/JavaScript App (1)
 
 
App1 – Visual Studio 2013 Windows 8 HTML5/JavaScript App (2)
 
 
App1 – Visual Studio 2013 Windows 8 HTML5/JavaScript App (3)
 
 
Summary: This document describes how Business Analysts and other company Users can use Project Siena App to rapidly build modern Windows 8 App implementing a real-world scenarios. Microsoft Project Siena (code name) is the beta release of a new technology for business experts, business analysts, consultants and other app imagineers. It allows you to create powerful, interactive, device-first and cloud-connected apps in a matter of a few hours – as easily as editing a document. I encourage you to check out other examples of Apps you can build using Project Siena on Channel 9 here: http://channel9.msdn.com/Blogs/Microsoft-Project-Siena
 
Author: Alex Anikiev, PhD, MCP
 
Tags: Dynamics ERP, Apps, Windows 8.1, Project Siena, HTML5, CSS, JavaScript, User Interface, Manufacturing, Production Manager.
 
Note: This document is intended for information purposes only, presented as it is with no warranties from the author. This document may be updated with more content to better outline the concepts and describe the examples.