views:

391

answers:

4

Hello everyone,

I am using VSTS 2008 + .Net + C# 3.5 to develop WCF service (self-hosted as a Windows Service). From client side, I am using ChannelFactory to connect to WCF service. My confusion is, when I change client side code from "public string response" to "public string responseAliasName", the value of responseAliasName is null. But when change back to variable name response, the response value is correct (value is "hi WCF").

My confusion is, I think variable name should not matter as long as the layout is the same from client and server side. Any ideas what is wrong?

Server side code:

namespace Foo
{
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
    [ServiceContract]
    public interface IFoo
    {
        [OperationContract]
        FooResponse Submit(string request);
    }

    [DataContract]
    public class FooResponse
    {
        [DataMember]
        public string response;
    }
}

namespace Foo
{
    // NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
    public class FooImpl : IFoo
    {
        public FooResponse Submit(string request)
        {
            FooResponse foo = new FooResponse();
            foo.response = "hi WCF";
            return foo;
        }
    }
}

Client side code:

namespace Foo
{
    // NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
    [ServiceContract]
    public interface IFoo
    {
        [OperationContract]
        FooResponse Submit(string request);
    }

    [DataContract]
    public class FooResponse
    {
        [DataMember]
        // public string responseAliasName;
        public string response;
    }
}


namespace FooTestClient1
{
    class Program
    {
        static void Main(string[] args)
        {
            ChannelFactory<IFoo> factory = new ChannelFactory<IFoo>(
               "IFoo");
            IFoo f = factory.CreateChannel();
            FooResponse response = f.Submit("Hi!");

            return;
        }
    }
}

thanks in advance, George

+1  A: 

No, the member name is included in the serialization. If you change it on the client side, it can't deserialize back into that member.

David M
+1  A: 

you can use

[DataContract(Name="ResponseAliasName")]
public string response;

on Server side and it will work as you expect, DataContract by default uses field or property name to serialize data, and the server can't find correct data

ArsenMkrt
Your solution works, cool! Thanks ArsenMkrt!
George2
A: 

George, why not just use "Add Service Reference" to create your client? As you can see, it's dangerous to create the client-side service contracts by hand.

John Saunders
A: 

Hi George2

My confusion is, when I change client side code from "public string response" to "public string responseAliasName", the value of responseAliasName is null. But when change back to variable name response, the response value is correct (value is "hi WCF"). My confusion is, I think variable name should not matter as long as the layout is the same from client and server side. Any ideas what is wrong?

The variable name that you use locally in your client is totally irrelevant - the server knows nothing about that. Given your code snippet from the client:

ChannelFactory<IFoo> factory = new ChannelFactory<IFoo>("IFoo");
IFoo f = factory.CreateChannel();
FooResponse response = f.Submit("Hi!");

This will work - no problem:

FooResponse myResponseVar1 = f.Submit("Hi!");

and so will this:

FooResponse someReallyCleverVariableNameWhateverItMightBe = f.Submit("Hi!");

But the DataContract of course is a shared element that the service and client have to agree on! You cannot locally change the names of the elements in the data contract - after all, that's what really describes how your calls are going to be turned into an XML message, and these bits and pieces have to stay in sync between the server and the client in order for the client to be able to turn the message received from the server back into an object for you to use.

The ServiceContract and the DataContract must be the same on both ends - that's the basic requirement, otherwise, pretty much nothing goes at all.

Marc

marc_s