Monday, April 6, 2015

Calling RESTful services using AX 2009, AX 2012


While integrating Dynamics AX with other systems, you might need to call REST services in Dynamics AX to Pull data in AX or Push data out of AX to other systems. REST services are the easiest and very useful way to provide the interface between 2 systems. The Job written below is the example of how one can call REST service from within AX.

Tip: Either you want to push data from AX or pull data in AX, you can always use POST method. In case you want to send data out of AX, you will always need to use POST method with your data as shown below in postData variable. In case, you need to download data in AX from some other system, you can still use POST method and send your credentials, API key for authentication purpose and download your data either in XML or JSON format as I have done in returnValue variable in job written below.

static void Job1(Args _args)
{
    str                             url;
    str                             postData;
    str                             returnValue;
    System.Net.HttpWebRequest       request;
    System.Net.HttpWebResponse      response;
    System.Byte[]                   byteArray;
    System.IO.Stream                dataStream;
    System.IO.StreamReader          streamReader;
    System.Net.ServicePoint         servicePoint;
    System.Net.ServicePointManager  servicePointManager;
    CLRObject                       clrObj;
    System.Text.Encoding            utf8;

    ;

    postData = strfmt('api_key=%1&account_id=%2', "DEC8A896-9244-4FAB-ACB9-15B932E630CB", "3");

    new InteropPermission(InteropKind::ClrInterop).assert();

    url = "http://yoururl.com/services/api/external/authentication.ashx?login";

    clrObj = System.Net.WebRequest::Create(url);
    System.Net.ServicePointManager::set_Expect100Continue(false);

    request = clrObj;
    request.set_Method("POST");
    utf8 = System.Text.Encoding::get_UTF8();
    byteArray = utf8.GetBytes(postData);
    request.set_ContentType("application/x-www-form-urlencoded");
    request.set_ContentLength(byteArray.get_Length());

    dataStream = request.GetRequestStream();
    dataStream.Write(byteArray, 0, byteArray.get_Length());
    dataStream.Close();

    try
    {
        response = request.GetResponse();
    }
    catch (Exception::CLRError)
    {
    postdata = "";
    }

    dataStream = response.GetResponseStream();
    streamReader = new System.IO.StreamReader(dataStream);
    returnValue = streamReader.ReadToEnd();

    info(returnvalue);

    streamReader.Close();
    dataStream.Close();
    response.Close();


}

Thursday, February 12, 2015

Easiest say to obtain SID - AX 2012 installation

We often need to obtain SID while installing or moving Dynamics AX across different environments. There are several ways to obtain SID which we need to set in the database table. However, the easiest way to obtain SID is to:

Open command prompt and type the following:

whoami /user

That's it.

Wednesday, December 31, 2014

Applying Current User Id range in an AOT query

If you want to apply a range to an AX 2012 AOT query, you can simply add a new range to the field and specify the integer or string value against them. However, if you want to apply a range on a User Id field and want to provide the value of Currently logged in user, you need to get the value dynamically and pass that value to the query. Below snap shot shows a very simple way to achieve this.


Tips on Extensible Data Security in AX 2012

Recently, I had chance to work on Extensible Data Security and noticed few things which can be very helpful, they are posted below.

  1. XDS can hurt performance sometimes if query is not designed well. In order to design security without hurting the performance, always try to reduce number of joins in your Security Policy Query.
  2. If your requirement is complex and needs to add some dynamic filters to the query. In that case you can create a temporary table with type TEMPDB and override its xds() method to fill the table dynamically. This method can be considered for performance improvements as it would reduce query joins. For this, please see xds method on the table MyLegalEntitiesForXDS
  3. If you have to disable XDS, consider following 2 methods
    1. Create a view and fetch data from that view. View is a different object for XDS framework, thus the security applied on the table will not be considered for view and you will see the data.
    2. Second method to disable the security is mentioned here in my other post.

AX 2012 Disable/ByPass extensible data security (XDS) through code

Extensible Data Security or XDS is a framework introduced in AX 2012 to apply security on data. We had RLS or Record Level Security in AX 2009. However, XDS is completely a new framework with more capabilities in order to apply data security. This post is about disabling or bypassing the XDS using code. For more details about XDS, download a whitepaper provided by Microsoft using following link.
http://www.microsoft.com/en-us/download/details.aspx?id=3110

Disabling/Bypassing XDS or Extensible Data Security:
Recently, I had a requirement to restrict users from viewing all the Warehouses available and they must be able to see only the Warehouses they belong to. I designed a new security policy and it started working very easily without much problem. However, the problem was on Inventory Transfer From where we have two fields for Warehouses:
  1. From warehouse and
  2. To warehouse
Our requirement was to restrict only From warehouse and To warehouse MUST show all the warehouses available so they can issue inventory to any warehouse but should not be allowed to issue inventory from the warehouse they don't belong to. In order to achieve this, I had to disable the XDS on To Warehouse lookup method. I did override the lookup() method on To Warehouse field on the datasource and below is the code which I wrote to disable the XDS.

public void lookup(FormControl _formControl, str _filterStr)
{
    XDSServices                      xXDS = new XDSServices();

    xXDS.setXDSState(0); // Disable XDS
    super(_formControl, _filterStr);
    xXDS.setXDSState(1); // Enable XDS
}

Wednesday, December 17, 2014

AX 2012 showing lookup from different (cross) company

I had a requirement in AX 2012 in which I had to show Customer Lookup from a different company. Our requirement was to provide user with two lookups on the Vendor Form (VendTable).

  1. One lookup - To select the company from which they want to see Customers
  2. Second lookup - Show Customers from the company selected on above lookup
To achieve this I added 2 fields in the table VendTable
  1. TargetCompanyId (EDT: SelectableDataAreaId)
  2. TargetCustAccount (EDT: CustVendAC) - Don't use CustAccount EDT, I tried this in AX2009 and it appeared to be using EDT relation and could not work.
After adding these fields, create a new relationship and add both of the above added fields in this relationship.

Drop the fields on the form and you will see Customer will appear from the company you have selected in the first lookup. Change company from the first lookup and see how data in the customer lookup changes.


Sunday, December 14, 2014

Calling Events of AX Form's Datasource

While working on AX 2012 Forms, we need to call form's datasource events every now and then from other events. Below is the example that shows how you can call any event like modified, validate etc. of a form's datasource from any other method.

Below example shows how you can call modified method of ItemId field under InventJournalTrans datasource.

FormDataObject          itemIdField;
itemIdField = inventjournalTrans_ds.object(fieldnum(InventJournalTrans, ItemId));
itemIdField.modified();