2011-05-12 10 views
1

wcfを使用してサービスを作成しています。 私は2つのプロジェクトとソリューション作成しました:サービスに関するファイルを格納するためのプロジェクト(インターフェースと、そのサービスに対応する実装を含む):WCFでのサービスのアドレス指定に関する問題

  • ライブラリを。このプロジェクトは図書館プロジェクトです。
  • ホスティングアプリケーションこれらのサービスをホストするためのプロジェクト(自己ホスティング)。このため、このプロジェクトは、サービスを構成するために必要な情報を配置するconfigファイルを持つ実行可能なプロジェクトです。

私はサービスを呼び出すためにクライアントも書いています。これは、クライアントアプリケーションと呼ばれます。

私にはサービスがあります。

namespace EchoWcfLibrary { 
    /// <summary> 
    /// The interface specifies for those classes implementing it (services), the operation that the service will expose. 
    /// </summary> 
    [ServiceContract] 
    public interface IService1 { 
     // This does not use serialization (implicit serialization in considered: base types used). 
     [OperationContract] 
     string GetData(int value); 
     // This uses data contracts and serialization. 
     [OperationContract] 
     CompositeType GetDataUsingDataContract(CompositeType composite); 
    } 

    [DataContract] 
    public class CompositeType { 
     // Members not serialized 
     bool boolValue = true; 
     string stringValue = "Hello "; 
     // Serialized 
     [DataMember] 
     public bool BoolValue { 
      get { return boolValue; } 
      set { boolValue = value; } 
     } 
     // Serialized 
     [DataMember] 
     public string StringValue { 
      get { return stringValue; } 
      set { stringValue = value; } 
     } 
    } 
} 

次のサービスホストアプリケーションの起動(実行可能なプロジェクト)されています:

namespace WcfServiceApplication { 
    public static class Program { 
     static void Main(string[] args) { 
      // Setting endpoints and setting the service to start properly. 
      // Base address specified: http://localhost:8081/Service1 
      Console.WriteLine("Beginning..."); 
      using (ServiceHost host = new ServiceHost(typeof(Service1), new Uri("http://localhost:8081/Service1"))) { 
       Console.WriteLine("Opening host..."); 
       host.Open(); 
       Console.WriteLine("Waiting..."); 
       System.Threading.Thread.Sleep(1000000); 
       Console.WriteLine("Closing..."); 
       host.Close(); 
       Console.WriteLine("Quitting..."); 
      } 
     } 
    } 
} 

次のように実行可能なプロジェクトでApp.config(ではインタフェースと実装(ライブラリプロジェクト)は、次のとおり

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 

    <!-- When deploying the service library project, the content of the config file must be added to the host's 
    app.config file. System.Configuration does not support config files for libraries. --> 
    <system.serviceModel> 
     <services> 
      <service name="WcfServiceLibrary.Service1"> 
       <host> 
        <baseAddresses> 
         <add baseAddress="http://localhost:8081/Service1" /> 
        </baseAddresses> 
       </host> 
       <!-- Service Endpoints --> 
       <!-- Unless fully qualified, address is relative to base address supplied above --> 
       <endpoint address="/GoInto/Svc" 
            binding="basicHttpBinding" 
            contract="WcfServiceLibrary.IService1"> 
        <!-- 
       Upon deployment, the following identity element should be removed or replaced to reflect the 
       identity under which the deployed service runs. If removed, WCF will infer an appropriate identity 
       automatically. 
      --> 
        <identity> 
         <dns value="localhost"/> 
        </identity> 
       </endpoint> 
       <endpoint address="/GoInto/Sav" 
            binding="basicHttpBinding" 
            contract="WcfServiceLibrary.IService1"> 
        <!-- 
       Upon deployment, the following identity element should be removed or replaced to reflect the 
       identity under which the deployed service runs. If removed, WCF will infer an appropriate identity 
       automatically. 
      --> 
        <identity> 
         <dns value="localhost"/> 
        </identity> 
       </endpoint> 
       <!-- Metadata Endpoints --> 
       <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> 
       <!-- This endpoint does not use a secure binding and should be secured or removed before deployment --> 
       <endpoint address="GoInto/Mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
      </service> 
     </services> 

     <behaviors> 
      <serviceBehaviors> 
       <behavior> 
        <!-- To avoid disclosing metadata information, 
      set the value below to false and remove the metadata endpoint above before deployment --> 
        <serviceMetadata httpGetEnabled="True"/> 
        <!-- To receive exception details in faults for debugging purposes, 
      set the value below to true. Set to false before deployment 
      to avoid disclosing exception information --> 
        <serviceDebug includeExceptionDetailInFaults="False" /> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 
    </system.serviceModel> 

</configuration> 

クライアント実行可能プロジェクト(ライブラリプロジェクトへのリンクが作成されています)、basicaこれはクライアントです:

namespace WcfServiceClient { 
    class Program { 
     static void Main(string[] args) { 
      ServiceEndpoint httpEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IService1)), new BasicHttpBinding(), new EndpointAddress("http://localhost:8081/Service1")); 
      ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>(httpEndpoint); 
      IService1 svc = channelFactory.CreateChannel(); 
      Console.WriteLine(svc.GetData(121)); 
      System.Threading.Thread.Sleep(10000); 
     } 
    } 
} 

まあ...私の問題は次のとおりです:このアプリケーションは働いています! なぜそれは問題ですか? 問題は、サービスをホストするときにApp.configファイルに3つのエンドポイント、2つのbasicHttpと1つのメタデータエンドポイントを指定したことです。さて、私は<endpoint address="/GoInto/Svc"...エンドポイントに対処したいと思います。これは完全なアドレスであると仮定しています(ベースアドレスを指定していることに注意してください):http://localhost:8081/Service1/GoInto/Svc

残念ながら、クライアントでは、私はこのエンドポイントにアドレスします:http://localhost:8081/Service1これはちょうどベースアドレスです......なぜそれは働いていますか?

namespace WcfServiceClient { 
    class Program { 
     static void Main(string[] args) { 
      ServiceEndpoint httpEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IService1)), new BasicHttpBinding(), new EndpointAddress("http://localhost:8081/Service1/GoInto/Svc")); 
      ChannelFactory<IService1> channelFactory = new ChannelFactory<IService1>(httpEndpoint); 
      IService1 svc = channelFactory.CreateChannel(); 
      Console.WriteLine(svc.GetData(121)); 
      System.Threading.Thread.Sleep(10000); 
     } 
    } 
} 

しかし、私はこれを行う場合、不一致エラーが発生します:私はクライアントにこのアドレスを指定したい

「のhttpへのメッセージ:// localhostを:8081 /サービス1/GoInto/Svc ' EndpointDispatcherでのAddressFilterの不一致により、受信者で を処理できません。 送信者と受信者の エンドポイントアドレスが一致することを確認します。

なぜ機能しないのですか?

答えて

1

ベースアドレスは、ServiceHostコンストラクターまたは要素のいずれかで1か所に指定する必要があります。両方の場所にいる場合、WCFは同じスキーム(HTTP)に対して2つのベースアドレスがあるという例外をスローします。

ホストプロジェクトのapp.configのサービス名に不一致があり、設定が選択されていないことが考えられます(デフォルトのエンドポイントはアドレスがベースアドレスと同じもの)。あなたのホスティングコードにforeachループを追加すると、あなたのサービスがリッスンしているエンドポイントのアドレスがわかるはずです。

   Console.WriteLine("Opening host..."); 
      host.Open(); 

      foreach (ServiceEndpoint endpoint in host.Description.Endpoints) 
      { 
       Console.WriteLine("Endpoint:"); 
       Console.WriteLine(" Address: {0}", endpoint.Address.Uri); 
       Console.WriteLine(" Binding: {0}", endpoint.Binding); 
       Console.WriteLine(" Contract: {0}", endpoint.Contract.Name); 
      } 

      Console.WriteLine("Waiting..."); 
関連する問題