Hassam
Hassam

Reputation: 69

WCF With XmlSerializer

I have an XML string like

<?xml version="1.0"?>
<FullServiceAddressCorrectionDelivery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <AuthenticationInfo  xmlns="http://www.usps.com/postalone/services/UserAuthenticationSchema">
    <UserId xmlns="">FAPushService</UserId>
    <UserPassword xmlns="">Password4Now</UserPassword>
  </AuthenticationInfo>
  <FullServiceAddressCorrectionDelivery d2p1:MessageGroupID="3599" d2p1:TotalMessageCount="1" d2p1:MessageSerialNumber="1" xmlns:d2p1="http://idealliance.org/Specs/mailxml10.0/mailxml_defs" xmlns="http://idealliance.org/Specs/mailxml10.0A/mailxml_dd">
    <SubmittingParty d2p1:MaildatUserLicense="USPS" />
    <SubmittingSoftware d2p1:SoftwareName="PostalOne" d2p1:Vendor="USPS" d2p1:Version="27.0" />
    <PushMessageID>3599001</PushMessageID>
  </FullServiceAddressCorrectionDelivery>
</FullServiceAddressCorrectionDelivery>

and service contract like

[ServiceContract(Namespace = http://www.usps.com/postalone/services/DataDistributionPushMailXML10A")]
public interface DataDistributionPushMailXML10APortType
{
    [OperationContract]
    [XmlSerializerFormat]
    FullServiceAddressCorrectionDelivery PushFullServiceAddressCorrectionDelivery(FullServiceAddressCorrectionDelivery obj);
}

// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract(Name = "FullServiceAddressCorrectionDelivery", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
[Serializable]
public class FullServiceAddressCorrectionDelivery
{
    [XmlElement("AuthenticationInfo", 
     Namespace = "http://www.usps.com/postalone/services/UserAuthenticationSchema")]
    [DataMember]
    public AuthenticationInfoType AuthenticationInfo
    {
        get;
        set;
    }

    [XmlElement("FullServiceAddressCorrectionDelivery",
     Namespace = "http://idealliance.org/Specs/mailxml10.0A/mailxml_dd")]
    [DataMember]
    public FullServiceAddressCorrectionDelivery1 FullServiceAddressCorrectionDelivery1
    {
        get;
        set;
    }
}

[DataContract]
[Serializable]
public class AuthenticationInfoType
{
    [DataMember]
    [XmlElement("UserId", Namespace = "")]
    public string UserId
    {
        get;
        set;
    }

    [DataMember]
    [XmlElement("UserPassword", Namespace = "")]

    public string UserPassword
    {
        get;
        set;
    }
}

[DataContract]
[Serializable]
public class ParticipantIDType
{
    private string _maildatUserLicense;

    [DataMember]
    [XmlAttribute("MaildatUserLicense", 
    Namespace ="http://idealliance.org/Specs/mailxml10.0/mailxml_defs")] 
    public string MaildatUserLicense
    {
        get
        {
            return this._maildatUserLicense;
        }
        set
        {
            this._maildatUserLicense = value;
        }
    }
}

[DataContract]
[Serializable]
public class FullServiceAddressCorrectionDelivery1
{
    [DataMember]
    [XmlElement("SubmittingParty")]
    public ParticipantIDType SubmittingParty
    {
        get;
        set;
    }

    [DataMember]
    [XmlElement("PushMessageID")]
    public string PushMessageID
    {
        get;
        set;

    }
}

On deserializing, I use XmlSerializer:

FullServiceAddressCorrectionDelivery objAddressCorrectionDelivery = 
  new  FullServiceAddressCorrectionDelivery();
byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(this.richTextBox1.Text);
MemoryStream stream = new MemoryStream(byteArray);
XmlSerializer Xs = new XmlSerializer(typeof(FullServiceAddressCorrectionDelivery));
var result = (FullServiceAddressCorrectionDelivery)Xs.Deserialize(stream);

Problem is while deserializing: my FullServiceAddressCorrectionDelivery object is successfully deserialized, but it contains null in its PushMessageID property. What have I missed?

Upvotes: 2

Views: 3515

Answers (1)

GTG
GTG

Reputation: 4954

The reason for this is that your FullServiceAddressCorrectionDelivery1 class (the inner FullServiceAddressCorrectionDelivery) doesn't contain a definition of the SubmittingSoftware element, but the XML contains it. What seems to happen then is that the XML deserializer can read the properties before SubmittingSoftware, but all properties after SubmittingSoftware are set to null. I have experienced this myself in deserializing XML from web services.

Typically this will happen if you create a client using version 1 of your web service and then you create version 2 of your web service, having one more property in your datacontract. In those cases, you need to ensure that the new property is placed last (at the bottom) in your XML.

Upvotes: 2

Related Questions