NAV2013R2 - .NET WebService decimals all NULL

andrewtandrewt Member Posts: 73
edited 2014-12-15 in NAV Three Tier
Hi all,
this is for NAV 2013R2
I am consuming a 3rd party web service to retrieve purchase order data from an outside application and use this data in NAV.
I've built a DotNet ControlAddIn component with a method to receive the PO data from the WS: InputValue is the PO No. requested by NAV, return value is the DotNet complex data type PurchaseOrderHeader:
public FIService.PurchaseOrderHeader GetPurchOrder(string PurchOrderNo)
{
[...]
}

In NAV I've also defined a DotNet variable of type PurchaseOrderHeader.
From NAV, I call the DotNet Method GetPurchOrder to load the PO Data into NAV:

SMTPurchOrder DotNet SMTConnector.PurchOrderHeader
SMTPurchOrder := SMTConnector.GetPurchOrder('CH3-13-DST006-V(01)'

Basically, this works and I am able to use content from the DotNet data within NAV, e.g. assign it to NAV fields/variables etc.

The problem I have is, the DotNet data type PurchOrderHeader contains fields/values of type nullable<double> which seems to not get transferred into NAV correctly. The values of other data types are available in NAV, e.g. strings, but the decimals, defined as nullable<double> are all received with NULL values.
When I debug the DotNet ControlAddin I can see the values are retreived correctly from the WS, but when transferred to NAV through the Method's return value, it seems they got lost.

Anyone who knows what's wong with it and how to resolve this ? How to get the received decimal values returned correctly from DotNet into NAV ?

Thanks in advance
Andrew

Answers

  • andrewtandrewt Member Posts: 73
    OK, let me simplify this isue a little bit:

    My experience is that NAV is not able to deal with DotNet nullable datatypes.
    To verify this, I've created a small DotNet component which I use as ControlAddin in NAV:
    namespace Microsoft.Dynamics.NAV.SMTConnector
    {
        public class TestDotNetTypes
        {
            public System.Nullable<double> DotNetNullableDouble { get; set; }
            public double DotNetDouble { get; set; }
    
            public System.Nullable<double> GetNullable()
            {
                System.Nullable<double> Value;
    
                Value = 123.456;
                return Value;
            }
    
            public double GetNonNullable()
            {
                double Value;
    
                Value = 123.456;
                return Value;
            }
        }
    }
    

    From NAV I use the following code piece to define the double and nullable double dotnet data types and retrieve the values from the according methods:
    SMTTestDotNetTypes := SMTTestDotNetTypes.TestDotNetTypes;
    SMTTestDotNetTypes.DotNetDouble := SMTTestDotNetTypes.GetNonNullable;
    SMTTestDotNetTypes.DotNetNullableDouble := SMTTestDotNetTypes.GetNullable;
    
    IF ISNULL(SMTTestDotNetTypes.DotNetNullableDouble) THEN
      MESSAGE('The returned nullable value is NULL.')
    ELSE BEGIN
      NAVAmount := SMTTestDotNetTypes.DotNetNullableDouble;
      MESSAGE('The returned nullable value is %1.',NAVAmount);
    END;
    
    NAVAmount := SMTTestDotNetTypes.DotNetDouble;
      MESSAGE('The returned non-nullable value is %1.',NAVAmount);
    

    The variant with the DotNet type DOUBLE works as expected and I am able to retrieve and use the value in NAV.
    Including the variant which uses the DotNet type Nullable<double> causes the NAV client to crash.
    Thus to me it currently looks like NAV has a problem to deal with the nullable datatypes.

    My current NAV version is NAV2013R2, Version 7.10.36897

    I've run some research for nullables in relation to NAV but haven't found anything.
    So my question here is if anybody made similar experiences or can explain why this is the case or what's wrong with my code and/or how to work around this problem ?

    Thanks
    Andrew
  • Cem_KaraerCem_Karaer Member Posts: 281
    Hello,

    You can assign nullable dotnet variable to NAV's variant variable and evaluate that variant variable to a NAV's decimal variable. But as far as I can understand you cannot do the otherwise, namely there is no way for assigning a NAV variable (decimal, integer or something else) to nullable dotnet variable. I could assign a variant variable to a nullable dotnet in design time, and it did not create a compile time error. But when I execute my code, it gave me the following:

    Microsoft Dynamics NAV Classic
    Microsoft.Dynamics.Nav.Runtime.NavIndirectValue cannot be casted to Microsoft.Dynamics.Nav.Runtime.NavDotNet.
    OK
    Cem Karaer @ Pargesoft
    Dynamics NAV Developer since 2005
  • andrewtandrewt Member Posts: 73
    Hello Cem,

    I've tried what you suggested by using a simple .NET class which provides a nullable double value as return value:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TestNullables
    {
        public class Test
        {
            public double? GetNullableValue()
            {
                return 12.34;
            }
        }
    }
    

    In NAV, the method GetNullableValue is called and assigned to a Variant variable, then converted into string and from string to decimal:
    [b]Name	DataType[/b]
    TestNullables	DotNet	TestNullables.Test.'TestNullables, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'	
    varValue	Variant		
    txtValue	Text		
    decValue	Decimal		
    
    OnRun()
    IF NOT CONFIRM('Test .NET Nullables ?',FALSE) THEN
      EXIT;
    
    TestNullables := TestNullables.Test;
    
    varValue := TestNullables.GetNullableValue;
    
    txtValue := FORMAT(varValue);
    IF varValue.ISDECIMAL THEN BEGIN
      EVALUATE(decValue,txtValue);
    END;
    
    MESSAGE('Var value : %1 - decimal value %2',txtValue,decValue);
    

    The good news is - NAV does compile and does not crash on execution anymore.
    But the NAV variant variable does not receive any value - it remains NULL.
    If I turn the return value of .NET into simple double without nullable (removing the questionmark) the NAV variant variable receives the correct value and converts it into the internal decimal.

    Thanks for digging into it, Cem. The variant datatype seems to be a good idea.
    But NAV still seems to be unable to handle those nullables...
    Again - I am currently working on NAV NAV2013R2, Version 7.10.36897

    Cheers
    Andrew
  • Cem_KaraerCem_Karaer Member Posts: 281
    Well, probably ISDECIMAL check fails, because the value that the variant variable holds is not a decimal at all, but a nullable decimal. Did you try to get the value without ISDECIMAL check? What does the expression "FORMAT(varValue)" return?
    Cem Karaer @ Pargesoft
    Dynamics NAV Developer since 2005
  • andrewtandrewt Member Posts: 73
    Yes, I tried also without ISDECIMAL - same result. The FORMAT step is necessary because NAV does not allow to use EVALUATE with a variant type as input.
    When debugging, after execution of varValue := TestNullables.GetNullableValue, the var variable is shown as "Uninitialized". The text variable contains 'null' after the FORMAT statement.

    Which leeds us - by the way - back to the initial problem of this request that nullable datatypes in NAV always seem to deliver NULL. Looks like NAV looses the content of nullable datatypes when pulling them into NAV. In this simple example it's the return value of the .NET Method, in my first statement it's the value of nullable<double> fields within a complex .NET datatype (class).

    Cheers
    Andrew
  • nhsejthnhsejth Member, Microsoft Employee Posts: 34
    Nullable types are not supported by the .Net data type in Nav 2013 and they cannot be used in variants. I will suggest that you either change the interface or use a set of wrapper methods that will return the native .Net data types. One approach could be two readonly properties. One will return true if the nullable entity contains data and they other property will return the actual data.
    _________________
    Niels-Henrik Sejthen
    Senior Software Developer
    Microsoft Dynamics NAV

    The information in this post is provided "AS IS" with no warranties, and confers no rights. This post does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion.
  • Cem_KaraerCem_Karaer Member Posts: 281
    Well..
    Having no support is not helpful I think. Is there any official statement in any technical Microsoft document that nullable type usage is not supported in NAV? I think there is not. If there were, we wouldn't lose much time to find a convenient way to circumvent that problem, would we?
    Cem Karaer @ Pargesoft
    Dynamics NAV Developer since 2005
  • nhsejthnhsejth Member, Microsoft Employee Posts: 34
    I have not seen requests for nullable types in the interop interface for the C/AL langauge until now, but please file a feature request using the normal channels if its important for your business cases. The .Net data types are reflect loaded, which means that these special cases must be handled separately if they should have native support in the NAV runtime. The original 2009 .Net documentation show some examples about use of generics that migth be useful (http://msdn.microsoft.com/en-us/library/gg502500.aspx).

    I will not say that it cannot be done if requested, but will have some concerns about performance.
    _________________
    Niels-Henrik Sejthen
    Senior Software Developer
    Microsoft Dynamics NAV

    The information in this post is provided "AS IS" with no warranties, and confers no rights. This post does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion.
  • andrewtandrewt Member Posts: 73
    Cem, I fully agree.
    I haven't found anything saying NAV 2013 R2 is not supporting nullable .NET datatypes. Even if this would be the case, I think MS would have to change their minds because outside NAV, in .NET it is common usage to have nullable datatypes. For instance, data packages retrieved from foreign web services may contain nullable datatypes. Of cause it could be possible to convert those data types into non-nullables before bringing them into the NAV environment, but that would cause extra efforts in terms of development, runtime payload etc.
    In my opinion, NAV .NET interop should support nullables, simply because .NET HAS those datatypes.

    In the meantime, I opened a support case at Microsoft, at least they confirmed that they are able to reproduce the problem.
    So let's see what they come up with - will keep you guys updated.

    Cheers
    Andrew
  • andrewtandrewt Member Posts: 73
    Just a short and final update to this topic:
    After some discussion back and forth with Microsoft, I received a pre-patch for NAV 2013R2 which actually resloved the issue I had about not getting nullable values from a .NET web service into NAV. CU version is 7.10.38455. Not sure what exactly they fixed, but with the suggestion from Cem, using a variant as NAV datatype where to assign nullable .NET decimal to, I am now able to bring nullable decimals from .NET into NAV.

    I did also test with NAV 2015 (8.00.38457), which worked as well out of the box.

    Cheers
    Andrew
Sign In or Register to comment.