Question

i need to return an array of a structure in a Datacontract. i cant manage to make it. i receive an error when setting the values for the array.

Here's the Datacontract declaration:

[DataContract] 
public class invoice_data
{
    [DataMember]
    public Invoice_Body_Item[] invoice_body;
}


[StructLayout(LayoutKind.Sequential)]
public struct Invoice_Body_Item
{
    public string Item_Description;
    public decimal Item_Value;
}

} And here's the method code:

invoice_data Invoice = new invoice_data();
object tr_bl = svr.GetInvoiceData(inputparams.ck, svr.Confirm(inputparams.ck));

for (int i = ((Array)(((object[])(tr_bl))[1])).GetLowerBound(0); i <= ((Array)(((object[])(tr_bl))[1])).GetUpperBound(0); i++)
{
    Invoice.invoice_body[i].Item_Description = (string)((object[])(((object[])(((object[])(tr_bl))[1]))[i]))[0];
    Invoice.invoice_body[i].Item_Value = (decimal)((object[])(((object[])(((object[])(tr_bl))[1]))[i]))[1]; 
}
                        }

In this line i get the error "Object reference not set to an instance of an object."

Invoice.invoice_body[i].Item_Description = (string)((object[])(((object[])(((object[])(tr_bl))[1]))[i]))[0];

SOLVED. Thanks all for the help. I made the following changes:

  public Invoice_Body_Item[] fill_invoice_body(object tr_bl)
    {    
        Invoice_Body_Item[] temp = new Invoice_Body_Item[40];

        for (int i = 0; i <= ((Array)(((object[])(tr_bl))[1])).GetUpperBound(0); i++)
        {
            temp[i].Item_Description = (string)((object[])(((object[])(((object[])(tr_bl))[1]))[i]))[0];
            temp[i].Item_Value = (decimal)((object[])(((object[])(((object[])(tr_bl))[1]))[i]))[1]; 
        }

       return temp;

    }

and then call it with

  Invoice.invoice_body = fill_invoice_body(tr_bl);
Était-ce utile?

La solution

invoice_body of invoice_data is still null, given this example. You can't just declare a thing as of type array and then use it, you still need to initialise it, so you can't access by index something that is nothing, let alone has no length.

To do this:

Invoice.invoice_body = new Invoice_Body_Item[desiredLength];

Where desiredLength should be decided based on how much you're going to put in there/how many items you want or will end up with in the array. This should generally be calculable from the same data used to determine how many times to loop.

Autres conseils

Your Invoice instance is being instantiated to a new invoice_data object, and you're then assigning values to the invoice_data.invoice_body collection - I can't see why you'd get a null reference exception from the code which extracts the value to assign, so is invoice_data.invoice_body null?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top