为什么我在wcf反序列化时得到空数据?

时间:2012-07-18 14:27:31

标签: wcf deserialization nettcpbinding

我有一个系统,我在Windows和嵌入式系统之间通过不同的点到点通信通道交换消息,并且已经完成所有这些,因为非常标准的自定义序列化/反序列化功能几乎完全是手工完成的,因为那样可以轻松地在Windows端的C#和嵌入式的C之间移植。

现在我想添加一个在网络上的PC之间进行通信的块。而不是做另一批相同的东西,使用TcpClient / TcpListener并跟踪重叠的消息和响应,我决定看看WCF。

在这里查看了很多消息,在其他地方查看了文档等之后,我想出了一个非常简单的应用程序来交换消息,服务器包含一个获取并返回接口实例的函数,而不是一个固定的类。即使该示例只有一种消息 - 因此只使用KnownType和ServiceKnownType属性设置了一种类型,我想可以发送几十种不同类型的消息,我希望能够添加它们随着事情的发展,相当容易。

虽然代码没有生成错误,但是在远端实例化的对象没有发送的数据。我已经尝试了数据包嗅探,看看我是否可以确认数据实际上在线上,但我无法理解有线协议。所以我不知道数据是在传输中还是在服务器中消失在客户端中。如果我更改代码直接使用TestMessageType的实例而不是使用接口,它可以正常工作。

解决方案由三个项目组成; “类型”程序集,然后是引用该程序集的客户端和服务器控制台应用程序。类型程序集包含此代码;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace WCF_TCP_Sandpit
{

    public interface ITestInterface
    {
        Int64 I64Value {get; set;}
    }

    [ServiceContract]
    public interface IServer
    {
        [OperationContract]
        [ServiceKnownType(typeof(TestMessageType))]
        ITestInterface Test(ITestInterface msg);
    }

    [DataContract]
    [KnownType(typeof(TestMessageType))]
    public class TestMessageType : ITestInterface
    {
        Int64 _v1;

        public long I64Value
        {
            get { return _v1;  }
            set { _v1 = value; }
        }

        public static Type[] KnownTypes()
        {
            return new Type[] { typeof(TestMessageType) };   
        }
    }
}

服务器代码是

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using WCF_TCP_Sandpit;
using System.Runtime.Serialization;

namespace Server
{  
    class Program : IServer
    {
        static void Main(string[] args)
        {
            using (ServiceHost serviceHost = new ServiceHost(typeof(Program), new Uri("net.tcp://127.0.0.1:9000")))
            {
                serviceHost.Open();

                // The service can now be accessed.
                Console.WriteLine("The service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();
            }

        }

        #region IServer Members

        public ITestInterface Test(ITestInterface msg)
        {
            ITestInterface reply = new TestMessageType();

            reply.I64Value = msg.I64Value * 2;
            return reply;
        }

        #endregion 
    }
}

,客户端代码是

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCF_TCP_Sandpit;

using System.ServiceModel;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            ITestInterface m,r;
            int i = 0;
            ChannelFactory<WCF_TCP_Sandpit.IServer> srv
                = new ChannelFactory<WCF_TCP_Sandpit.IServer>
                (new NetTcpBinding(), "net.tcp://127.0.0.1:9000");

            WCF_TCP_Sandpit.IServer s;
            s = srv.CreateChannel();

            while (true)
            {
                m = new WCF_TCP_Sandpit.TestMessageType();
                m.I64Value = i++;

                r = s.Test(m);

                Console.WriteLine("Sent " + m.I64Value + "; received " + r.I64Value);
                System.Threading.Thread.Sleep(1000);
            }
        }
    }
}

任何人都可以对出现问题的方法有所了解吗?

1 个答案:

答案 0 :(得分:0)

您是否需要DataMember属性上的I64Value属性?