none
Passing Null to WCF WebService (a published orchestration) RRS feed

  • Question

  •  

    We have a C# GUI application (VS2008/.NET 3.5)  that wants to pass nulls to certain fields (in order to eventually nullify a field in the database).

    This article seems to cover many good points - but leaves one hanging with no easy solution:
    http://bytes.com/forum/thread375805.html 

    When the C# consumes the web service (published orchestration), the proxy doesn't seem to have any allowance for nulls.

    For example, one of our decimal fields is defined in the proxy like this:

     

    [System.Runtime.Serialization.

    OptionalFieldAttribute()]

     

     

    private decimal CurrentGrossRateField;


            [System.Runtime.Serialization.DataMemberAttribute(Order=56)]
            public decimal CurrentGrossRate {
                get {
                    return this.CurrentGrossRateField;
                }
                set {
                    if ((this.CurrentGrossRateField.Equals(value) != true)) {
                        this.CurrentGrossRateField = value;
                        this.RaisePropertyChanged("CurrentGrossRate");
                    }
                }
            }

    In the schema used by the orchestration, the field is defined as minOccurs=0, maxOccurs=1, and Nillable= True
    What happens to the "Nillable=True"?  Does this not float over to the C# proxy somehow?

    Thanks,
    Neal Walters
    http://BizTalk-Training.com - Learn BizTalk faster

    Tuesday, September 9, 2008 8:24 PM

All replies

  • If you declare an interface with a nullable type then the proxy class will use System.Nullable as the type information in the proxy class. The WSDL would have Nillable=true for this case. For example, here is my test method:

     

    Code Snippet

    public string GetData(int? value)

    {

    return string.Format("You entered: {0}", value);

    }

     

     

    The generated schema is:

    Code Snippet

     

    <xs:element name="GetData">

    <xs:complexType>

    <xs:sequence>

    <xs:element minOccurs="0" name="value" nillable="true" type="xs:int" />

    </xs:sequence>

    </xs:complexType>

    </xs:element>

     

     

    Then in the generated proxy class you see:

     

    Code Snippet

    [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetData", ReplyAction="http://tempuri.org/IService1/GetDataResponse")]

    string GetData(System.Nullable<int> value);

     

     

    Thanks,

    Thursday, September 11, 2008 5:03 PM
    Moderator
  •  

    Hi Ben,

       I have a request and a response schema defined with BizTalk schema editor. The schema then becomes the receive/send of an orchestration, which in turn is published as a WCF service. 

       The proxy that is built when I consume the service does not generate nulllable fields.  However, a coworker of mine is doing a similar process, and his proxy has for instance OriginalBalance (decimal) and OriginalBalanceSpecified (bool). 

        We have yet to see why his proxy has the "Specified" suffix on most fields, and mine does not have any. 
    In the schema, the we both have decimal fields, with minOccurs=0 and have tried setting Nillable to both true and false, and that doesn't seem to effect the proxy.

     

        Here's more info (I'm double posting on two forums: http://www.biztalkgurus.com/forums/t/10662.aspx)

     

    Any other ideas appreciated.
    Thanks,

    Neal Walters

    Friday, September 12, 2008 4:05 PM
  • Hi a little thread bump,

    Me and a coworker have the following problem.

    A webservice contract with optional fields (minOccurs="0"). The server expects these field to be omitted if they do not contain valuable information.
    The contract has both value types and object types with the attribute minOccurs = 0.


    We create a webservice reference with the contract. When we use .NET 3.5 the value types are always supplied in the SOAP message. If we use 2.0 we get the extra properties (bool xSpecified) which we can set to false to omit the values.

    The problem with 3.5 only occurs with value types and not object types. We examined the generated code and noted that for object type we have the EmitDefaultValue = false specified which we do not have for value types. We tried to put EmitDefaultValue = false to the value type aswell. It does the trick but it will not allow us to send 0 (the default value). Here is the generated code in 3.5:

    [System.Runtime.Serialization.DataMemberAttribute(Order = 1)] 
    public long Id { 
     
       get { 
              return this.Id; 
       } 
       set { 
              if ((this.Id.Equals(value) != true)) { 
                   this.Id = value; 
                   this.RaisePropertyChanged("Id"); 
              } 
       } 
     
    [System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=2)] 
    public string Text { 
     
    get { 
         return this.TextField; 
     
    set { 
     
         if ((object.ReferenceEquals(this.TextField, value) != true)) { 
              this.Text = value; 
              this.RaisePropertyChanged("Text"); 
     
         } 
     
     

    This can be compared with the generated code from 2.0:
    /// <remarks/> 
    public long Id { 
        get { 
            return this.IdField; 
        } 
        set { 
            this.IdField = value; 
        } 
     
    /// <remarks/> 
    [System.Xml.Serialization.XmlIgnoreAttribute()] 
    public bool IdSpecified { 
        get { 
            return this.IdFieldSpecified; 
        } 
        set { 
            this.IdFieldSpecified = value; 
     
        } 
     
    /// <remarks/> 
    public string Text { 
        get { 
            return this.TextField; 
        } 
        set { 
            this.TextField = value; 
        } 
     


    We found this from MSDN about the EmitDefaultValue:

    http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.emitdefaultvalue.aspx


    Is there a way to be able to send 0 and omit the tag if we do not specify a value in .NET 3.5? In other words can we have the same, or similar, behavior in 3.5 as we had in 2.0?

    Regards,

    Ola Melin
    Friday, March 20, 2009 2:38 PM

  • >Is there a way to be able to send 0 and omit the tag if we do not specify a value ...
    I assume this is a typo because it is not possible, you want to send a value of 0 to a client but not have a tag emitted?

    Perhaps you meant you want to set a data member to zero or whatever the default value is for that type, and not emitted a tag, if the default value is used.  If this is the case, "EmitDefaultValue=false" is the way to go.  In order to get this attribute property in your generated code, you'll need to annotated the element as shown below.


             <xs:element minOccurs="0" name="Age" nillable="true" type="xs:int">
                <xs:annotation>
                   <xs:appinfo>
                      <DefaultValue EmitDefaultValue="false" xmlns="http://schemas.microsoft.com/2003/10/Serialization/"/>
                   </xs:appinfo>
                </xs:annotation>
             </xs:element>
    >It does the trick but it will not allow us to send 0 (the default value).
    Make sure minOccurs != 1 in the xsd file and IsRequired=True property is not set in code file.

    It is an error to have minOccurs = 1 and "EmitDefaultValue=false".


    HTH,
    An
    Thursday, July 9, 2009 7:03 PM