Welcome to MSDN Blogs Sign in | Join | Help

Using the BDS Snap-in in a distributed environment

 

As mentioned in the release notes of Business Data Search (BDS) Snap-in - Phase 2 pre-release 4, the snap-in was tested on a single box configuration where-in all the pre-requisites and all the back-office application servers that need to be searched like Microsoft Dynamics CRM 3.0, Microsoft Dynamics AX 4.0 and Microsoft Office SharePoint Services 2007 were installed on the same machine where the BDS server was installed.  

 

When we tested in a distributed environment (i.e. an environment where Microsoft CRM 3.0, Microsoft Dynamics AX 4.0 and Microsoft Office SharePoint Services 2007 were on different machines) under Windows integrated authentication mode, it was found that the snap-in did not work as expected due to a security limitation popularly known as the “double hop issue”. In this issue, the user’s credentials are  passed from the client system to the server that is running IIS but they cannot be forwarded by the server to another machine. In case of the BDS snap-in, when a user launches the snap-in from Outlook, the user credentials are  passed to the BDS asp.net application residing on the SharePoint server, and these need to be passed to the other services (in this case Microsoft Dynamics CRM 3.0, Microsoft Dynamics AX 4.0 and Microsoft Office SharePoint Services 2007), Which did not happen. This worked perfectly fine when these services were being accessed from the same machine as the double hop issue was not faced in this environment.

 

Solution

To make the environment distributed i.e. to install the BDS snap-in and SharePoint services on a machine different from the ones hosting Microsoft Dynamics CRM 3.0 or Microsoft Dynamics AX 4.0 servers in a secure fashion, you need to use secure http configuration. The following needs to be configured on the machine where BDS is being setup:

 

     I.    Ensure Microsoft IIS 6.0 is installed as this is not default with Windows 2003 installation. Instructions on how to do this can be found at the following link:

http://technet2.microsoft.com/WindowsServer/f/?en/Library/42b0d059-dd84-4aa8-be26-dbeaa2d971ac1033.mspx

 

   II.    Install and configure Certificate Authentication (CA) service on Windows Server 2003: This provides extended security by offering Digital Certificates. Instructions on how to do this can be found at the following link:

http://www.microsoft.com/technet/security/prodtech/windowsserver2003/build_ent_root_ca.mspx#EACAC

 

Note: Once CA service has been activated, ensure that the users of this application enroll for a Digital Certificate.

 

          III.    Request a new Server certificate from an online CA. Instructions on how to do this can be found at: http://technet2.microsoft.com/WindowsServer/en/library/87e27bae-a060-4bf9-a4ff-98fbf227cea71033.mspx?mfr=true

          IV.    Install and Configure the obtained SSL certificate on Microsoft IIS 6.0.  The link given below may be referred for this:

http://msdn.microsoft.com/library/en-us/dnmaploc/html/MLSSecur.asp?frame=true#mlssecur_topic3

 

Finally, there are a few minor steps that need to be followed on the user’s local machine for the solution to work:

  1. After entering the URL of the BDS website in the Home page tab within the Business Data Lookup folder properties in Outlook, make sure you click at least once on the Browse button.
  2. In case the user has IE 7.0 browser, then SSL 2.0 should be enabled in the Security section under the Advanced tab in Internet Options.

 The steps mentioned above should help you run the BDS snap-in in a real scenario where the back-office application server (Microsoft Dynamics CRM 3.0/Microsoft Dynamics AX 4.0/ Microsoft Dynamics SharePoint 2007 Server) is running on a machine different from the one hosting the BDS Server. In case you have any further doubts or queries, please do post them on the message board on our Sandbox.

 

 

Code Samples for basic operations performed by Snap-ins for Microsoft Dynamics Ax

This post provides a few C# code snippets to demonstrate the programming methodology used within Snap-ins for Microsoft Dynamics Ax in performing the following basic functions:

 

·        Login to Microsoft Dynamics Ax

·        Retrieve table data from Microsoft Dynamics Ax

·        Create data records in Microsoft Dynamics Ax:

·        Update data in Microsoft Dynamics Ax

·        Delete data in Microsoft Dynamics Ax

 

Note: All the functions described below need AxaptaComConnector 1.2 Library as their reference and the following statements should be included in the beginning of the code:

using AxaptaCOMConnector;

using Microsoft.Win32;

 

Login to Microsoft Dynamics Ax:

 

There are two ways of Login supported by the Microsoft Dynamics Ax COM Connector:

 

1. Using the Logon2 method of Axapta2Class

 

This method mainly expects a username, password, language, Server Manager, Object Server and Configuration details pertaining to the Microsoft Dynamics Ax Server among other things. These can be obtained from the HKEY_CurrentUser registry key that stores the required information when Microsoft Dynamics Ax is installed. Given below is a sample code for a class called CAxConnection containing a method Login that accepts a username and password and in turn makes a call to Logon2:

 

/// <summary>

       /// Provides a connection to Axapta System

       /// </summary>

       public class CAxConnection

       {

              private Axapta2 axConn = new Axapta2Class();;

 

              /// <summary>

              /// Login to the Axapta system using user name and password

              /// </summary>

              /// <param name="userName"></param>

              /// <param name="Password"></param>

              public void Login(string userName, string passwd)

              {

                     object company = null;

                     object lang = null;

                     object servManager = null;

                     object objServ = null;

                     object config = null;

RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Navision\\Axapta\\3.0");

                     if(key != null)

                     {

                           config = key.GetValue("Current");

                           RegistryKey configKey = key.OpenSubKey(

                                   config.ToString());                         

                           if(configKey != null)

                           {

                                  company = configKey.GetValue("company");

                                  lang = configKey.GetValue("language");

                                  objServ = configKey.GetValue("servermask");

                                  servManager = configKey.GetValue("internet");

                            }

                           axConn.Logon2((object)userName, (object)passwd,

                                          company, lang, servManager, objServ,

                                          config,     (object)false,

(object)" ", (object)" ");

                     }

              }

       }

 

2. Using the Logon method of  Axapta2Class

 

The other way is to login to Ax using the Windows username of the current user. For this, the user should follow the steps given below:

 

           a) In the Ax Client go to the Administration module.

           b) Go into the Users section and select any user.

                 c) Go to the General tab.

                 d)  Fill the ‘Network Account Name’ field with the current user’s Windows Username.

 

Now passing empty strings to the Logon method, makes it use the Windows Login information of the current user to automatically detect the Ax User ID, password and other default values from the Ax Configuration and use them for login, as shown below:

 

//Login to Ax

public void Login()

{

axConn.Logon("", "", "", "");           

}

 

Similarly, To Logoff the user can make a call to the Logoff method:

 

//Logoff from Ax

public void Logoff()

{

       axConn.Logoff();

}

 

Retrieve table data from Microsoft Dynamics Ax

 

Given below is the code for a Retrieve function that demonstrates how to execute an SQL query and retrieve data from a table in Microsoft Dynamics Ax using the methods provided by the Microsoft Dynamics Ax COM Connector:

 

private void Retrieve(string tableName, string fieldName)

{

        IAxaptaRecord retrieveRecordSet;

        retrieveRecordSet = axConn.CreateRecord(tableName);

                       

        string query = "select " + fieldName + " from %1";

        //query can be constructed with more fields seperated by commas

        //and filter conditions can also be added with the use of WHERE clause.

           

        retrieveRecordSet.ExecuteStmt(query);

 

        //retrieveRecord now contains values of the field from all the rows

        //To fetch each one of them loop through the retrieveRecord.

 

        while (retrieveRecordSet.Found)

        {

string retrievedValue = retrieveRecordSet.get_field(fieldName).ToString();

               

               //Make use of the value obtained in retrievedValue and go to the next row(record).

              

               retrieveRecordSet.Next();

        }           

}

 

Create a new data record in Microsoft Dynamics Ax

 

Given below is a Create function which creates (or inserts) a new record in a given table in Microsoft Dynamics Ax. It accepts a field name and a field value along with the table name. It then uses the DoInsert method to insert a new record in the table with the field’s value set to fieldValue:

 

private void Create(string fieldName, string fieldValue, string tableName)

{

        IAxaptaRecord createRecord;

        createRecord = axConn.CreateRecord(tableName);

       

        //Initialize the table for insertion

        createRecord.Call("initValue",null,null,null,null,null,null);

           

        //set the value to the field and insert the record.

        axConn.TTSBegin();

        createRecord.set_field(fieldName, fieldValue);

        createRecord.DoInsert();

        axConn.TTSCommit();

}

 

Update data in Microsoft Dynamics Ax

 

The Update function given below takes a field name, its old value, a new value and a table name and updates all records in the specified table that have oldValue in the field given by fieldName replacing it with newValue. It uses the DoUpdate method to do this:

 

private void Update(string fieldName, string oldValue, string newValue, string tableName)

{

       IAxaptaRecord updateRecord;

 

       //Note the 'FORUPDATE' clause.

       string query = "select FORUPDATE " + fieldName + "from %1 where %1." + fieldName +

                           " == '" + oldValue + "'";

 

       updateRecord = axConn.CreateRecord(tableName);

       updateRecord.ExecuteStmt(query);

 

       while (updateRecord.Found)

       {

           updateRecord.set_field(fieldName, newValue);

           updateRecord.Next();

       }

 

       axConn.TTSBegin();

       updateRecord.DoUpdate();

       axConn.TTSCommit();

}

 

Delete data in Microsoft Dynamics Ax

 

The Delete function given below uses the DoDelete method to delete all records which have delValue in the field specified by fieldname:

 

private void Delete(string fieldName, string delValue, string tableName)

{

       IAxaptaRecord delRecord;

 

       //Note the 'FORUPDATE' clause.

       string query = "select FORUPDATE * " + "from %1 where %1." + fieldName +

                           " == '" + delValue + "'";

 

       delRecord = axConn.CreateRecord(tableName);

       delRecord.ExecuteStmt(query);

 

       if(delRecord.Found)

       {

       axConn.TTSBegin();

       delRecord.DoDelete();

       axConn.TTSCommit();

       }

}

 

 

Configuring Business Data Lookup Snap-in for Microsoft Dynamics AX 3.0

The entities, fields and relationships shown in Business Data Lookup Snap-in are driven off a configuration file. A default configuration file is installed during setup but you can create your own and point setup to use that configuration file.

 

The configuration file defines the metadata for Snap-in. In particular, it defines the

  • Dynamics AX entities to search on that are listed in ‘Look In’ drop down
  • List of related entities to show for the selected record in ‘Look For’ text box thus describing the browse order
  • Field Groups to show in record details for the selected record
  • Default fields to show for related record details - these are also the ones that are inserted by default when a user clicks the 'Insert Record' button for related entities.

Since the configuration file can be private for each user or shared across multiple users, by changing the configuration file, an administrator can make the Business Data Lookup behave differently for different users. Specifically, he can create configurations such that:

  • Everyone sees the same entities (of course within their security privileges), relationships and same default fields
  • Employees belonging to each department or set of users see same entities, relationships and default fields but those belonging to a different department  would see a different set. For example, the entities that a Sales person is interested in would be different from the ones an Operations person likes to view and hence the administrator can create different config files for Sales department employees and Operations department employees
  • Personalized configuration for each user, so each user has his private copy of the config file and sees a different view of the Dynamics AX 3.0 entities and a different browse order.

 

Of course, if you make the configurations too narrow (one for each user,) maintaining it can become a challenge.  But customizing it for each department or a set of users based on their work profies can help improve their experience.

 

To elaborate further, the default configuration file shared with the application enables showing only a few entities, whereas the one shared by vsinha03 here shows many more entities and relationships like Project, Business Relations, etc. As another example, listed below is XML text for a very basic configuration that allows a user to only look up customer details and sales order details for those customers. Copy and paste below text into the config file (take a backup of your current config file if you don’t want to lose any changes you might have made) for Business Data Lookup Snap-in for Dynamics AX to try it out -

 

<?xml version="1.0" encoding="utf-8"?>

<Configuration>

  <SystemConfiguration>

  </SystemConfiguration >

  <EntityConfiguration>

 

    <Entity Name = "Customer" Table = "CustTable" TableId = "77" MainEntity ="Yes">

      <Groups>

        <Group DisplayName ="General" AxName="AutoReport">  </Group>

        <Group DisplayName ="Description" AxName="Description"> </Group>

        <Group DisplayName ="Invoice" AxName="Invoice"></Group>

        <Group DisplayName ="Address" AxName="AddressDisplay"></Group>

      </Groups>

      <QuickSearch>

        <Attribute Name ="AccountNum"/>

        <Attribute Name ="Name"/>

      </QuickSearch>

      <RelatedView>

        <Attribute Name ="AccountNum"/>

        <Attribute Name ="Name"/>

        <Attribute Name="Address"/>

        <Attribute Name ="CustGroup"/>

        <Attribute Name="Currency"/>

      </RelatedView>

      <ParentTo>

           

        <ChildEntity Name = "SalesOrder">

          <RelationInfo ParentAttrName ="Accountnum" ChildAttrName ="CustAccount"/>

        </ChildEntity>

       

      </ParentTo>

 

      <ChildrenOf>

      </ChildrenOf>

    </Entity>

 

    <Entity Name = "SalesOrder" Table ="SalesTable" TableId = "366">

      <Groups>

        <Group DisplayName ="General" AxName="AutoReport"></Group>

        <Group DisplayName ="DeliveryAddress" AxName="DeliveryAddress"></Group>

        <Group DisplayName ="Delivery" AxName="Delivery"></Group>

        <Group DisplayName ="AddressDisplay" AxName="AddressDisplay"></Group>

      </Groups>

      <QuickSearch>

        <Attribute Name ="SalesId"/>

      </QuickSearch>

      <RelatedView>

        <Attribute Name ="SalesId"/>

        <Attribute Name="SalesName"/>

        <Attribute Name ="SalesStatus"/>

        <Attribute Name="DeliveryDate"/>

        <Attribute Name="DeliveryAddress"/>

      </RelatedView>

      <ParentTo>

        <ChildEntity Name ="Sales Order Items">

          <RelationInfo ParentAttrName ="SalesId" ChildAttrName ="SalesId"/>

        </ChildEntity>

      </ParentTo>

    </Entity>

 

   

 

    <Entity Name ="Sales Order Items" Table ="SalesLine" TableId = "359">

      <Groups>

        <Group DisplayName ="General" AxName="AutoReport"> </Group>

        <Group DisplayName ="Inventory" AxName="Inventory"> </Group>

        <Group DisplayName ="SalesQuantity" AxName="SalesQuantity"></Group>

        <Group DisplayName ="OrderLines" AxName="OrderLines"> </Group>

      </Groups>

      <QuickSearch>

        <Attribute Name ="SalesId"/>

        <Attribute Name="ItemId"/>

      </QuickSearch>

      <RelatedView>

        <Attribute Name ="ItemId"/>

        <Attribute Name ="Name"/>

        <Attribute Name="SalesQty"/>

        <Attribute Name="SalesDeliverNow"/>

      </RelatedView>

      <ParentTo>

      </ParentTo>

    </Entity>

  

   </EntityConfiguration>

</Configuration>

 

 

Welcome to Dynamics Snap blog

Welcome to the blog by Dynamics Snap team. We will use this blog to help our partners and customers realize more out of the Dynamics Snap initiative by posting content around feature highlights and useful scenarios for Snap-ins, code snippets, ideas on extending the Snap-ins and much more.

Let us know if there are more topics of interest you would like covered in the posts on this blog.

 
Page view tracker