D365/AX7: Custom Web Service/API For Header-Line JSON Integration

Requirement

Developing a custom web service for reading data from 2 Header Line tables.The return message should be in JSON Format and input message should also be in JSON Format.

Sample Code

  1. Create a contract class of header table[DataContractAttribute('KIOSKTagHeaderContract')]
    class AcxKIOSKTagHeaderContract
    {
    AcxTagNo tagNo;
    Description tagDescription;
    InventSiteId currentSite;
    InventLocationId currentWarehouse;
    str tagStatus;
    AcxGrossWeight grossWt;
    AcxNetWeight netWt;
    AcxNetWeight stoneWt;
    PurchPrice purchPrice;
    ItemId fgItemId;
    AcxSectionId sectionId;
    AcxBrandId brand;
    AcxCertificateNo certificateNo;
    str addWeight;
    List tagLineList;
    [DataMemberAttribute('tagNo')]
    public AcxTagNo tagNo(AcxTagNo _tagNo = tagNo)
    {
    tagNo = _tagNo;
    return tagNo;
    }
    
    [DataMemberAttribute('tagDescription')]
    public Description tagDescription(Description _tagDescription = tagDescription)
    {
    tagDescription = _tagDescription;
    return tagDescription;
    }
    
    [DataMemberAttribute('currentSite')]
    public InventSiteId currentSite(InventSiteId _currentSite = currentSite)
    {
    currentSite = _currentSite;
    return currentSite;
    }
    
    [DataMemberAttribute('currentWarehouse')]
    public InventLocationId currentWarehouse(InventLocationId _currentWarehouse = currentWarehouse)
    {
    currentWarehouse = _currentWarehouse;
    return currentWarehouse;
    }
    
    [DataMemberAttribute('tagStatus')]
    public str tagStatus(str _tagStatus = tagStatus)
    {
    tagStatus = _tagStatus;
    return tagStatus;
    }
    
    [DataMemberAttribute('grossWt')]
    public AcxGrossWeight grossWt(AcxGrossWeight _grossWt = grossWt)
    {
    grossWt = _grossWt;
    return grossWt;
    }
    
    [DataMemberAttribute('stoneWt')]
    public AcxNetWeight stoneWt(AcxNetWeight _stoneWt = stoneWt)
    {
    stoneWt = _stoneWt;
    return stoneWt;
    }
    
    [DataMemberAttribute('netWt')]
    public AcxNetWeight netWt(AcxNetWeight _netWt = netWt)
    {
    netWt = _netWt;
    return netWt;
    }
    
    [DataMemberAttribute('purchPrice')]
    public PurchPrice purchPrice(PurchPrice _purchPrice = purchPrice)
    {
    purchPrice = _purchPrice;
    return purchPrice;
    }
    
    [DataMemberAttribute('fgItemId')]
    public ItemId fgItemId(ItemId _fgItemId = fgItemId)
    {
    fgItemId = _fgItemId;
    return fgItemId;
    }
    
    [DataMemberAttribute('sectionId')]
    public AcxSectionId sectionId(AcxSectionId _sectionId = sectionId)
    {
    sectionId = _sectionId;
    return sectionId;
    }
    
    [DataMemberAttribute('brand')]
    public AcxBrandId brand(AcxBrandId _brand = brand)
    {
    brand = _brand;
    return brand;
    }
    
    [DataMemberAttribute('certificateNo')]
    public AcxCertificateNo certificateNo(AcxCertificateNo _certificateNo = certificateNo)
    {
    certificateNo = _certificateNo;
    return certificateNo;
    }
    
    [DataMemberAttribute('addWeight')]
    public str addWeight(str _addWeight = addWeight)
    {
    addWeight = _addWeight;
    return addWeight;
    }
    
    [DataMemberAttribute("tagLine"),
    AifCollectionTypeAttribute("_tagLineList",Types::Class, classStr(AcxKIOSKTagLineContract)),
    AifCollectionTypeAttribute("return",Types::Class, classStr(AcxKIOSKTagLineContract))]
    public List parmtagLineList(List _tagLineList =tagLineList)
    {
    tagLineList = _tagLineList;
    return tagLineList;
    }
    
    }
  2. Create a contract class of line table[DataContractAttribute('KIOSKTagLineContract')]
    
    class AcxKIOSKTagLineContract
    
    {
    
    AcxTagNo tagNo;
    
    LineNum LineNum;
    
    ItemId itemCode;
    
    Qty qty;
    
    AcxNetWeight netWt;
    
    int noofStonePcs;
    
    PurchPrice purchTransPrice;
    
    PurchPrice purchTransValue;
    
    AcxGrossWeight grossWt;
    
    UnitOfMeasureSymbol uom;
    
    AcxShortName stoneCut;
    
    AcxShortName diamonColor;
    
    AcxShortName stoneClarity;
    
    AcxShortName stoneShape;
    
    AcxShortName stoneSize;
    
    AcxShortName stoneName;
    
    str primaryItem;
    
    [DataMemberAttribute('tagNo')]
    public AcxTagNo tagNo(AcxTagNo _tagNo = tagNo)
    {
    tagNo = _tagNo;
    return tagNo;
    }
    
    [DataMemberAttribute('LineNum')]
    public LineNum LineNum(LineNum _LineNum = LineNum)
    {
    LineNum = _LineNum;
    return LineNum;
    }
    
    [DataMemberAttribute('itemCode')]
    public ItemId itemCode(ItemId _itemCode = itemCode)
    {
    itemCode = _itemCode;
    return itemCode;
    }
    
    [DataMemberAttribute('qty')]
    public Qty qty(Qty _qty = qty)
    {
    qty = _qty;
    return qty;
    }
    
    [DataMemberAttribute('netWt')]
    public AcxNetWeight netWt(AcxNetWeight _netWt = netWt)
    {
    netWt = _netWt;
    return netWt;
    }
    
    [DataMemberAttribute('noofStonePcs')]
    public int noofStonePcs(int _noofStonePcs = noofStonePcs)
    {
    noofStonePcs = _noofStonePcs;
    return noofStonePcs;
    }
    
    [DataMemberAttribute('purchTransPrice')]
    public PurchPrice purchTransPrice(PurchPrice _purchTransPrice = purchTransPrice)
    {
    purchTransPrice = _purchTransPrice;
    return purchTransPrice;
    }
    
    [DataMemberAttribute('purchTransValue')]
    public PurchPrice purchTransValue(PurchPrice _purchTransValue = purchTransValue)
    {
    purchTransValue = _purchTransValue;
    return purchTransValue;
    }
    
    [DataMemberAttribute('uom')]
    public UnitOfMeasureSymbol uom(UnitOfMeasureSymbol _uom = uom)
    {
    uom = _uom;
    return uom;
    }
    
    [DataMemberAttribute('stoneCut')]
    public AcxShortName stoneCut(AcxShortName _stoneCut = stoneCut)
    {
    stoneCut = _stoneCut;
    return stoneCut;
    }
    
    [DataMemberAttribute('diamonColor')]
    public AcxShortName diamonColor(AcxShortName _diamonColor = diamonColor)
    {
    diamonColor = _diamonColor;
    return diamonColor;
    }
    
    [DataMemberAttribute('stoneClarity')]
    public AcxShortName stoneClarity(AcxShortName _stoneClarity = stoneClarity)
    {
    stoneClarity = _stoneClarity;
    return stoneClarity;
    }
    
    [DataMemberAttribute('stoneShape')]
    public AcxShortName stoneShape(AcxShortName _stoneShape = stoneShape)
    {
    stoneShape = _stoneShape;
    return stoneShape;
    }
    
    [DataMemberAttribute('stoneSize')]
    public AcxShortName stoneSize(AcxShortName _stoneSize = stoneSize)
    {
    stoneSize = _stoneSize;
    return stoneSize;
    }
    
    [DataMemberAttribute('stoneName')]
    public AcxShortName stoneName(AcxShortName _stoneName = stoneName)
    {
    stoneName = _stoneName;
    return stoneName;
    }
    
    [DataMemberAttribute('primaryItem')]
    public str primaryItem(str _primaryItem = primaryItem)
    {
    primaryItem = _primaryItem;
    return primaryItem;
    }
    
    [DataMemberAttribute('grossWt')]
    public AcxGrossWeight grossWt(AcxGrossWeight _grossWt = grossWt)
    {
    grossWt = _grossWt;
    return grossWt;
    }
    
    }
  3. Create a service operation classclass AcxKIOSKService
    
    {
    
    [AifCollectionTypeAttribute('return', Types::Class, classStr(AcxKIOSKTagHeaderContract)),
    
    AifCollectionTypeAttribute('_keys', Types::Class, classStr(AcxKIOSKParmInfoContract))
    
    ]
    
    public List getTagInfo(List _keys)
    
    {
    
    ListEnumerator keysEnumerator;
    
    AcxKIOSKTagHeaderContract acxKIOSKTagHeaderContract;
    
    AcxKIOSKTagLineContract aCXKIOSKTagLineContract;
    
    AcxKIOSKParmInfoContract acxKIOSKParmInfoContract;
    
    List returnList = new List(Types::Class);
    
    List returnLineList = new List(Types::Class);
    
    AcxTagHeader acxTagHeader;
    
    AcxTagLines tagLines;
    
    str fromDateTime, toDateTime;
    
    ;
    
    keysEnumerator = _keys.getEnumerator();
    keysEnumerator.moveNext();
    acxKIOSKParmInfoContract = new AcxKIOSKParmInfoContract();
    acxKIOSKParmInfoContract = keysEnumerator.current();
    fromDateTime = acxKIOSKParmInfoContract.fromDateTime();
    if (!fromDateTime)
    {
    fromDateTime ="1985/02/25 23:04:59";
    }
    
    toDateTime = acxKIOSKParmInfoContract.toDateTime();
    if (!toDateTime)
    {
    toDateTime ="2050/02/25 23:04:59";
    }
    while select * from acxTagHeader
    where acxTagHeader.ModifiedDateTime >= str2Datetime(fromDateTime, 321)
    && acxTagHeader.ModifiedDateTime <= str2Datetime(toDateTime, 321)
    {
    acxKIOSKTagHeaderContract = new acxKIOSKTagHeaderContract();
    acxKIOSKTagHeaderContract.tagNo(acxTagHeader.TagNo);
    acxKIOSKTagHeaderContract.tagDescription(acxTagHeader.Description);
    acxKIOSKTagHeaderContract.fgItemId(acxTagHeader.ItemId);
    acxKIOSKTagHeaderContract.currentWarehouse(acxTagHeader.InventLocationId);
    acxKIOSKTagHeaderContract.currentSite(acxTagHeader.InventSiteId);
    acxKIOSKTagHeaderContract.grossWt(acxTagHeader.GrossWeight);
    acxKIOSKTagHeaderContract.netWt(acxTagHeader.NetWeight);
    acxKIOSKTagHeaderContract.stoneWt(acxTagHeader.StoneWeight);
    acxKIOSKTagHeaderContract.tagStatus(enum2Str(acxTagHeader.TagStatus));
    acxKIOSKTagHeaderContract.purchPrice(acxTagHeader.PurchaseCost);
    acxKIOSKTagHeaderContract.sectionId(acxTagHeader.SectionId);
    acxKIOSKTagHeaderContract.brand(acxTagHeader.Brand);
    acxKIOSKTagHeaderContract.certificateNo(acxTagHeader.CertificateNo);
    acxKIOSKTagHeaderContract.addWeight(enum2Str(acxTagHeader.AddWeight));
    returnLineList = new List(Types::Class);
    this.kioskTagLines(acxTagHeader.TagNo);
    /*******
    while select * from tagLines
    where tagLines.TagNo == acxTagHeader.TagNo
    {
    aCXKIOSKTagLineContract = new AcxKIOSKTagLineContract();
    aCXKIOSKTagLineContract.tagNo(tagLines.TagNo);
    aCXKIOSKTagLineContract.LineNum(tagLines.LineNum);
    aCXKIOSKTagLineContract.itemCode(tagLines.ItemId);
    aCXKIOSKTagLineContract.netWt(tagLines.NetWeight);
    aCXKIOSKTagLineContract.grossWt(tagLines.GrossWeight);
    aCXKIOSKTagLineContract.qty(tagLines.Quantity);
    aCXKIOSKTagLineContract.noofStonePcs(tagLines.NoofStonePcs);
    aCXKIOSKTagLineContract.purchTransPrice(tagLines.PurchTransPrice);
    aCXKIOSKTagLineContract.purchTransValue(tagLines.PurchTransValue);
    aCXKIOSKTagLineContract.uom(tagLines.UOM);
    aCXKIOSKTagLineContract.stoneCut(tagLines.StoneCut);
    aCXKIOSKTagLineContract.diamonColor(tagLines.DiamondColor);
    aCXKIOSKTagLineContract.stoneClarity(tagLines.StoneClarity);
    aCXKIOSKTagLineContract.stoneName(tagLines.StoneName);
    aCXKIOSKTagLineContract.stoneShape(tagLines.StoneShape);
    aCXKIOSKTagLineContract.stoneSize(tagLines.StoneSize);
    aCXKIOSKTagLineContract.primaryItem(enum2Str(tagLines.PrimaryItem));
    returnLineList.addEnd(aCXKIOSKTagLineContract);
    }
    acxKIOSKTagHeaderContract.parmtagLineList(returnLineList);
    *******/
    returnList.addEnd(acxKIOSKTagHeaderContract);
    }
    return returnList;
    }
    
    public void kioskTagLines(AcxTagNo tagNo)
    {
    AcxKIOSKTagLineContract aCXKIOSKTagLineContract;
    AcxKIOSKParmInfoContract acxKIOSKParmInfoContract;
    List returnLineList = new List(Types::Class);
    
    AcxTagLines tagLines ;
    
    returnLineList = new List(Types::Class);
    
    while select * from tagLines
    where tagLines.TagNo == tagNo
    {
    aCXKIOSKTagLineContract = new AcxKIOSKTagLineContract();
    aCXKIOSKTagLineContract.tagNo(tagLines.TagNo);
    aCXKIOSKTagLineContract.LineNum(tagLines.LineNum);
    aCXKIOSKTagLineContract.itemCode(tagLines.ItemId);
    aCXKIOSKTagLineContract.netWt(tagLines.NetWeight);
    aCXKIOSKTagLineContract.grossWt(tagLines.GrossWeight);
    aCXKIOSKTagLineContract.qty(tagLines.Quantity);
    aCXKIOSKTagLineContract.noofStonePcs(tagLines.NoofStonePcs);
    aCXKIOSKTagLineContract.purchTransPrice(tagLines.PurchTransPrice);
    aCXKIOSKTagLineContract.purchTransValue(tagLines.PurchTransValue);
    aCXKIOSKTagLineContract.uom(tagLines.UOM);
    aCXKIOSKTagLineContract.stoneCut(tagLines.StoneCut);
    aCXKIOSKTagLineContract.diamonColor(tagLines.DiamondColor);
    aCXKIOSKTagLineContract.stoneClarity(tagLines.StoneClarity);
    aCXKIOSKTagLineContract.stoneName(tagLines.StoneName);
    aCXKIOSKTagLineContract.stoneShape(tagLines.StoneShape);
    aCXKIOSKTagLineContract.stoneSize(tagLines.StoneSize);
    aCXKIOSKTagLineContract.primaryItem(enum2Str(tagLines.PrimaryItem));
    returnLineList.addEnd(aCXKIOSKTagLineContract);
    }
    /////acxKIOSKTagHeaderContract.parmtagLineList(returnLineList);
    }
    
    [
    AifCollectionTypeAttribute('return', Types::Class, classStr(AcxKIOSKDesignReplyContract)),
    AifCollectionTypeAttribute('_keys', Types::Class, classStr(AcxKIOSKDesignContract))
    ]
    public List setDesignInfo(List _keys)
    {
    ListEnumerator keysEnumerator;
    AcxKIOSKDesignReplyContract acxKIOSKDesignReplyContract;
    AcxKIOSKDesignContract acxKIOSKDesignContract;
    List returnList = new List(Types::Class);
    AcxDesignHeader acxDesignHeader;
    AcxDesignLine acxdesignLine;
    ;
    
    keysEnumerator = _keys.getEnumerator();
    while (keysEnumerator.moveNext())
    {
    infolog.clear();
    try
    {
    ttsbegin;
    acxKIOSKDesignContract = keysEnumerator.current();
    acxDesignHeader.clear();
    acxDesignHeader.initValue();
    acxDesignHeader.DesignCode = acxKIOSKDesignContract.designCode();
    acxDesignHeader.DesignName = acxKIOSKDesignContract.designName();
    acxDesignHeader.VendAccount = acxKIOSKDesignContract.vendAccount();
    acxDesignHeader.VendDesignNo = acxKIOSKDesignContract.vendDesign();
    acxDesignHeader.insert();
    acxdesignLine.clear();
    acxdesignLine.initValue();
    acxdesignLine.DesignCode = acxDesignHeader.DesignCode;
    acxdesignLine.DesignName = acxDesignHeader.DesignName;
    acxdesignLine.ItemId = acxKIOSKDesignContract.itemId();
    acxdesignLine.ItemTypeCode = acxKIOSKDesignContract.itemTypeCode();
    acxdesignLine.OrnamentCategoryCode = acxKIOSKDesignContract.ornamentCategoryCode();
    acxdesignLine.GrossWeightRangeCode = acxKIOSKDesignContract.weightRangeCode();
    acxdesignLine.DiamondWeightRangeCode = acxKIOSKDesignContract.diamonWeightRangeCode();
    acxdesignLine.SectionId = acxKIOSKDesignContract.sectionId();
    acxdesignLine.BrandId = acxKIOSKDesignContract.brandId();
    acxdesignLine.SectionName = AcxSection::find(acxdesignLine.SectionId, acxdesignLine.OrnamentCategoryCode).SectionName;
    acxdesignLine.BrandName = AcxBrand::find(acxdesignLine.BrandId, acxdesignLine.SectionId, acxdesignLine.OrnamentCategoryCode).BrandName;
    acxdesignLine.insert();
    ttscommit;
    acxKIOSKDesignReplyContract = new AcxKIOSKDesignReplyContract();
    acxKIOSKDesignReplyContract.designCode(acxKIOSKDesignContract.designCode());
    acxKIOSKDesignReplyContract.designName(acxKIOSKDesignContract.designName());
    acxKIOSKDesignReplyContract.status("200");
    acxKIOSKDesignReplyContract.message("Success");
    returnList.addEnd(acxKIOSKDesignReplyContract);
    }
    catch
    {
    ttsabort;
    acxKIOSKDesignReplyContract = new AcxKIOSKDesignReplyContract();
    acxKIOSKDesignReplyContract.designCode(acxKIOSKDesignContract.designCode());
    acxKIOSKDesignReplyContract.designName(acxKIOSKDesignContract.designName());
    acxKIOSKDesignReplyContract.status("400");
    acxKIOSKDesignReplyContract.message(strFmt("Failed{%1}", infolog.text()));
    returnList.addEnd(acxKIOSKDesignReplyContract);
    }
    }
    
    return returnList;
    }
    
    [
    AifCollectionTypeAttribute('return', Types::Class, classStr(AcxJobCardReplyContract)),
    AifCollectionTypeAttribute('_keys', Types::Class, classStr(AcxJobCardContract))
    ]
    public List setJobCardInfo(List _keys)
    {
    ListEnumerator keysEnumerator;
    AcxJobCardReplyContract acxJobCardReplyContract;
    AcxJobCardContract acxJobCardContract;
    List returnList = new List(Types::Class);
    AcxKIOSKJobCardTable acxKIOSKJobCardTable;
    ;
    
    keysEnumerator = _keys.getEnumerator();
    while (keysEnumerator.moveNext())
    {
    infolog.clear();
    try
    {
    acxJobCardContract = keysEnumerator.current();
    changecompany(acxJobCardContract.dataAreaId())
    {
    ttsbegin;
    acxKIOSKJobCardTable.clear();
    acxKIOSKJobCardTable.initValue();
    acxKIOSKJobCardTable.BrandId = acxJobCardContract.brandId();
    acxKIOSKJobCardTable.DesignCode = acxJobCardContract.designCode();
    acxKIOSKJobCardTable.DiamondWtRangeCode = acxJobCardContract.brandId();
    acxKIOSKJobCardTable.FGItemId = acxJobCardContract.fgItemId();
    acxKIOSKJobCardTable.GrossWtRangeCode = acxJobCardContract.grossWeightRangeCode();
    acxKIOSKJobCardTable.NetWtRangeCode = acxJobCardContract.netWeightRangeCode();
    acxKIOSKJobCardTable.OrnamentPcs = acxJobCardContract.ornPCS();
    acxKIOSKJobCardTable.ReferenceId = acxJobCardContract.referenceID();
    acxKIOSKJobCardTable.SectionId = acxJobCardContract.sectionId();
    acxKIOSKJobCardTable.insert();
    ttscommit;
    }
    acxJobCardReplyContract = new acxJobCardReplyContract();
    acxJobCardReplyContract.designCode(acxJobCardContract.designCode());
    acxJobCardReplyContract.referenceID(acxJobCardContract.referenceID());
    acxJobCardReplyContract.fgItemId(acxJobCardContract.fgItemId());
    acxJobCardReplyContract.status("200");
    acxJobCardReplyContract.message("Success");
    returnList.addEnd(acxJobCardReplyContract);
    }
    catch
    {
    ttsabort;
    acxJobCardReplyContract = new acxJobCardReplyContract();
    acxJobCardReplyContract.designCode(acxJobCardContract.designCode());
    acxJobCardReplyContract.referenceID(acxJobCardContract.referenceID());
    acxJobCardReplyContract.fgItemId(acxJobCardContract.fgItemId());
    acxJobCardReplyContract.status("400");
    acxJobCardReplyContract.message(strFmt("Failed{%1}", infolog.text()));
    returnList.addEnd(acxJobCardReplyContract);
    }
    }
    
    return returnList;
    }
    
    }
  4. Create a new services and add service operation class inside it which you created in Step 3.
  5. Create a new services group using services which you created in step 4.The property of services group should be AutoDeploy = Yes.
  6. Now Your API is ready to use.You case consume API in C# by downloading below sampleshttps://github.com/microsoft/Dynamics-AX-Integration/tree/master/ServiceSamples/ODataConsoleApplication
    
    Your C# or DotNet should look like below one :
    
    static void Main(string[] args)
    {
    string GetUserSessionOperationPath = string.Format("{0}{1}", ClientConfiguration.Default.UriString.TrimEnd('/'), sessionUrl);
    
    var request = HttpWebRequest.Create(GetUserSessionOperationPath);
    // If you call GetAuthenticationHeader with true you will the auth via AAD Web App, otherwise via Native AAD App
    request.Headers[OAuthHelper.OAuthHeader] = OAuthHelper.GetAuthenticationHeader(true);
    request.ContentType = "application/json; charset=utf-8";
    request.Method = "POST";
    //request.ContentLength = Encoding.UTF8.GetByteCount("[{\"ordernumber\": \"en-US\",\"customerCode\": \"ABC\"}]");
    using (var streamWriter = new StreamWriter(request.GetRequestStream()))
    {
    // string json = "{\"_keys\":[{\"fromDateTime\":\"\",\"toDateTime\":\"\"}]}";
    // string json = "{\"_keys\":[{\"designCode\":\"10DES-0054-TA\",\"designName\":\"10DES-0054-T\",\"itemId\":\"14_G_22K\",\"group\":\"G\",\"subGroup\":\"14\",\"sectionId\":\"CELEBRATED\",\"brandId\":\"OTHER\",\"grossweight\":0,\"weightRangeCode\":\"WR1\",\"diamonWeightRangeCode\":\"CT1\",\"vendAccount\":\"TST-000001\",\"vendDesign\":\"10DES-0054-T\",\"dataAreaId\":\"tst\"}]}";
    
    string json = "{\"_keys\":[{\"designCode\":\"10DES-0054-T\",\"referenceID\":\"KIOSKRef001\",\"fgItemId\":\"14_G_22K\",\"sectionId\":\"CELEBRATED\",\"brandId\":\"OTHER\",\"grossWeightRange\":\"WR1\",\"diamonWeightRange\":\"CT1\",\"netWeightRange\":\"TST-000001\",\"ornPCS\":10,\"dataAreaId\":\"tst\"}]}";
    Debug.Write(json);
    streamWriter.Write(json);
    streamWriter.Flush();
    streamWriter.Close();
    }
    using (var response = (HttpWebResponse)request.GetResponse())
    {
    using (Stream responseStream = response.GetResponseStream())
    {
    using (StreamReader streamReader = new StreamReader(responseStream))
    {
    string responseString = streamReader.ReadToEnd();
    
    Console.WriteLine(responseString);
    }
    }
    }
    
    Console.ReadLine();
    }
    
    }

One thought on “D365/AX7: Custom Web Service/API For Header-Line JSON Integration”

  1. Can you please send me the whole project, It is missing many tables and a class – AcxKIOSKParmInfoContract and other objects. ( D365/AX7: Custom Web Service/API For Header-Line JSON Integration)

    Regards
    Anita Chawla

Leave a Reply