Using Properties with Visual Studio to Indicate the Presence of a Value in a Field

When you set a field to a value in the code for a web service client and then send the value back to the web service, such as when you use the Create Operationor the Update Operation, the field value is not actually updated to anything other than its default value. This issue can occur if you are using proxies that are generated by Visual Studio or the tools in the .NET Framework SDK. This topic describes the issue and shows how to avoid the problem.

Using Properties to Indicate the Presence of Values

The problem occurs because of the way proxies are autogenerated and the way the .NET Framework handles values in XML documents that are exchanged between the web service and the client. The issue is not specific to Dynamics NAV.

For example, the following code shows the schema for the two fields on this Customer Card web service:

<xsd:element minOccurs="0" maxOccurs="1" name="Credit_Limit_LCY" type="xsd:decimal" />   
<xsd:element minOccurs="0" maxOccurs="1" name="Salesperson_Code" type="xsd:string" />   

Both fields are optional, which means that they do not have to be present in the XML document. One field is declared as a Decimal data type in Dynamics NAV. The other field is a string because it is declared as a Text data type in Dynamics NAV.

If both values are present, then the XML document should contain the following elements:

<Credit_Limit_LCY>1000</Credit_Limit_LCY>   
<Salesperson_Code>JR</Salesperson_Code>   

But if there is no information about the credit limit, then the document should contain the following element:

<Salesperson_Code>JR</Salesperson_Code>   

If the credit limit is zero, then the document should contain the following line:

<Credit_Limit_LCY>0</Credit_Limit_LCY>   

For the decimal type and all .NET Framework value types, you can handle this state in the proxy objects by using a Boolean *Specified property:

if (salesOrder.Credit_Limit_LCYSpecified)  
    there is a value present in salesOrder.Credit_Limit_LCY  
else   
    there is no useful value in salesOrder.Credit_Limit_LCY  

If you assign a non-default value in the value type, then you should confirm this by setting the accompanying Boolean *Specified property to true:

salesOrder.Credit_Limit_LCY = 1000;  
salesOrder.Credit_Limit_LCYSpecified = true;  

To specify that there is no meaningful value in the salesOrder.Credit_Limit_LCY value type, set the accompanying Boolean *Specified property to false:

salesOrder.Credit_Limit_LCYSpecified = false;  

The value in the salesOrder.Credit_Limit_LCY value type will now be disregarded.

.NET Framework reference types, such as the String class, are handled differently because .NET Framework declarations that are based on those types can be null, which means that they can have an explicit expression of no value present:

if (salesOrder.Salesperson_Code != null)  
    there is a value present in salesOrder.Salesperson_Code  
else   
    there is no value in salesOrder.Salesperson_Code  

If you assign a value, then you implicitly also define it as present:

salesOrder.Salesperson_Code = "JR";  

To specify that there is no useful value in salesOrder.Salesperson_Code, you should set it to null:

salesOrder.Salesperson_Code = null;  

Example

SalesOrder salesOrder = new SalesOrder();  
salesOrder.Order_Date = DateTime.Today;  
salesOrder.Order_DateSpecified = true;  
salesOrder.Currency_Code = "SEK";  

salesOrderService.Create(ref salesOrder);