none
CollectionDataContract with the extra property RRS feed

  • Question

  • I am working with the list in the WCF. I want to pass the list between the client and server with the one extra property inside it.

    Needed Output:

    <NumbersList>
        <Count>2</Count> //Extra property to parse
        <Number>1</Number>
        <Number>2</Number>
    </NumbersList>

    And I wrote the below code to achieve that.

    [MessageContract]
    public class RequestResponse
    {
        [MessageBodyMember(Name = "NumbersList")]
        public NumbersList NumbersList;
    }
    
    [DataContract]
    public class NumbersList
    {
        [DataMember]
        public int Count { get; set; }
    
        [DataMember]
        public Number Number { get; set; }
    }
    
    [CollectionDataContract(ItemName = "Number")]
    public class Number : Collection<int>
    {        
    }

    And I got the output like this:

    <NumbersList>
        <Count>2</Count>
        <Number>
            <Number>1</Number>
            <Number>2</Number>
        </Number>
    </NumbersList>

    One more try:

    If I put the Count property decorated with the DataMember directly inside the CollectionDataContract than the however WCF omit that property.

    [MessageContract]
    public class RequestResponse
    {
        [MessageBodyMember(Name = "NumbersList")]
        public Number NumbersList;
    }
    
    [CollectionDataContract(ItemName = "Number")]
    public class Number : Collection<int>
    {
        [DataMember]
        public int Count { get; set; } // This will be omited...
    }

    Than it can be give the output like this:

    <NumbersList>
        <Number>
            <Number>1</Number>
            <Number>2</Number>
        </Number>
    </NumbersList>

    Can any one help me to get the output like this:

    <NumbersList>
        <Count>2</Count>
        <Number>1</Number>
        <Number>2</Number>
    </NumbersList>

    Thanks & Regards,


    Monday, October 24, 2016 6:21 AM

Answers

  • Hi Kalpesh,

    There are two serialize class in WCF, DataContractSerializer and XmlSerializer, XmlSerializer allows much more control over the resulting XML and supports much more of the XML XSD standard.

    For your requirement, I suggest you follow below steps.

    1. Add XmlSerializerFormat to WCF Service interfance.

        [ServiceContract]
        [XmlSerializerFormat]
        public interface IService1
        {
            [OperationContract]
            Group GetGroup();
        }

    2. Define the class

        [DataContract]
        [XmlRoot(ElementName = "NumbersList")]
        public class NumbersList
        {
            [XmlElement(ElementName = "Count")]
            public int Count { get; set; }
            [XmlElement(ElementName = "Number")]
            public List<int> Number { get; set; }
        }
        public class Group
        {
            [XmlElement(ElementName = "NumbersList")]
            public NumbersList ns { get; set; }
        }

    3. WCF method

            public Group GetGroup()
            {
                NumbersList nl = new NumbersList();
                Number n1 = new Number { value = 1 };
                Number n2 = new Number { value = 2 };
                List<int> l = new List<int> { 1, 2 };
                nl.Number = l;
                nl.Count = 2;
                Group g = new Group {  ns=nl};
                return g;
            }

    4. Here is the output.

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
      <s:Header />
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <GetGroupResponse xmlns="http://tempuri.org/">
          <GetGroupResult>
            <NumbersList>
              <Count>2</Count>
              <Number>1</Number>
              <Number>2</Number>
            </NumbersList>
          </GetGroupResult>
        </GetGroupResponse>
      </s:Body>
    </s:Envelope>

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Kalpesh Rajai Wednesday, October 26, 2016 8:27 AM
    Wednesday, October 26, 2016 6:40 AM

All replies

  • What is the count for, since a List<T> has a public Count() method that tells one how many items are in the List<T>, which is zero based?
    Monday, October 24, 2016 11:00 PM
  • Thanks @DA924x,

    Count is one extra field to my class which I added. It is not related with the List.Count and it is not the List.Count.

    That, Count property is sent by the client which tell us the how many number will be in the list and also while return we tell the client that how many numbers in the list by the Count field.

    Actually I does not overridden the List.Count property and is independent field of the class.

    Thanks & Regards,

    Kalpesh Rajai 

    Tuesday, October 25, 2016 3:53 AM
  • Hi Kalpesh,
    How did you check the output result? It would be helpful if you could share us detailed steps that you run the service and check the result. I suggest you try something like below for the class:

        [XmlRoot(ElementName = "NumbersList")]
        public class NumbersList
        {
            [XmlElement(ElementName = "Count")]
            public int Count { get; set; }
            [XmlElement(ElementName = "Number")]
            public List<int> Number { get; set; }
        }

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, October 25, 2016 6:53 AM
  • Hi Edward Z,

    Thanks for your reply.

    How I am calling the WCF Service ?

    First I am running my WCF service in the WCF Test client which comes with the Visual Studio.

    After that I created the one Console Application (WCF Client) that call the WCF's Method 

    string endpoint = "http://localhost:62854/Service1.svc"; //Specify Your Service Endpoint
    
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endpoint);
    
    request.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
    
    request.ContentType = @"text/xml; charset=""utf-8""";
    request.Method = "POST";
    request.Headers.Add("SOAPAction", "http://tempuri.org/IService1/GetData2"); //Specify Method to Execute
    string payload = @"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
                          <s:Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                            <RequestResponse xmlns=""http://tempuri.org/"">
                              <NumbersList>
                                    <Count>3</Count>
                        			<Number>1</Number>
                        			<Number>2</Number>
                        			<Number>3</Number>
                        	  </NumbersList>
                            </RequestResponse>
                          </s:Body>
                        </s:Envelope>";
    
    byte[] byteArray = Encoding.UTF8.GetBytes(payload);
    request.ContentLength = byteArray.Length;
    
    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(byteArray, 0, byteArray.Length);
        requestStream.Close();
    
        HttpWebResponse response = null;
        try
        {
            response = (HttpWebResponse)request.GetResponse();
        }
        catch (WebException ex)
        {
            response = (HttpWebResponse)ex.Response;
        }
    
        Console.WriteLine(string.Format("HTTP/{0} {1} {2}\n", response.ProtocolVersion, (int)response.StatusCode, response.StatusDescription));
    
        using (Stream responseStream = response.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(responseStream))
            {
                string str = reader.ReadToEnd();
                string str1 = str.Replace("<", System.Environment.NewLine + " <");
                Console.WriteLine(str1);
                System.IO.File.WriteAllText(@"WriteText.xml", str);
            }
        }
        response.Close();
    }
    Console.ReadLine();

    I also tired your code but however it does not work. Your code created the object of NumbersList inside the action method, but all the properties of it null like Count and List<Number>.

    By using the help of IXmlSerializable, I done my task successfully. But the problem is that I have to manually read and write from and to the XML.

    Can you please help me to tackle down this problem in some another way, where serialization and deserialization done automatically.

    Thanks & Regards,

    Kalpesh Rajai

    Tuesday, October 25, 2016 7:51 AM
  • Hi Kalpesh,

    There are two serialize class in WCF, DataContractSerializer and XmlSerializer, XmlSerializer allows much more control over the resulting XML and supports much more of the XML XSD standard.

    For your requirement, I suggest you follow below steps.

    1. Add XmlSerializerFormat to WCF Service interfance.

        [ServiceContract]
        [XmlSerializerFormat]
        public interface IService1
        {
            [OperationContract]
            Group GetGroup();
        }

    2. Define the class

        [DataContract]
        [XmlRoot(ElementName = "NumbersList")]
        public class NumbersList
        {
            [XmlElement(ElementName = "Count")]
            public int Count { get; set; }
            [XmlElement(ElementName = "Number")]
            public List<int> Number { get; set; }
        }
        public class Group
        {
            [XmlElement(ElementName = "NumbersList")]
            public NumbersList ns { get; set; }
        }

    3. WCF method

            public Group GetGroup()
            {
                NumbersList nl = new NumbersList();
                Number n1 = new Number { value = 1 };
                Number n2 = new Number { value = 2 };
                List<int> l = new List<int> { 1, 2 };
                nl.Number = l;
                nl.Count = 2;
                Group g = new Group {  ns=nl};
                return g;
            }

    4. Here is the output.

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
      <s:Header />
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <GetGroupResponse xmlns="http://tempuri.org/">
          <GetGroupResult>
            <NumbersList>
              <Count>2</Count>
              <Number>1</Number>
              <Number>2</Number>
            </NumbersList>
          </GetGroupResult>
        </GetGroupResponse>
      </s:Body>
    </s:Envelope>

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Kalpesh Rajai Wednesday, October 26, 2016 8:27 AM
    Wednesday, October 26, 2016 6:40 AM
  • Hi Edward Z,

    Thank you so much for the code.

    It's work like the charm.....

    Thanks & Regards,

    Kalpesh Rajai.

    Wednesday, October 26, 2016 8:27 AM
  • Hi Edward Z,

    After using your code it solved my problem.

    In my WCF project I have too many DataContract and MessageContract. Wher I used the isRequired property to true. So if user does not send the isRequired property than it will throw the exception.

    But however, Append this solution to my project, Now isRequired property is not working. After doing the R&D and I got the XmlSerializerFormat does not allow the isRequired property to do it's task.

    Can you please help me? What can I do in this problem? Because I does not found anything relate to this on the web.

    Thanks & Regards,

    Kalpesh Rajai

    Thursday, October 27, 2016 8:13 AM
  • Hi Kalpesh,

    >>After doing the R&D and I got the XmlSerializerFormat does not allow the isRequired property to do it's task.

    Do you need the same xml format for the object which needs isRequired? If not, I think you could add XmlSerializerFormat to the special method instead of on the top of public interface IService1.

    If it did not meet your requirement, I would suggest you post a new thread for this new issue, and then we could focus on this special issue. More detailed steps to reproduce your issue would be much helpful in this new thread.

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, October 27, 2016 9:54 AM