Search code examples
c#xmlwcf

WCF: Nested DataContract Values are null


I am writing a WCF service that accepts XML data. However when I consume the service, the parameters it receives have null value.

Here's my service contract:

[OperationContract]
        [ServiceKnownType(typeof(ECardPaymentModel))]
        [ServiceKnownType(typeof(TransactionInformation))]
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "ECardPayment")]
        string ECardPayment(ECardPaymentModel Payment);

The Data Contracts:

[DataContract(Name = "Payment", Namespace = "")]
    [Serializable]
    public class ECardPaymentModel
    {
        [DataMember(Name = "TransactionInfo")]
        public TransactionInformation TransactionInfo { get; set; }
    }

    [DataContract(Name = "TransactionInfo")]
    public class TransactionInformation
    {
        [DataMember(Name = "customer")]
        public string Customer { get; set; }

        [DataMember(Name = "transid")]
        public string TransID { get; set; }
    }

The XML that I use to call the service:

<Payment>
    <TransactionInfo>
           <customer>HD000083</customer>
           <transid>1001</transid>
    </TransactionInfo>
</Payment>

However, when the values I receive for Payment.TransactionInfo.Customer and Payment.TransactionInfo.TransID are both null.

I don't know where I am wrong. Because when I use flat objects, like

    [DataContract(Name = "Payment")]
    public class ECardPaymentModel
    {
        [DataMember(Name = "customer")]
        public string Customer { get; set; }

        [DataMember(Name = "transid")]
        public string TransID { get; set; }
    }

And XML as,

<Payment>
           <customer>HD000083</customer>
           <transid>1001</transid>
</Payment>

I receive correct values for Payment.Customer and Payment.TransID.


Solution

  • It looks like your TransactionInformation has a default xml namespace but you don't pass it for customer and transid.

    You should try to remove the default namespace by setting DataContract(..., Namespace = "") on TransactionInformation class like you did it ECardPaymentModel class.