Search code examples
wcfmessage

WCF: The issue with using System.ServiceModel.Channels.Message class?


I'm trying to use WCF service with raw messages.

1) WCF service code:

[DataContract]
public class Person
{
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string LastName { get; set; }
}

public static List<Person> CreateEmployees()
{
    List<Person> lstPersons = new List<Person>()
    {
        new Person { Id = 1, FirstName = "Andrey", LastName = "Andreyev" },
        new Person { Id = 2, FirstName = "Sergey", LastName = "Sergeyev" }
    };

    return lstPersons;
}

[ServiceContract]
public interface ITestService
{
    [OperationContract(Action = TestService.RequestAction, ReplyAction = TestService.ReplyAction)]
    Message GetPersonById(Message id);
}

public class TestService : ITestService
{
    public const String ReplyAction = "http://localhost:4249/Message_ReplyAction";
    public const String RequestAction = "http://localhost:4249/Message_RequestAction";

    public Message GetPersonById(Message id)
    {
        string firstName = Employees.CreateEmployees().First(e => e.Id == id.GetBody<int>()).FirstName;
        Message response = Message.CreateMessage(id.Version, ReplyAction, firstName);
        return response;
    }
}

2) Client code:

static void Main(string[] args)
{
    TestServiceClient client = new TestServiceClient();
    String RequestAction = "http://localhost:4249/Message_RequestAction";
    int value = 1;
    Message request = Message.CreateMessage(MessageVersion.Default, RequestAction, value);
    Message reply = client.GetPersonById(request);
    string firstName = reply.GetBody<string>();

    Console.WriteLine(firstName);
    client.Close();
}

When I run the client with: int value = 1 everything works fine. But, when I use: int value = 2 I get the following error:

System.Runtime.Serialization.SerializationException was unhandled Message="Error in line 1 position 276. Expecting element 'string' from namespace 'http://schemas.microsoft.com/2003/10/Serialization/'.. Encountered 'Element' with name 'Fault', namespace 'http://www.w3.org/2003/05/soap-envelope'. " Source="System.Runtime.Serialization" StackTrace: at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName) at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName) at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader) at System.ServiceModel.Channels.Message.GetBody[T](XmlObjectSerializer serializer) at System.ServiceModel.Channels.Message.GetBodyT at ClientTestService.Program.Main(String[] args) in E:\Projekti\WCF\Parus\ClientTestService\ClientTestService\Program.cs:line 22 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:

At line:

string firstName = reply.GetBody<string>();

The service is started and I've added the service reference through "Add Service Reference..." in VS2008. I use .NET Framework 3.5.

I'm not sure why I'm getting this error.

When I don't use Message class everything works fine. I mean on this:

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    Person GetPersonById(int id);
}

public class TestService : ITestService
{
    public Person GetPersonById(int id)
    {
        Person person = Employees.CreateEmployees().First(e => e.Id == id);
        return person;
    }
}

2) Client code:

static void Main(string[] args)
{
    TestServiceClient client = new TestServiceClient();
    int value = 1;
    Person person = client.GetPersonById(value);

    Console.WriteLine(person.FirstName);
    client.Close();
}

I would be really thankful if somebody can help.


Solution

  • Message reply = client.GetPersonById(request); 
    if(reply.IsFault)
      throw new GoransException(reply.toString());
    string firstName = reply.GetBody<string>();
    //...