Microsoft Dynamics AX Support

This blog contains posts by the Microsoft Dynamics AX Support teams Worldwide

Updating customers via the Customer AIF service

Updating customers via the Customer AIF service

Rate This
  • Comments 7

We have received many questions in AX 2009 around how to update customers using the customer service in AIF.  People report errors like the following while trying to do updates:

"The record in Address with record id <12345789> cannot be updated because the record has changed since last read."

To update customers set the DocumentHash of the CustTable entity to itself, and the RecId and RecVersion fields of the AddressRelationship and AddressRelationshipMap to themselves so that AIF is aware of which record in each table you want to update.  In your code the update call should look something like the following:

CustomerServiceClient proxy = new CustomerServiceClient();

 

foreach (AxdEntity_CustTable custTable in this.customer.CustTable){

custTable.CellularPhone = "3456789999";

custTable._DocumentHash = custTable._DocumentHash;

custTable.AddressRelationship[0].RecId = custTable.AddressRelationship[0].RecId;

custTable.AddressRelationship[0].RecVersion = custTable.AddressRelationship[0].RecVersion;

custTable.AddressRelationship[0].AddressRelationshipMap[0].RecId = custTable.AddressRelationship[0].AddressRelationshipMap[0].RecId;

custTable.AddressRelationship[0].AddressRelationshipMap[0].RecVersion = custTable.AddressRelationship[0].AddressRelationshipMap[0].RecVersion;

custTable.AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].RecId = custTable.AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].RecId;

custTable.AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].RecVersion = custTable.AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].RecVersion;

custTable.AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].State =

"SD";

custTable.AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].City =

"Onida";

custTable.AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].County =

"SULLY";

custTable.AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].ZipCode =

"57564";

}

 

try{

this.createEntityKeyList(), customer);

proxy.update(

Console.WriteLine("The customer was successfully updated");

}

catch (Exception e) {

Console.WriteLine(e.InnerException.Message);

Console.WriteLine("The customer was not updated.");

}

For the file adapter the update portion of your xml file should look something like:

<Customer xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/Customer">
                <CustTable class="entity" action="update">
      <_DocumentHash>140885c43d75ec28cf99c8778b0414e3</_DocumentHash>
                    <AccountNum>1101</AccountNum>
                    <CustGroup>20</CustGroup>
                    <PartyType>Organization</PartyType>
   <AddressRelationship class ="entity" action="update">
    <PartyId>191</PartyId>
    <RecId>5637145108</RecId>
    <RecVersion>1</RecVersion>
    <AddressRelationshipMap class="entity" action="update"> 
     <RecId>5637145533</RecId>
     <RecVersion>1</RecVersion>
                          <CustAddress class="entity" action="update">
                               <RecId>5637151719</RecId>
                               <RecVersion>623863500</RecVersion>
          <ZipCode>58801</ZipCode>
                          </CustAddress>
    </AddressRelationshipMap>
   </AddressRelationship>
                </CustTable>
            </Customer>

Leave a Comment
  • Please add 7 and 1 and type the answer here:
  • Post
  • Hai Becky Newell

    this.createEntityKeyList(), customer);

    proxy.update(

    here it asking callcontext also how can we reslove

  • Hello,

    This post is specific to AX 2009.  For 2012 a CallContext object is required for every service call.  It is the first parameter passed to the read, find, update, etc method.  Have a look at some of the other posts on this site that use 2012 services for how to instantiate the CallContext object.

  • Hi Becky,

    I do not know if you have received my message last week so I will try to repost it.

    I have a program in c# that needs to update custTable. I have the same issue as the one you described above but your solution do not work on my side. I still receive the error. Can you take a look at my code and tell me what is wrong? I am using AX 2009 SP1 RU6 with visual studio 2010. In this example, I do not need to update the address but my program may have to update it eventually.

    CustomerServiceClient customerServiceLocal = new CustomerServiceClient();                              

    AxdCustomer recordWrapper =  FindCustomer(); //return the customer that we want to update

    AxdEntity_CustTable custTable = recordWrapper.CustTable[0];                                

    CustomerServiceUpdateRequest updateRequest = new CustomerServiceUpdateRequest();

    updateRequest.Customer = new AxdCustomer();

    updateRequest.Customer.CustTable = new AxdEntity_CustTable[1];

    updateRequest.Customer.CustTable[0] =  new AxdEntity_CustTable();

    updateRequest.EntityKeyList = new Customer.EntityKey[1];

    updateRequest.EntityKeyList[0] = new Customer.EntityKey();

    updateRequest.EntityKeyList[0].KeyData = new Customer.KeyField[1];

    updateRequest.EntityKeyList[0].KeyData[0] = new Customer.KeyField();

    updateRequest.EntityKeyList[0].KeyData[0].Field = "AccountNum";

    updateRequest.EntityKeyList[0].KeyData[0].Value = custTable.AccountNum;                

    updateRequest.Customer.CustTable[0].AddressRelationship = new AxdEntity_AddressRelationship[1];

    updateRequest.Customer.CustTable[0].AddressRelationship[0] = new AxdEntity_AddressRelationship();

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap = new AxdEntity_AddressRelationshipMap[1];

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0] = new AxdEntity_AddressRelationshipMap();

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress = new AxdEntity_CustAddress[1];

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0] = new AxdEntity_CustAddress();

    updateRequest.Customer.CustTable[0] = custTable;

    updateRequest.Customer.CustTable[0].CustGroup = "20";

    updateRequest.Customer.CustTable[0]._DocumentHash = updateRequest.Customer.CustTable[0]._DocumentHash;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].RecId = updateRequest.Customer.CustTable[0].AddressRelationship[0].RecId;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].RecVersion = updateRequest.Customer.CustTable[0].AddressRelationship[0].RecVersion;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].RecId = updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].RecId;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].RecVersion = updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].RecVersion;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].RecId = updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].RecId;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].RecVersion = updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].RecVersion;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].State = updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].State;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].City = updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].City;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].County = updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].County;

    updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].ZipCode = updateRequest.Customer.CustTable[0].AddressRelationship[0].AddressRelationshipMap[0].CustAddress[0].ZipCode;              

    customerServiceLocal.update(updateRequest.EntityKeyList, updateRequest.Customer);

    Thank you.

  • Hi Stephanie,

    What you are doing is slightly different from what I had.  You are instantiating a new customer object and then assigning to the new customer fields from the retrieved one (same for each of the sub-entities).  What I am doing in my code is directly updating the customer retrieved by the find operation.  I think that is the difference.

  • Hi Becky,

    Thank you for your fast reply.

    I have tied to use your example above but still not working. Can you send me your method this.createEntityKeyList() as I think that my error is on this side. I think that the call should be proxy.update(this.createEntityKeyList(), customer)?. I am curious to see what is in your createEntityList method.

    Thank you.

  • Here you go:

     private EntityKey[] createEntityKeyList()

           {

               EntityKey[] entityKeyList = new EntityKey[1];

               EntityKey entityKey = new EntityKey();

               KeyField[] keyDataList = new KeyField[1];

               KeyField keyField = new KeyField();

               keyField.Field = "AccountNum";

               keyField.Value = this.accountNum;

               keyDataList[0] = keyField;

               entityKey.KeyData = keyDataList;

               entityKeyList[0] = entityKey;

               return entityKeyList;

           }

    Enjoy!

  • Hi Stephanie,

    If you need additional help you should put a call into us at support.  We're getting outside the scope of a blog post.

Page 1 of 1 (7 items)