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 Microsoft Dynamics NAV.
For example, the following code shows the schema for the two fields on this Customer Card web service:
Copy Code | |
---|---|
<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 Microsoft Dynamics NAV. The other field is a string because it is declared as a Text data type in Microsoft Dynamics NAV.
If both values are present, then the XML document should contain the following elements:
Copy Code | |
---|---|
<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:
Copy Code | |
---|---|
<Salesperson_Code>JR</Salesperson_Code> |
If the credit limit is zero, then the document should contain the following line:
Copy Code | |
---|---|
<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:
Copy Code | |
---|---|
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
:
Copy Code | |
---|---|
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
:
Copy Code | |
---|---|
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:
Copy Code | |
---|---|
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:
Copy Code | |
---|---|
salesOrder.Salesperson_Code = "JR"; |
To specify that there is no useful value in salesOrder.Salesperson_Code
, you should set it to null:
Copy Code | |
---|---|
salesOrder.Salesperson_Code = null; |
Example
Copy Code | |
---|---|
SalesOrder salesOrder = new SalesOrder(); salesOrder.Order_Date = DateTime.Today; salesOrder.Order_DateSpecified = true; salesOrder.Currency_Code = "SEK"; salesOrderService.Create(ref salesOrder); |