2016-10-14 5 views
0

WCF呼び出しで渡したいオブジェクトを作成しましたがServiceReference1の内部に...このオブジェクトは再定義されています...元のオブジェクトはどこにでもあります...人々がこれをやったようですが、私が間違っていることを理解できません。WCFはService ReferenceのDataObjectの独自のバージョンを定義しています

オブジェクトは、サービスコントラクトの関数のパラメータとして使用されます。

[OperationContract(IsOneWay = true)] 
    void UpdateInformation(MyObject myObject); 

私は私のクライアントからの関数を呼び出すしようとすると、私が手にエラーがある「引数1: 『MyNameSpace.ServiceReference1.MyObject』から 『MyNameSpaceDTO.MyObject』から変換できません」

オブジェクト自身のクラスライブラリdllにあり、[DataObject]および[DataMember]属性でマークされています。

namespace MyNameSpaceDTO 
{ 
    [DataContract] 
    public class MyObject 
    { 
     [DataMember] 
     public string Name { get; set; } 
    …. 

しかし、としてもサービス参照を追加した後Reference.csで終わる:また、私はは、サービス参照の追加の詳細]セクションで、次のセットを持っているん

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
[System.Runtime.Serialization.DataContractAttribute(Name="MyObject", Namespace="http://schemas.datacontract.org/2004/07/MyNameSpaceDTO")] 
[System.SerializableAttribute()] 
public partial class MyObject : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { 

    [System.NonSerializedAttribute()] 
    private System.Runtime.Serialization.ExtensionDataObject extensionDataField; 

    [System.Runtime.Serialization.OptionalFieldAttribute()] 
    private string NameField; 
    ... 

[X]参照アセンブリで再利用タイプ

(O)は、すべての参照アセンブリ内の型を再利用

+0

あなたの溶液構造がどのように見えるのでしょうか?私はいくつかのアセンブリがあると思います:DTOを保持する契約アセンブリ、サービスをホストする別のアセンブリ、そしてそのサービスのクライアントとして機能する3番目のアセンブリ? – khlr

+0

私はDTO用にクライアントとサービスコードの両方を含むライブラリを持っています...そして、クライアント関数をインスタンス化して使用する2つのWinFormsアプリケーションと、サービス関数をインスタンス化して使用するもう1つのアプリケーションがあります。 –

+0

OK、クライアントアプリで_Add service reference_ダイアログを使用してサービスを参照しましたか? – khlr

答えて

0

WCFサービスを使用するには、サービス参照の追加ダイアログを使用してそのサービスを追加するように指示されているサンプルが表示されることがよくあります(間違いなく間違いありません)。クライアントアプリケーションがプロキシクラスを作成するような方法でサービスを参照することにより、サービスによって公開されるWSDLが形成されます。

結果として、たとえばWSDLから生成されたクライアントアプリケーション内のMyNameSpace.ServiceReference1.MyObjectと、という名前の契約アセンブリがあります。これはと思われます。はやや冗長です。

この動作が必要な状況は、次のようなものが考えられます。自分が制御していない任意の公開Webサービスを使用したいとします。そのような状況では、公開されたWSDLから独自のローカルプロキシクラスを作成することは、必要な型を取得する唯一の方法なので、最適です。

しかし、具体的な状況は少し違っているようです。あなたが探しているのはの共有契約です。あなたは、クライアントサーバコードの制御にいる(との両方が幸せに同じ溶液中で並んで生きる)ので、あなただけのシェア契約に快適な状況にいる:

ので、代わりの(サービス参照の追加を経由して)クライアントアプリケーション内にサービス参照を追加すると、通常の参照の追加ダイアログを使用して契約アセンブリを参照するだけです。これを行うことによって、MyNameSpaceDTO.MyObjectが1つだけ生成されます。これは、2番目のものが決して作成されず、不要なためです。このアプローチは契約共有と呼ばれます。

その例を見てみてください。

enter image description here

EDIT:

をいくつか変更されています。最も重要なのは、あなたが通常のアセンブリを共有することを望んでいないだろうということですサービスの実装ロジックを保持します。そこで私はその部分を契約組立から抜き出し、それを別個の実装組立体に入れました。そうすることで、インプリメンテーションロジックではなくインターフェイスとタイプを共有するだけです。この変更は上記のスクリーンショットにも反映されています。

あなたは設定することができ、その次のクラスで小さなソリューション:

契約 - IService1.cs

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    string GetData(int value); 
} 

実装 - Service1.cs

public class Service1 : IService1 
{ 
    public string GetData(int value) 
    { 
     return string.Format("You entered: {0}", value); 
    } 
} 

ホスト - Program.cs

class Program 
{ 
    static void Main(string[] args) 
    { 
     var baseAddress = new Uri("http://localhost:8732/Design_Time_Addresses/Service1/"); 

     using (var host = new ServiceHost(typeof(Service1), baseAddress)) 
     { 
      // Enable metadata publishing. 
      var smb = new ServiceMetadataBehavior(); 
      smb.HttpGetEnabled = true; 
      smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; 
      host.Description.Behaviors.Add(smb); 

      // Open the ServiceHost to start listening for messages. Since no endpoints are 
      // explicitly configured, the runtime will create one endpoint per base address 
      // for each service contract implemented by the service. 
      host.Open(); 

      Console.WriteLine("The service is ready at {0}", baseAddress); 
      Console.WriteLine("Press <Enter> to stop the service."); 
      Console.ReadLine(); 

      host.Close(); 
     } 
    } 
} 

クライアント - Program.cs

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine("Press <Enter> to proceed."); 
     Console.ReadLine(); 

     var binding = new BasicHttpBinding(); 
     var endpoint = new EndpointAddress("http://localhost:8732/Design_Time_Addresses/Service1/"); 
     var channelFactory = new ChannelFactory<IService1>(binding, endpoint); 

     // Create a channel. 
     IService1 wcfClient1 = channelFactory.CreateChannel(); 
     string s = wcfClient1.GetData(42); 
     Console.WriteLine(s); 
     ((IClientChannel)wcfClient1).Close(); 

     Console.WriteLine("Press <Enter> to quit the client."); 
     Console.ReadLine(); 
    } 
} 
+0

あなたは「その例を見てください」と言っています...どの例ですか? –

+0

私は、(うまくいけば)私が書いたことを視覚的に説明するスクリーンショットを意味しました。 – khlr

+0

Ok ...それは...私が密集している場合は申し訳ありません...しかし、今... ServiceReference1はありません(私はService Referenceの追加を実行しないので)...だから私はどのようにサービスを呼び出しますか私のクライアントのコードですか? –

関連する問題