web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

How to pass List from X++ to C# using DLL with passing method?

(1) ShareShare
ReportReport
Posted on by 8
Hello everyone,
I am working on a project that requires me to integrate my invoice with a third party application using C# DLL files. I have written some code in C# to create a method that takes some parameters from d365fo and assigns values to them. In C#, I use a List to store the items data, such as CustInvoiceTrans. However, when I try to pass the List parameter from X++ to C#, I get the following error:
 
        Method 'Test(System.Object)' is not found on type 'CSharp.Class1'.        
 
Can anyone help me to solve this error or suggest another way to pass parameters from X++ to C# for inserting data as a JSON using Restful API?
 
I have the same question (0)
  • Martin Dráb Profile Picture
    236,513 Most Valuable Professional on at
    How to pass List from D365 X++ to C# using DLL with passing method?
    What is the exact type you used for the parameter? A generic List class (List<T>)? ArrayList? Something else?
     
    And what are you trying to pass in. If the X++ List class, it's not going to work - you must a CLR type (such as System.Collections.ArrayList), not a native F&O type. Also, what is the type of elements of the collection?
  • Community member Profile Picture
    8 on at
    How to pass List from X++ to C# using DLL with passing method?
    I have implemented a method in d365fo x++ that uses a DLL file from C#. I have also added a button in the sales invoice form that triggers the method when clicked. The method takes the current sales invoice as an input and passes it to a C# class library. The C# class library then sends the sales invoice to a server where I have written some code in C#.
    The problem is that I don't know how to send the custInvoiceTrans data to the C# class library. If I use a list, it will send the data line by line, which is not what I want. Is there any other way to send the whole data at once?
     
  • Suggested answer
    Martin Dráb Profile Picture
    236,513 Most Valuable Professional on at
    How to pass List from X++ to C# using DLL with passing method?
    If you use a list, you'll still send a single object - the list. You probably meant that you must add the lines to the list, which is true. That's what collections like lists are for.
     
    Passing a table buffer and then iterating the records may be theoretically possible, but I don't know how to do it and I wouldn't use it even if I knew how. It's better to keep those two components (your C# library and F&O) loosely coupled.
     
    I wouldn't even use CustInvoiceTrans type in the library, because it would require a reference from your C# library to Application Suite module. Using X++ types directly is C# is cool, but my practical experience isn't very good.
     
    I would rather designe two contract classes in C# - one for the invoice header and one for lines. The header contract would hold a collection of line contracts in a property. In X++, I would have a method that initialize the line contract from CustInvoiceTrans record. The header contract could have a method like AddLine(), so you don't really have to deal with the collection in X++ at all.
     
  • Community member Profile Picture
    8 on at
    How to pass List from X++ to C# using DLL with passing method?
    I'm writing to share with you my C# code that I use as a reference for inserting invoices. You can find the code below:
            public String InsertInvoice(Int32 totalQty, int totalbillInv, int totalTaxInv, int discInv, string ItemCodeInv, string itemNameInv, DateTime date, string lineqty, string lineAmount, string UnitPrice, string TaxCharged, string Discount, string TaxRate, string invoiceType)
       
            {
        
                Invoice objInv = new Invoice();
                objInv.InvoiceNumber = "";
                objInv.DateTime = DateTime.UtcNow;
                objInv.PaymentMode = 1;
                objInv.TotalSaleValue = 0;
                objInv.TotalQuantity = 100;
                objInv.TotalBillAmount = 10000;
                objInv.TotalTaxCharged = 10;
                objInv.Discount = 10;
                objInv.FurtherTax = 100;
                objInv.InvoiceType = 1;
                objInv.Items = Items();
                List<InvoiceItems> Items()
                {
                    List<InvoiceItems> lst = new List<InvoiceItems>();
                    InvoiceItems objItem = new InvoiceItems();
                   
                    objItem.ItemCode = ItemCodeInv;
                    objItem.ItemName = itemNameInv;
                    objItem.Quantity = lineQty
                    objItem.TotalAmount = Convert.ToDouble(lineAmount);
                    objItem.SaleValue = Convert.ToDouble(UnitPrice);
                    objItem.Discount = Discount;
                    lst.Add(objItem);
                    lst.Add(objItem);
                    return lst;
                }
    The code creates an invoice object with the given parameters and assigns it a list of invoice items. The list is populated by a nested function that creates an invoice item object for each line of data. I hope this code helps you understand how to insert invoices using C#.
    Please let me know if you have any questions or feedback. Thank you for your attention.
  • Martin Dráb Profile Picture
    236,513 Most Valuable Professional on at
    How to pass List from X++ to C# using DLL with passing method?
    First of all, let me format your code and throw away unused parameters:
    public String InsertInvoice(
        string ItemCodeInv,
        string itemNameInv,
        string lineQty,
        string lineAmount,
        string UnitPrice,
        string Discount)
    {
        Invoice objInv = new Invoice();
        objInv.InvoiceNumber = "";
        objInv.DateTime = DateTime.UtcNow;
        objInv.PaymentMode = 1;
        objInv.TotalSaleValue = 0;
        objInv.TotalQuantity = 100;
        objInv.TotalBillAmount = 10000;
        objInv.TotalTaxCharged = 10;
        objInv.Discount = 10;
        objInv.FurtherTax = 100;
        objInv.InvoiceType = 1;
        objInv.Items = Items();
        
        List<InvoiceItems> Items()
        {
            List<InvoiceItems> lst = new List<InvoiceItems>();
            InvoiceItems objItem = new InvoiceItems();
           
            objItem.ItemCode = ItemCodeInv;
            objItem.ItemName = itemNameInv;
            objItem.Quantity = lineQty
            objItem.TotalAmount = Convert.ToDouble(lineAmount);
            objItem.SaleValue = Convert.ToDouble(UnitPrice);
            objItem.Discount = Discount;
            lst.Add(objItem);
            lst.Add(objItem);
            return lst;
        }
    }
    The obvious problem with this code is that it always creates just a single line object. You just add the same object twice to the list.
     
    As I explained in my previous reply, if you want to be able to add multiple lines, you can have a method like AddLine() in Invoice class. You'll create an instance of Invoice and then add several lines by calling AddLine() multiple times (with different data).
     
    I would prefer populating properties in X++ and passing the while InvoiceItems object to AddLine(), but if you want to use individual parameters (like lineAmount) and create the object inside your library, it's possible too. It just looks like more work to me, every time when you need to make any changes to parameters.
     
    I'm ignoring the fact that the code wouldn't compile.
  • Arif Hussain Profile Picture
    206 on at
    How to pass List from X++ to C# using DLL with passing method?
    Hi sir Martin Dráb,

    I have gone through the post and your suggested answer which is "I would rather design two contract classes in C# - one for the invoice header and one for lines. The header contract would hold a collection of line contracts in a property. In X++, I would have a method that initialize the line contract from CustInvoiceTrans record. The header contract could have a method like AddLine(), so you don't really have to deal with the collection in X++ at all". 

    I have tried to do something like that but I have added the list of invoiceLine as my own understanding but I do not know if I am correct. Here is my code.
     
    [DataContractAttribute]
    public class InvoiceHeaderContract
    {
        public int POSID;
        public str USIN;
        public List invoiceLines;
    
        [DataMemberAttribute('PSOID')]
        public int parmPOSID(int _POSID = POSID)
        {
                
            POSID = _POSID;
            return POSID;
        }
    
        [DataMemberAttribute('USIN')]
        public str parmUSIN(str _USIN = USIN)
        {
                
            USIN = _USIN;
            return USIN;
        }
        [
            DataMemberAttribute('InvoiceLines'),
            AifCollectionTypeAttribute('InvoiceLines', Types::String)     
        ]
    
        public List parmInvoiceLines(List _invoiceLines = invoiceLines)
        {
            invoiceLines =_invoiceLines;
            return invoiceLines;
        }
    
    }
    


    and here is my InvoiceLineContract class code
     
    [DataContractAttribute]
    public class InvoiceLineContract
    {
        public str ItemCode;
        public str ItemName;
        public int Quantity;
    
        [DataMemberAttribute('ItemCode')]
        public str parmItemCode(str _ItemCode = ItemCode)
        {
                
            ItemCode = _ItemCode;
            return ItemCode;
        }
    
        [DataMemberAttribute('ItemName')]
        public str parmItemName(str _ItemName = ItemName)
        {
                
            ItemName = _ItemName;
            return ItemName;
        }
    
        [DataMemberAttribute('Quantity')]
        public int parmQuantity(int _Quantity = Quantity)
        {
                
            Quantity = _Quantity;
            return Quantity;
        }
    }
    


    Now, I am confused of how to add the the method of AddInvociceLine in the headerContract class as you suggested. I am just wondering if you could please provide the code snippet of the method. Also, please let me know if I am doing it correctly.

    Thanks in advance. 

    Regards,

     
  • Arif Hussain Profile Picture
    206 on at
    How to pass List from X++ to C# using DLL with passing method?
    Hi sir Martin Dráb,



    I have gone through the post and your suggested answer which is "I would rather design two contract classes in C# - one for the invoice header and one for lines. The header contract would hold a collection of line contracts in a property. In X++, I would have a method that initialize the line contract from CustInvoiceTrans record. The header contract could have a method like AddLine(), so you don't really have to deal with the collection in X++ at all". 

    I have tried to do something like that. Here is my code.
     
    [DataContractAttribute]
    public class InvoiceHeaderContract
    {
        public int POSID;
        public str USIN;
    
        [DataMemberAttribute('PSOID')]
        public int parmPOSID(int _POSID = POSID)
        {
                
            POSID = _POSID;
            return POSID;
        }
    
        [DataMemberAttribute('USIN')]
        public str parmUSIN(str _USIN = USIN)
        {
                
            USIN = _USIN;
            return USIN;
        }
    
        public void addInvoiceLine(str _itemCode, str _itemName, int _quantity)
        {
            InvoiceLineContract invoiceLine = new InvoiceLineContract();
            invoiceLine.parmItemCode(_itemCode);
            invoiceLine.parmItemName(_itemName);
            invoiceLine.parmQuantity(_quantity);
        }
    }
    


    and here is my InvoiceLineContract class code
     
    [DataContractAttribute]
    public class InvoiceLineContract
    {
        public str ItemCode;
        public str ItemName;
        public int Quantity;
    
        [DataMemberAttribute('ItemCode')]
        public str parmItemCode(str _ItemCode = ItemCode)
        {
                
            ItemCode = _ItemCode;
            return ItemCode;
        }
    
        [DataMemberAttribute('ItemName')]
        public str parmItemName(str _ItemName = ItemName)
        {
                
            ItemName = _ItemName;
            return ItemName;
        }
    
        [DataMemberAttribute('Quantity')]
        public int parmQuantity(int _Quantity = Quantity)
        {
                
            Quantity = _Quantity;
            return Quantity;
        }
    }
    


    And here is the main method code in the job where I am calling it.
     
        public static void main(Args _args)
        {
            InvoiceHeaderContract invoiceHeader = new InvoiceHeaderContract();
            InvoiceLineContract invoiceLine = new InvoiceLineContract();
            invoiceHeader.parmPOSID(987155);
            invoiceHeader.parmUSIN("USIN0");
            invoiceHeader.addInvoiceLine("Item1", "TestItem", 2);
    
            IntegrationWithFBRLibrary.SendRequest obj = new IntegrationWithFBRLibrary.SendRequest();
    
            str message= obj.sendMethod(invoiceHeader, invoiceLine);
    
        }



    And here is the C# code of sendMethod
     
     public string sendMethod(Object invoiceHeader, object invoiceLine)
            {
                // My logic
            }



    Now, still it is showing me the error of

    Error        Method 'sendMethod(System.Object, System.Object)' is not found on type 'IntegrationWithFBRLibrary.SendRequest'.    IntegrationWithFBRProject

    in the main method of my job where I am calling the obj.sendMethod(invoiceHeader, invoiceLine);

    Please suggest me with your knowledge how can I do it.

    Thanks in advance. 

    Regards,
  • Martin Dráb Profile Picture
    236,513 Most Valuable Professional on at
    How to pass List from X++ to C# using DLL with passing method?
    Your code doesn't resemble my suggested solution.
     
    You created X++ classes, instead of C# classes as suggested, and unlike your previous solution. This doesn't sound like the best idea to me, because you can easily refer to your C# classes from X++, but doing it the other way around it's much more problematic.
     
    Then there is no list of lines in the header contract and your addInvoiceLine() method doesn't do anything useful. It creates an object that ceases to exist at the end of the method. Your sendMethod() doesn't support invoices than more than one line.
     
    Actually, your original solution (Invoice and InvoiceItems classes written in C#) was much closer to my suggestion than your current code, therefore I suggest your return to that and start making changes as suggested:
     
    1. The header contract would hold a collection of line contracts in a property.
    For example:
    public List<InvoiceLine> Lines { get; private set; };
    2. In X++, I would have a method that initialize the line contract from CustInvoiceTrans record.
    3. The header contract could have a method like AddLine(), so you don't really have to deal with the collection in X++ at all. The method would take a line object and add it to the collection in the Invoice class.
     
    The method for sending will take just the Invoice object, because lines will be stored inside the invoice header.
  • Arif Hussain Profile Picture
    206 on at
    How to pass List from X++ to C# using DLL with passing method?
    Sir Martin Dráb,

    I have changed the code as suggested. Here is the new one.
     
    class InvoiceHeader
        {
            public int POSID { get; set; }
            public string USIN { get; set; }
            public List<InvoiceLine> Lines { get; set; }
    
            public List<InvoiceLine> addInvoice(string itemCode, string itemName, int lineQty)
            {
                    List<InvoiceLine> lst = new List<InvoiceLine>();
                    InvoiceLine objItem = new InvoiceLine();
    
                    objItem.ItemCode = itemCode;
                    objItem.ItemName = itemName;
                    objItem.Quantity = lineQty;
                    lst.Add(objItem);
                    lst.Add(objItem);
                    return lst;
            }
        }

    class InvoiceLine
        {
            public string ItemCode { get; set; }
            public string ItemName { get; set; }
            public int Quantity { get; set; }
        }


    And here is the sendMethod
     
    public class SendRequest
        {
            public string sendMethod(Object invoice)
            {
               // My logic
            }
        }

    I am still confused, how can I call the sendMethod in my x++ code and what parameter I have to pass from d365fo x++ to it. 

    Can you please elaborate a little bit more for me.

    Thanks,
  • Verified answer
    Martin Dráb Profile Picture
    236,513 Most Valuable Professional on at
    How to pass List from X++ to C# using DLL with passing method?
    Your addInvoice() method doesn't add the line to the Lines property. It ignores Lines completely; it always creates a new empty List, add the line there and returns it.
     
    What is should do is something like this:
    public void AddLine(string itemCode, string itemName, int lineQty)
    {
        if (this.Lines == null)
        {
            this.Lines = new List<InvoiceLine>();
        }
        
        InvoiceLine line = new InvoiceLine();
    
        line.ItemCode = itemCode;
        line.ItemName = itemName;
        line.Quantity = lineQty;
        
        this.Lines.Add(line);
    }
    The parameter of sendMethod() should be InvoiceHeader, because you want to send an invoice. What you'll pass there from X++ is an instance of your InvoiceHeader class; the same object where you added lines through AddLine() method.
     
    Your sendMethod() is an instance method, therefore you need to create and instance of SendRequest class and use the dot operator to call the method. For example:
    YourNamespace.SendRequest sender = new YourNamespace.SendRequest();
    sender.sendMethod(invoice);

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Abhilash Warrier – Community Spotlight

We are honored to recognize Abhilash Warrier as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
CA Neeraj Kumar Profile Picture

CA Neeraj Kumar 1,841

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 783 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 490 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans