This framework shows how we can build a cross-patform unified solution that can be used with most of the Microsoft Dynamics products.
It is also a starting point in a contest endorsed by Microsoft Dynamics Academic Alliance Advisory Council for students from different countries for developing simple business processes as mobile extensions to Dynamics products.
There is no such a thing as an information system suitable for every conceivable process from a company.
Many of these processes need to take place in the field, thus mobile device based solutions could be a suitable approach solving the informational needs of the workers involved in these processes.
The Microsoft Dynamics solutions are very flexible, and allow development of extensions suitable to each processes that need to be integrated in the system.
Our approach shows how we can build a unified solution that can be used with most of the Dynamics products, without too many modifications on the client side.
For this reason we built a framework that can connect to each of the Dynamics products and allows a unified client interface to be used.
The purpose of this framework is mainly educational, and can be used in different courses related to information systems and mobile applications.
Another area where this framework would be useful is as starting point in a contest for developing cross-platform mobile extensions to the Dynamics products.
A middleware is used for hiding the differences between the different Dynamics platforms.
It implements a unified REST web API that can be consumed from the mobile clients.
At the moment the following three APIs are partially implemented:
Below are some details of how are these implemented.
interface IApiProvider
{
UserModel User { get; set; }
}
interface IAuthenticationProvider
{
bool Login(UserModel user);
}
class AXAuthenticationProvider : IAuthenticationProvider
{
public bool Login(UserModel user)
{
try
{
NetworkCredential credential = new NetworkCredential(user.name, user.password, user.domain);
AXLoginService.LoginClient loginClient = new AXLoginService.LoginClient();
loginClient.Endpoint.ListenUri = new Uri(Globals.AXLoginServices);
loginClient.Endpoint.Address = new System.ServiceModel.EndpointAddress(Globals.AXLoginServices);
loginClient.ClientCredentials.Windows.ClientCredential = credential;
AXLoginService.CallContext loginContext = new AXLoginService.CallContext();
loginContext.Company = "usmf";
var login = loginClient.find(loginContext, null);
ResponseModel response = new ResponseModel(login, "success");
return (response.error == null);
}
catch (Exception e)
{
Console.WriteLine("Error " + e.Message);
return false;
}
}
}
class NAVAuthenticationProvider : IAuthenticationProvider
{
public bool Login(UserModel user)
{
try
{
NetworkCredential credential = new NetworkCredential(user.name, user.password, user.domain);
Login_PortClient service = new Login_PortClient();
service.Endpoint.ListenUri = new Uri(Globals.NAVLoginService);
service.Endpoint.Address = new System.ServiceModel.EndpointAddress(Globals.NAVLoginService);
service.ClientCredentials.Windows.ClientCredential = credential;
var login = service.Read(user.name);
if (login == null)
{
return false;
}
}
catch (Exception e)
{
Console.WriteLine("Error " + e.Message);
return false;
}
return true;
}
}
interface ICustomerProvider : IApiProvider
{
object GetCustomerList();
object GetCustomer(string id);
bool CreateCustomer(JObject data);
bool DeleteCustomer(string id);
}
public class AxCustomerProvider : ICustomerProvider
{
private static AXCustomerListService.CustomerServiceClient customerListClient;
private static AXCustomerService.CustomerServiceClient customerClient;
public UserModel User { get; set; }
public AxCustomerProvider(UserModel user)
{
User = user;
NetworkCredential credential = new NetworkCredential(user.name, user.password, user.domain);
customerListClient = new AXCustomerListService.CustomerServiceClient();
customerListClient.Endpoint.ListenUri = new Uri(Globals.AXCustomerListServices);
customerListClient.Endpoint.Address = new System.ServiceModel.EndpointAddress(Globals.AXCustomerListServices);
customerListClient.ClientCredentials.Windows.ClientCredential = credential;
customerClient = new AXCustomerService.CustomerServiceClient();
customerClient.Endpoint.ListenUri = new Uri(Globals.AXCustomerServices);
customerClient.Endpoint.Address = new System.ServiceModel.EndpointAddress(Globals.AXCustomerServices);
customerClient.ClientCredentials.Windows.ClientCredential = credential;
}
public bool CreateCustomer(JObject data)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public bool DeleteCustomer(string id)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public object GetCustomer(string id)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public object GetCustomerList()
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
}
public class NavCustomerProvider : ICustomerProvider
{
private Customer_PortClient service;
public UserModel User { get; set; }
public NavCustomerProvider(UserModel user)
{
User = user;
NetworkCredential credential = new NetworkCredential(user.name, user.password, user.domain);
service = new Customer_PortClient();
service.Endpoint.ListenUri = new Uri(Globals.NAVCustomerService);
service.Endpoint.Address = new System.ServiceModel.EndpointAddress(Globals.NAVCustomerService);
service.ClientCredentials.Windows.ClientCredential = credential;
}
public bool CreateCustomer(JObject data)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public bool DeleteCustomer(string id)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public object GetCustomer(string id)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public object GetCustomerList()
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
}
interface ISalesOrderProvider : IApiProvider
{
object GetCustomerSalesOrderList(string customerId);
object GetCustomerSalesOrder(string customerId, string salesOrderId);
bool CreateCustomerSalesOrder(JObject data);
bool DeleteCustomerSalesOrder(string customerId);
}
class AxSalesOrderProvider : ISalesOrderProvider
{
private static AXSalesOrderListService.SalesOrderServiceClient salesOrderListClient;
private static AXSalesOrderService.SalesOrderServiceClient salesOrderClient;
public UserModel User { get; set; }
public AxSalesOrderProvider(UserModel user)
{
User = user;
NetworkCredential credential = new NetworkCredential(user.name, user.password, user.domain);
salesOrderListClient = new AXSalesOrderListService.SalesOrderServiceClient();
salesOrderListClient.Endpoint.ListenUri = new Uri(Globals.AXSalesOrderListServices);
salesOrderListClient.Endpoint.Address = new System.ServiceModel.EndpointAddress(Globals.AXSalesOrderListServices);
salesOrderListClient.ClientCredentials.Windows.ClientCredential = credential;
salesOrderClient = new AXSalesOrderService.SalesOrderServiceClient();
salesOrderClient.Endpoint.ListenUri = new Uri(Globals.AXSalesOrderServices);
salesOrderClient.Endpoint.Address = new System.ServiceModel.EndpointAddress(Globals.AXSalesOrderServices);
salesOrderClient.ClientCredentials.Windows.ClientCredential = credential;
}
public bool CreateCustomerSalesOrder(JObject data)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public bool DeleteCustomerSalesOrder(string customerId)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public object GetCustomerSalesOrder(string customerId, string salesOrderId)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public object GetCustomerSalesOrderList(string customerId)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
}
class NavSalesOrderProvider : ISalesOrderProvider
{
private SalesOrder_PortClient salesOrderListClient;
public UserModel User { get; set; }
public NavSalesOrderProvider(UserModel user)
{
User = user;
NetworkCredential credential = new NetworkCredential(user.name, user.password, user.domain);
salesOrderListClient = new SalesOrder_PortClient();
salesOrderListClient.Endpoint.ListenUri = new Uri(Globals.NAVSalesOrderService);
salesOrderListClient.Endpoint.Address = new System.ServiceModel.EndpointAddress(Globals.NAVSalesOrderService);
salesOrderListClient.ClientCredentials.Windows.ClientCredential = credential;
}
public bool CreateCustomerSalesOrder(JObject data)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public bool DeleteCustomerSalesOrder(string customerId)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public object GetCustomerSalesOrder(string customerId, string salesOrderId)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
public object GetCustomerSalesOrderList(string customerId)
{
// Please register to the UniDynApps Contests to be able to access the sample implementation
}
}
To be able to access the full source code and some guidelines, please register to the UniDynApps Contests
Feel free to get in touch if you have any questions or suggestions.