0

シリアル化可能なオブジェクトのインスタンスをクライアントに渡そうとしていますが、サーバーで失敗するという問題を示す非常に単純なサーバーおよびクライアント コンソール アプリを作成しました。

何が足りないの?? 私は現在、DataContracts を使用してサービス指向であることを心配していません。コードがそのままの状態で EJob をクライアントに渡さない理由を理解しようとしているだけです (ただし、「Hello from the server」メッセージを呼び出します)。

どうもありがとう。

編集

EJob クラスを DataContract 属性 (以下のように) でデコレートしても、まだ機能しません - クライアントで受け取ったオブジェクトの LastName が null に設定されています?????

[DataContract]
public class EJob
{
    [DataMember]
    public string LastName = "Smith";
}

サーバ

namespace testServer
{
    [ServiceContract()]
    public interface IRemoteClient
    {
        [OperationContract]
        void SayHi(string msg);

        [OperationContract]
        void ProcessJob(EJob job);
    }

    [Serializable()]
    public class EJob
    {
        public string LastName = "Smith";
    }

    class Program
    {
        static void Main(string[] args)
        {
            MngrServer.SendJob();
        }
    }

    public class MngrServer
    {
        public static void SendJob()
        {
            try
            {
                // send this off to the correct exe
                NetTcpBinding binding = new NetTcpBinding(SecurityMode.None, true);

                string address = string.Format("net.tcp://localhost:33888/BatchMananger/client");
                EndpointAddress epa = new EndpointAddress(address);

                // create the proxy pointing to the correct exe
                IRemoteClient clientProxy = ChannelFactory<IRemoteClient>.CreateChannel(binding, epa);

                clientProxy.SayHi("Hello from server");  <-- THIS WORKS FINE

                EJob job = new EJob { LastName = "Janssen" };

                clientProxy.ProcessJob(job);             <-- THIS RAISES AN EXCEPTION see below...
            }
            catch (Exception ex)
            {
                string msg = ex.Message;

                //The formatter threw an exception while trying to deserialize the message: There was an error while 
                //trying to deserialize parameter http://tempuri.org/:job. The InnerException message was ''EndElement' 'job' 
                //from namespace 'http://tempuri.org/' is not expected. Expecting element 'LastName'.'.  
            }

        }
    }

}

クライアント

namespace testClient
{
    [ServiceContract()]
    public interface IRemoteClient
    {
        [OperationContract]
        void SayHi(string msg);

        [OperationContract]
        void ProcessJob(EJob job);
    }

    [Serializable()]
    public class EJob 
    {
        public string LastName = "Smith";
    }

    class Program
    {
        static void Main(string[] args)
        {
            MngrClient.Prepare();
            Console.ReadLine();
        }
    }

    /// <summary>
    /// STATIC / INSTANCE 
    /// </summary>
    public class MngrClient : IRemoteClient
    {
        public void SayHi(string msg)
        {
            Console.WriteLine(msg);
        }

        public void ProcessJob(EJob job)
        {
            Console.WriteLine(job.LastName);
        }

        public static void Prepare()
        {
            // allow this class to be used! - so instances are created and info directly passed on to its static members.
            ServiceHost sh = new ServiceHost(typeof(MngrClient));

            // create the net binding
            NetTcpBinding binding = new NetTcpBinding(SecurityMode.None, true);

            // define the tcpaddress
            string address = string.Format("net.tcp://localhost:33888/BatchMananger/client");

            // add a service point so my server can reach me
            sh.AddServiceEndpoint(typeof(IRemoteClient), binding, address);

            // now open the service for business
            sh.Open();
        }

    }

}
4

2 に答える 2

2

EJob データコントラクトは、サーバーとクライアントで異なる名前空間にあります。両方のクラスを同じ名前空間で宣言するか、属性を使用してクライアントの名前空間を設定し、サーバーの名前空間と一致させる必要があります。

(Datacontract 属性に渡すことができる名前空間の値があるか、コントラクトに別の名前空間を使用するように WCF に指示するために使用できる別の名前空間属性があり、頭の中で思い出すことができません)

編集 確認しました-必要なのは DataContractAttribute の Namespace プロパティであるため、クライアント側の宣言では次のようになります。

[DataContract(Namespace="EJobNamespaceAsItIsDeclaredOnTheServer")]
public class EJob ...

現在、すべての DataContract を、クライアントとサーバーの両方から参照される別個のアセンブリ (コントラクト アセンブリと呼ばれます) に配置することは非常に一般的です。そのアセンブリにはコントラクト クラスの定義だけが必要で、他には何も必要ありません。

于 2013-10-10T16:09:32.820 に答える