Dynamics AIF : Invalid child element in namespace

A couple of days ago, I encountered this problem while calling the InventInventLocation AIF web service’s create operation.

System.ServiceModel.FaultException : Invalid document schema. The following error is reported : The element ‘InventLocation’ in namespace ‘http://schemas.microsoft.com/dynamics/2008/01/documents/InventLocation’ has invalid child element ‘InventLocationIdQuarantine’ in namespace ‘http://schemas.microsoft.com/dynamics/2008/01/documents/InventLocation’. List of possible elements expected: ‘InventLocationId’ in namespace ‘http://schemas.microsoft.com/dynamics/2008/01/documents/InventLocation’. 

The error itself may actually be confusing because in this case, the InventLocationIdQuarantine field is not actually the cause of the problem. In most cases this error will appear when the order of fields is different from the one expected by the document schema. So either the field ordering is different of there are some fields missing. In this case, I was using AIF webservices (WCF services) and you can view the actual XML that was communicated to the AIF by going to the document history.

Basic – Periodic – Application Integration Framework –  Document History 

AIF Document History

 There you can view the XML by clicking the XML button.   

XML InventLocation Create Operation

Here we can see that the inventlocation field is not present in the XML.
Do note that in this Ax application we have create custom code to initiate the InventLocationId field from a numbersequence when the record is created.   

To solve the error here, we need to tell the AIF engine that the InventLocationId field is not mandatory in our XML document and make sure the value gets defaulted.
This will be done here by adding defaulting logic in the Entity class but this could also be done by putting the defaulting “behavior” on the table using a strategy pattern. 

Setting the field as not mandatory :   

protected void initMandatoryFieldsExemptionList()
{
    super();
    this.setParmMethodAsNotMandatory(methodstr(AxInventLocation,parmInventLocationId));
}

Adding the defaulting logic

protected void setInventLocationId()
{
    NumberSequenceReference numberSequenceReference;
    ;
 
    if (this.isMethodExecuted(funcname(), fieldnum(InventLocation, InventLocationId)))
    {
        return;
    }
 
    if (this.isSetMethodsCalledFromSave())
    {
        if (this.isFieldSetExternally(fieldnum(InventLocation, InventLocationId)))
        {
            if (!this.inventLocation())
            {
                numberSequenceReference = InventParameters::numRefInventLocationId();
                this.checkNumber(numberSequenceReference.numberSequenceTable(),fieldnum(InventLocation, InventLocationId),this.parmInventLocationId());
                if (numberSequenceReference.NumberSequence && numberSequenceReference.numberSequenceTable().Continuous)
                {
                    NumberSeq::newReserveNum(numberSequenceReference).reserve(this.parmInventLocationId());
                }
            }
        }
        else
        {
            if (this.isFieldSet(fieldnum(InventLocation, InventLocationId)))
            {
                return;
            }
 
            if (!this.parmInventLocationId())
            {
                this.parmInventLocationId(NumberSeq::newGetNum(InventParameters::numRefInventLocationId()).num());
            }
        }
    }
}

Now we do not need to specify the inventLocationId and the field will be defaulted to a new number from the number sequence reference.

Warning: count(): Parameter must be an array or an object that implements Countable in /customers/5/2/1/ksaelen.be/httpd.www/wordpresses/dynamicsaxblog/wp-includes/class-wp-comment-query.php on line 399

Leave a Comment Yourself

Your email address will not be published. Required fields are marked *