Isham Mohamed
Isham Mohamed

Reputation: 2789

WCF Unable to Parse SOAP Envelop, Only Getting Default Values

I have created a WCF server for a callback service. A remote machine is suppose to call this service with a defined envelop format and try to accomplish a task.

I have the following SOAP Envelop to be parsed in a WCF Service:

<s:Envelope
  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <ActivityId CorrelationId="e801930b-bf31-4509-b98a-96d106b5513f"
      xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">00000000-0000-0000-0000-000000000000
        
    </ActivityId>
  </s:Header>
  <s:Body>
    <Delivery
      xmlns="http://hsbdserver/calcula/v1">
      <info
        xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <Guid>5869a5c5-243e-11ed-4a4c-b14560d0fb70</Guid>
        <Name>Name</Name>
      </info>
      <items
        xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <Item>
          <Guid>43207e16-906e-d94a-86f6-753ae31092ef</Guid>
          <Name>c37fb62f-2729-244b-a082-4be80d952c1e.txt</Name>
          <ExtDocId i:nil="true"/>
          <NewUserId i:nil="true"
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
          <NewUserName i:nil="true"
            xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
            <NewWorkflow>Done</NewWorkflow>
            <PreviousUserId
              xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
              <a:guid>0e67f61a-d1c6-c448-a11c-82ee8428028a</a:guid>
            </PreviousUserId>
            <PreviousUserName
              xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
              <a:string>Nick</a:string>
            </PreviousUserName>
            <PreviousWorkflow>Progress</PreviousWorkflow>
            <Code>xkde</Code>
          </Item>
        </items>
      </Delivery>
    </s:Body>
  </s:Envelope>

The below is my C# implementation

[ServiceContract(Namespace = "http://hsbdserver/calcula/v1")]
public interface IServerCallback
{

  [OperationContract]
  void Delivery(Info info, Item[] items);
}


[DataContract]
public class Info
{
  Guid guid;
  string name;

  [DataMember]
  public Guid Guid
  {
    get { return guid; }
    set { guid = value; }
  }

  [DataMember]
  public string Name
  {
    get { return name; }
    set { name = value; }
  }
}

[DataContract]
public class Item
{
  Guid guid;
  string name;
  string extDocId;
  Guid[] newAssignedUserId;
  string[] newUserId;
  Workflow newWorkflow;
  Guid[] previousUserId;
  string[] previousUserName;
  Workflow previousWorkflow;
  string code;

  [DataMember]
  public Guid Guid
  {
    get { return guid; }
    set { guid = value; }
  }

  [DataMember]
  public string Name
  {
    get { return name; }
    set { name = value; }
  }

  [DataMember]
  public string ExtDocId
  {
    get { return extDocId; }
    set { extDocId = value; }
  }

  [DataMember]
  public Guid[] NewAssignedUserId
  {
    get { return newAssignedUserId; }
    set { newAssignedUserId = value; }
  }

  [DataMember]
  public string[] NewUserId
  {
    get { return newUserId; }
    set { newUserId = value; }
  }

  [DataMember]
  public Workflow NewWorkflow
  {
    get { return newWorkflow; }
    set { newWorkflow = value; }
  }

  [DataMember]
  public Guid[] PreviousUserId
  {
    get { return previousUserId; }
    set { previousUserId = value; }
  }

  [DataMember]
  public string[] PreviousUserName
  {
    get { return previousUserName; }
    set { previousUserName = value; }
  }

  [DataMember]
  public Workflow PreviousWorkflow
  {
    get { return previousWorkflow; }
    set { previousWorkflow = value; }
  }

  [DataMember]
  public string Code
  {
    get { return code; }
    set { code = value; }
  }
}

public enum Workflow
{
  Progress,
  Done
}

However the service is unable to interpret the SOAP envelop. I have a breakpoint at the beginning of Deliver method, it gets hit however the values seem default ones. For example GUIDs are just a bunch of zeros and the items array is empty as well.

What am I missing here? How should I make the C# class to reflect the SOAP envelop?

Upvotes: 0

Views: 82

Answers (1)

jdweng
jdweng

Reputation: 34421

Here are the classes for deserialize which should be the same for SOAP

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Globalization;

namespace ConsoleApplication49
{

    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(Envelope));
            Envelope envelope = (Envelope)serializer.Deserialize(reader);

        }
    }
    [XmlRoot(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public class Envelope
    {
        public Header Header { get; set; }
        public Body Body { get; set; }
    }
    public class Header
    {
        [XmlElement(Namespace = "http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics")]
        public ActivityId ActivityId { get; set; }
    }
    public class ActivityId
    {
        [XmlAttribute()]
        public string CorrelationId { get; set; }
        [XmlText]
        public string id { get; set; }
    }
    public class Body
    {
        [XmlElement(Namespace = "http://hsbdserver/calcula/v1")]
        public Delivery Delivery { get; set; }
    }
    public class Delivery
    {
        public Info info { get; set; }
        [XmlArray(ElementName = "items")]
        [XmlArrayItem(ElementName = "Item")]
        public List<Item> items { get; set; }
    }
    public class Info
    {
        public string Guid { get; set; }
        public string Name { get; set; }
    }
    public class Item
    {
        public string Guid { get; set; }
        public string Name { get; set; }
        public string ExtDocId { get; set; }
        public string NewUserId { get; set; }
        public string NewUserName { get; set; } 
        public string NewWorkflow { get; set; }
        public PreviousUserId PreviousUserId { get; set; }
        public PreviousUserName PreviousUserName { get; set; }
        public string PreviousWorkflow { get; set; }
        public string Code { get; set; }
    }
    public class PreviousUserId
    {
        [XmlElement(ElementName = "guid", Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")]
        public string Guid { get; set; }
    }
    public class PreviousUserName
    {
        [XmlElement(ElementName = "string", Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")]
        public string name { get; set; }
    }
}
 

Upvotes: -1

Related Questions