Options

Extension Codeunit returns array on Web Service Call

wmstreetwmstreet Member Posts: 9
edited 2012-09-26 in NAV Three Tier
I have discovered a problem when calling an extension codeunit function via NAV 2009 SP1 web services. The function is coded to return a BigDecimal, but the result of the web service call is an array of BigDecimals. The array has two populated values (in positions 0 and 1) that are the same (each value is the result I would have expected).

Here is the code for the codeunit function.

PROCEDURE CustomerSalesToDate@1000000001(Cust@1000000000 : Record 18) ToDateSales : Decimal;
BEGIN
WITH Cust DO BEGIN
IF CurrentDate <> WORKDATE THEN BEGIN
CurrentDate := WORKDATE;
END;
SETRANGE("Date Filter",0D,CurrentDate);
CALCFIELDS("Sales (LCY)");
EXIT("Sales (LCY)");
END;
END;

Interrogation of the WSDL reveals that the operation should return a BigDecimal (not an Array of BigDecimals)

<xsd:element name="CustomerSalesToDate_Result">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="return_value" type="xsd:decimal" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<operation name="CustomerSalesToDate">
<operation soapAction="urn:microsoft-dynamics-schemas/page/customerwidget:CustomerSalesToDate" style="document" xmlns="http://schemas.xmlsoap.org/wsdl/soap/&quot; />
<input name="CustomerSalesToDate">
<body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/&quot; />
</input>
<output name="CustomerSalesToDate_Result">
<body use="literal" xmlns="http://schemas.xmlsoap.org/wsdl/soap/&quot; />
</output>
</operation>

The result I am receiving from the above function is BigDecimal[] with two values {43356.45, 43356.45}

I have another function in this codeunit that returns an array of 5 BigDecimals. When calling the operation via a Web Service, it returns an array of 10 values (a pair of each value I was looking for.

Here is the first line of the codeunit function

PROCEDURE CustomerStats@1000000003(Cust@1000000000 : Record 18;CustDateChoice@1000000001 : 'Current,ThisFY,LastFY') CustStats : ARRAY [5] OF Decimal;

Here is the result that is returned.
[1896.6, 1896.6, 686.67, 686.67, 64.74, 64.74, 273849.72, 273849.72, 0, 0]

So, am I doing something wrong? Is this a bug in NAV Web Services? Or maybe it is an undocumented feature to insure the numbers accuracy by returning two of them so you can easily see that they are equal.

My development is done under Mac OS X in Java using the Eclipse IDE. I'm also calling the service using dynamic discovery / invocation (stubs? we don't need no stinking stubs!), So I would like to ask my .Net/C# Brethern if they have ran into this problem, or can it be duplicated in the .Net side of the house.

I'll append some Java code to show how the operation is constructed and the call is made.

public void initializeCustomerSalesToDateOperation() throws Exception{
// Customer Sales Operation (Returns Customer Sales for a date period for the customer key)
// Check the binding to make sure the anticipated operation exists and is consistent with our understanding
BindingOperation bindingOperation = navBinding.getBindingOperation("CustomerSalesToDate","CustomerSalesToDate", "CustomerSalesToDate_Result");
if (bindingOperation == null){
customerSalesToDateOperation = null;
return;
}

// Build the Operation
OperationDesc oper = new OperationDesc();
oper.setName("CustomerSales");

// Set the Input Parameters
ParameterDesc param;
param = new ParameterDesc(new QName(nameSpaceUri, "cust"),
org.apache.axis.description.ParameterDesc.IN,
new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"),
java.lang.String.class, false, false);
oper.addParameter(param);

// Set the Return Type
oper.setReturnType(new QName("http://www.w3.org/2001/XMLSchema", "decimal"));
oper.setReturnClass(java.math.BigDecimal.class);
oper.setReturnQName(new QName(nameSpaceUri,"return_value"));

oper.setStyle(org.apache.axis.constants.Style.WRAPPED);
oper.setUse(org.apache.axis.constants.Use.LITERAL);
customerSalesToDateOperation = oper;
}


Here is the actual call, hacked to return the first value in the array that was unexpectedly returned.

/**********************************************************************
*** CustomerSalesToDate - Extended (Codeunit) Method to retrieve ***
*** the value of flow field Sales To Date from a customer ***
*** parameter - key - a key from a retrieved ***
*** instance of a Customer (WMSNavRecordObject). ***
*** @throws AxisFault ***
* @throws Exception ***
*********************************************************************/
public BigDecimal customerSalesToDate (String key) throws AxisFault, Exception{
cardPageCall.setOperation(customerSalesToDateOperation);
cardPageCall.setUseSOAPAction(true);
cardPageCall.setSOAPActionURI(nameSpaceUri + ":CustomerSalesToDate");
cardPageCall.setEncodingStyle(null);
cardPageCall.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
cardPageCall.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
cardPageCall.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
cardPageCall.setOperationName(new javax.xml.namespace.QName(nameSpaceUri, "CustomerSalesToDate"));

try {
java.lang.Object _resp = cardPageCall.invoke(new java.lang.Object[] {key});

if (_resp instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException)_resp;
}
else {
// extractAttachments(cardPageCall);
try {
ArrayList respArray = (ArrayList) _resp;
if (respArray.get(0) instanceof BigDecimal) return (BigDecimal)respArray.get(0);
else return new BigDecimal(0);
} catch (java.lang.Exception _exception) {
return (BigDecimal) org.apache.axis.utils.JavaUtils.convert(_resp, BigDecimal.class);
}
}
} catch (org.apache.axis.AxisFault axisFaultException) {
throw axisFaultException;
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

On the function that should return 5 but actually returns 10 values, I Hacked it by multiplying the index that the value should have been in by 2.
Wm. Matthew Street (Matt)
http://www.wmmatthewstreet.com

Comments

  • Options
    davesdaves Member Posts: 49
    We've seen the same behavior (data being returned in arrays of duplicate data) on a consistent basis in SP1. We are doing our development all in php in a totally different operating environment than yours. That makes it highly likely that this behavior is not due to something you're doing, but is a NAV Web Services behavior. I don't know if it's a bug or a feature. We've found it somewhat irritating but, so long as we code to deal with it, it hasn't stopped us from doing anything we wanted to do.
    Dave Studebaker
    Co-Founder Liberty Grove Software
    Author: Programming Microsoft Dynamics NAV (V5.0), 2009, 2013
  • Options
    wmstreetwmstreet Member Posts: 9
    Thanks, thats the confirmation I needed.

    I agree it can be worked around easily enough, but it may take some cleanup effort if the problem is fixed, or the secret feature is taken away from us.
    Wm. Matthew Street (Matt)
    http://www.wmmatthewstreet.com
  • Options
    AnsettAnsett Member Posts: 1
    Thanks for the post.
    I found the same problem and seems it's a trouble with decimal data type.

    If the Codeunit use is only for web service yo can return a text. In that case only return one return value, but in the definition schema the data type is string of course.

    I found another trouble when you try to use XMLports like parameters in codeunit's methods for web services publication. The definition schema that generated Navision can be treated with .NET with success but there is a mistake using name spaces and have to be modified if you want to consume with another system.
  • Options
    StefanTStefanT Member Posts: 2
    This is rather an old thread, but I ran into the same problem the other day.

    What worked for me was setting the MaxOccurs property of the XMLport field to "Once" instead of the default "Unbound" option. This should return one single element instead of an array.
  • Options
    amariteiandreeaamariteiandreea Member Posts: 2
    Hello all. I have the same problem.. In a Webservice codeunit I tried to return in a function an array of decimals.. I defined the array with dimension =4, but it actually returns 8 values.. I understood from the discussion above that it's a bug. There is a solutions for this topic?

    Thank u
Sign In or Register to comment.