1

契約書を作成しました

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    [NetDataContract]
    void PassGuid(Guid id);

    [OperationContract]
    [NetDataContract]
    void PassInt(int id);
}

ここでNetDataContractAttribute説明する属性。呼び出していると、エラーが発生します。PassGuid

追加情報: メッセージのデシリアライズ中にフォーマッタが例外をスローしました: パラメータhttp://tempuri.org/:idのデシリアライズ中にエラーが発生しました。InnerException メッセージは、「XML 'Element' ' http://tempuri.org/:id ' には予期された属性 ' http://schemas.microsoft.com/2003/10/Serialization/:Type 'が含まれていません」でした。デシリアライザは、デシリアライズする型を認識していません。シリアル化されている型が、逆シリアル化されている型と同じコントラクトを持っていることを確認してください。詳細については、InnerException を参照してください。

しかしPassInt、エラーなしで呼び出すことができました。

完全なソースコードはこちら.

編集: この質問は、このような GUID の送信効率に関するものではなく、主に NetDataContractSerializer の使用に関するものです。

4

2 に答える 2

2

NetDataContractSerializerサーバー側と同じようにカスタムシリアライザーを使用しています。NetDataContractSerializerとの違いはDataContractSerializer、シリアライゼーションがタイプの追加情報を追加することです。

たとえば DatacontractsSerializer、次のようにシリアル化されます。

<Customer xmlns="http://www.contoso.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <FirstName>Zighetti</FirstName>
  <ID>101</ID>
  <LastName>Barbara</LastName>
</Customer>

NetDataContractSerializer同じオブジェクトを次のようにシリアル化します。

<Customer z:Id="1" z:Type="NetDCS.Person" z:Assembly="NetDCS, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns="http://www.contoso.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
  <FirstName z:Id="2">Zighetti</FirstName>
  <ID>101</ID>
  <LastName z:Id="3">Barbara</LastName>
</Customer>

より多くのタイプ固有の情報を誘導します。

あなたの場合、サーバーは知ってNetDataContractSerializerいますが、クライアントは知りません。この動作を共有コード ライブラリに配置して、クライアントと共有する必要があります。次に、以下のコードを使用して、この enw 動作をクライアントに追加できます。

       using (var client = new TestServiceClient())
        {
            // Get the channel factory
            var factory = client.ChannelFactory;

            // Attach the behavior
            foreach (OperationDescription desc in factory.Endpoint.Contract.Operations)
            {
                DataContractSerializerOperationBehavior dcsOperationBehavior = desc.Behaviors.Find<DataContractSerializerOperationBehavior>();
                if (dcsOperationBehavior != null)
                {
                    int idx = desc.Behaviors.IndexOf(dcsOperationBehavior);
                    desc.Behaviors.Remove(dcsOperationBehavior);
                    desc.Behaviors.Insert(idx, new WcfClient.NetDataContractAttribute.NetDataContractSerializerOperationBehavior(desc));
                    //return true;

                }
            }

            // pass
            client.PassInt(0);
            // fail
            client.PassGuid(Guid.NewGuid());
            client.Close();
        }

構成ファイルを介して動作をアタッチすることもできます。

于 2015-09-24T19:27:36.277 に答える
1

問題は、クライアント側で自動生成されたコントラクト (ファイルを参照) に属性WcfClient\Service References\TestService\Reference.csがないことです。[NetDataContract]

したがってDataContractSerializer、クライアント側で使用されます。

がクライアントとサーバーの両方で機能するNetDataContractSerializerには、クライアント側で適切なコントラクト定義が必要です (サーバー DLL を参照するか、コントラクトを別の DLL に抽出することにより)。そして、自動生成されたClientBase<ITestService>ものではなく、独自の Proxy クラス (から継承) を作成する必要があります (またはChannelFactory<ITestService>、プロキシ クラスをまったく使用せずに使用するだけです)。

于 2015-09-24T15:04:04.147 に答える