EP Vendor Relations Bug for System Administrators


Error message

Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in drupal_get_feeds() (line 394 of D:\home\site\wwwroot\webapp\includes\common.inc).

I was helping troubleshoot an issue with Enterprise Portal for a client recently where the Vendor Relations drop down chooser control was not showing up:

After some digging on the Enterprise Portal farm, I saw this error repeated several times in the Event Viewer logs:

The key here is the DLL Microsoft.Dynamics.Framework.Portal.CommonControls.dll.  To jump in and see what this dll is trying to do, I used JetBrain’s dotPeek to decompile the assembly.  In the VendProfileAccountHelper.cs class, there is a ManagedInterop call back to AX \Classes\VendAccountManager::getAllVendors()

This returns an array of [VendorAccount, VendorName] from the system.  Now, you’ll notice the comment there about XDS.  It should add an implicit where-clause to this query so that it only returns vendors that are related to the current User account.  Doesn’t make sense to return all vendors for every user right?

However, if you are system administrator that bypasses the XDS security and you are indeed returned a list of all Vendors in the current legal entity. 

This lead back to the error message above of a duplicate key exception in the array.  I did a query in the system and there were vendor accounts with the exact same name, but each had a unique Vendor Account number from the Number Sequence.  Surely the vendor name shouldn’t matter?

In the DLL I was able to find that the collection was a StringKeyedCollection which would serialize any class objects added to the collection.

  2. while (index < strArray.Length - 1)
  3. {
  4. stringKeyedCollection.Add(new VendProfileAccountInfo(strArray[index], strArray[index + 1]));
  5. index += 2;
  6. }

The collection was being populated with VendProfileAccountInfo objects, which had the following declarations:
  1. namespace Microsoft.Dynamics.Framework.Portal.CommonControls
  2. {
  3. [Serializable]
  4. internal struct VendProfileAccountInfo
  5. {
  6. public readonly string Name;
  7. public readonly string AccountNumber;
  9. public VendProfileAccountInfo(string accountNumber, string name)
  10. {
  11. this.Name = name;
  12. this.AccountNumber = accountNumber;
  13. }

And the ToString() method was overridden, alas to return the NAME of the Vendor Account and not the account number:

  2. public override string ToString()
  3. {
  4. return this.Name;
  5. }

This will cause a duplicate key exception if you have more than one vendor account in the same legal entity with the exact same DirParty.Name value.  Granted, this is only an issue for System Administrators, but was not easily apparent as to why until after some digging.  Hope this helps in case you run in to the same problem!

To resolve you have a few options:

  1. View the page with one of the more restrictive roles applied such as “Vendor (external)”
  2. Modify the while-select in AX to explicitly filter on current user relations and not rely on XDS
  3. Delete duplicate vendor accounts [if business requirements allow it]