none
WCF REST Post method : Deserializing a base class

    Question

  • I have the following class structure:

    [DataContract(Namespace = "")]
    public class MyBase
    {
            [DataMember]
            public Int32 CreatedBy;
            [DataMember]
            public string CreatedProc;

           //Constructor which initializes the fields...
     }

    [DataContract(Namespace = "")]
    public class Person:MyBase
    {
            [DataMember]
            public Int32 Id;
            [DataMember]
            public string FirstNm;
            [DataMember]
            public string LastNm;

           //Constructor which calls the base constructor and  initializes the fields...
    }

    And my service is like this:

        [ServiceContract(Namespace = "")]
        public interface IPersonManager
        {
           
            [OperationContract]
            [WebInvoke(Method = "POST", UriTemplate = "/person", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json)]
            Int32 UpdatePerson(Person p);
        }

    And from my client I am sending an xml in this format:
    <Person>
        <Id>2</Id>
        <FirstNm>Mike</FirstNm>
        <LastNm>Shape</LastNm>
        <CreatedBy>0</CreatedBy>
        <CreatedProc>TEST</CreatedProc>   
    </Person>

    In the PersonMgr concrete class i have the following:

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class PersonManager:IPersonManager
    {
             public Int32 UpdatePerson(Person p)
            {
                --------  // Code which uses person object
            }
    }

    In the person object above, I am able to acess the person class fields like first name and last name but not any of the base class fields like CreatedBy and CreatedProc.

    How can I get these fields populated?  I have tried [KnownType] attribute in the person class with out any success.

    Thanks for the help.
    Wednesday, September 23, 2009 2:50 PM

Answers

  • I think the problem is related to the serialization order. It try to deserialize, in order, first the base class elements and then the sub class elements. Try to use the Order property of DataMemberAttribute to define the correct serialization order.

    HTH

    Fabio Cozzolino Blogs: http://dotnetside.org/blogs/fabio http://weblogs.asp.net/fabio
    • Marked as answer by krish KG Wednesday, September 23, 2009 8:02 PM
    Wednesday, September 23, 2009 4:25 PM
  • Like Fabio said, use the order property  and then in you operation cast the Person to the MyBase class to use the members.
    MyBase base = p as MyBase; 

    [DataContract(Namespace = "")]
        public class Base
        {
            [DataMember(Order=1)]
            public int CreatedBy;
            [DataMember(Order = 2)]
            public string CreatedProc;
        }
    
    
        [DataContract(Namespace="")]
        public class Person: Base   
        {
            [DataMember(Order = 3)]
            public int Id;
            [DataMember(Order = 4)]
            public string FirstNm;
            [DataMember(Order = 5)]
            public string LastNm;
    
        }
    Request:

    <Person>
      <CreatedBy>12</CreatedBy>
      <CreatedProc>TEST</CreatedProc>
      <Id>2</Id>
      <FirstNm>Mike</FirstNm>
      <LastNm>Shape</LastNm>
    </Person>


    Amit Sharma
    • Marked as answer by krish KG Wednesday, September 23, 2009 8:03 PM
    Wednesday, September 23, 2009 4:49 PM
    Moderator

All replies

  • I think the problem is related to the serialization order. It try to deserialize, in order, first the base class elements and then the sub class elements. Try to use the Order property of DataMemberAttribute to define the correct serialization order.

    HTH

    Fabio Cozzolino Blogs: http://dotnetside.org/blogs/fabio http://weblogs.asp.net/fabio
    • Marked as answer by krish KG Wednesday, September 23, 2009 8:02 PM
    Wednesday, September 23, 2009 4:25 PM
  • Like Fabio said, use the order property  and then in you operation cast the Person to the MyBase class to use the members.
    MyBase base = p as MyBase; 

    [DataContract(Namespace = "")]
        public class Base
        {
            [DataMember(Order=1)]
            public int CreatedBy;
            [DataMember(Order = 2)]
            public string CreatedProc;
        }
    
    
        [DataContract(Namespace="")]
        public class Person: Base   
        {
            [DataMember(Order = 3)]
            public int Id;
            [DataMember(Order = 4)]
            public string FirstNm;
            [DataMember(Order = 5)]
            public string LastNm;
    
        }
    Request:

    <Person>
      <CreatedBy>12</CreatedBy>
      <CreatedProc>TEST</CreatedProc>
      <Id>2</Id>
      <FirstNm>Mike</FirstNm>
      <LastNm>Shape</LastNm>
    </Person>


    Amit Sharma
    • Marked as answer by krish KG Wednesday, September 23, 2009 8:03 PM
    Wednesday, September 23, 2009 4:49 PM
    Moderator
  • Thanks Fabio and Amit. That worked.......
    Wednesday, September 23, 2009 8:04 PM