10

ChannelFactoryを実装する StackOverflow で見つかった例を一部使用して、別のサービス内から WCF サービスを呼び出そうとしています。

テスト用のソリューション内に別のコンソール アプリ プロジェクトを作成しました (VS 2008、ところで)、

namespace MyService.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            MySolution.MyTestClient proxy = new MyTestClient();

            proxy = new MyTestClient();
            proxy.Endpoint.Address = new EndpointAddress("http://localhost:8723/MySolution/");

            // Instantiate a request object and assign values to its member variables.    
            MySolution.RemoteServiceMethod() theObject = new RemoteServiceMethod();            
            theObject.SomeProperty = "123";
            theObject.SomeOtherProperty = "alpha";

            Console.WriteLine("Calling the remote service method now...");

            try
            {
                proxy.SubmitRemoteServiceRequest(proxy.theObject);
            }
            catch (FaultException<MySolution.RequestException> e)
            {
                // exception code hereMySolution
            }
        }
    }
}

これは、エンドポイントを示すローカル サービスのApp.Configからのものです。

<system.serviceModel>
  <client>
   <endpoint address="http://MyService/MyService.asmx"
     binding="basicHttpBinding" bindingConfiguration="ServiceSoap"
     contract="ServiceReference.ServiceSoap"
     name="ServiceSoap" />
  </client>
  ...
 </system.serviceModel>  

これは、テスト プロジェクト独自のApp.Configからのものです。

 <client>
      <endpoint address="http://localhost:8723/MyService"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServiceContract"
        contract="ServiceContract.IServiceContract" name="BasicHttpBinding_IServiceContract" />
 </client>  

これは、ローカル サービスで公開したメソッドで、リクエスト オブジェクトをリモート サービスに渡します。

public ServiceContract.Response.ZZZ_Response SubmitRemoteServiceRequest(ServiceContract.Request.ZZZ_Request sc_TheirServiceRequest)
{
     var factory = new ChannelFactory<ServiceReference.ServiceSoap>("ServiceSoap");
     var wcfClient = factory.CreateChannel();
     bool closedSuccessfully = false;

     // Instantiate a response object which I will return to the consumer.
     ServiceContract.Response.ZZZ_Response zzz_Response = new ServiceContract.Response.ZZZ_Response();

     // Instantiate request and response objects, respectively, which I use internal to my service to call remote service.
     ServiceReference.MyServiceRequest scMyServiceRequest = new ServiceReference.MyServiceRequest();

     ServiceReference.MyServiceResponse scMyServiceResponse = new ServiceReference.MyServiceResponse();

     try
     {                
          // Now you can make calls on the wcfClient object
          scMyServiceResponse = wcfClient.MyServiceMethod(scMyServiceRequest );                

          ((ICommunicationObject)wcfClient).Close();
          closedSuccessfully = true;
     }
     finally
     {
          if (!closedSuccessfully)
          {
               ((ICommunicationObject)wcfClient).Abort();
          }
     }

     return zzz_Response;
}

私が受け取るエラーはこれです:

ServiceModel クライアント構成セクションで、名前が「 ServiceSoap」でコントラクトが「ServiceReference.ServiceSoap 」のエンドポイント要素が見つかりませんでした。これは、アプリケーションの構成ファイルが見つからなかったか、この名前に一致するエンドポイント要素が client 要素に見つからなかったためである可能性があります。


ローカル サービスの app.config (リモート サービスを指すサービス リファレンスが定義されている)、テスト アプリの app.config、または他の場所で、endpoint 要素が正確にどこにないのでしょうか。 !


更新:この MSDN の記事を読んだ後、ある種の回避策を見つけました。または、ChannelFactory をインスタンス化する別の方法だと思います。

var factory = new ChannelFactory<ServiceReference.ServiceSoap>(new BasicHttpBinding(), "http://urlToRemoteService/RemoteService.asmx");

app.config に存在しない情報や正しくない情報を取得しようとする代わりに、Binding (BasicHttpBinding) の値とリモート サービスへのアドレスを手動でプラグインします。これにより、「エンドポイント要素が見つかりませんでした」というエラーを回避できたようですが、これが最善の解決策であるかどうかはわかりません。

4

1 に答える 1

16

テスト アプリのコードでは、"ServiceSoap" という名前でエンドポイント要素を要求します。

 var factory = new ChannelFactory<ServiceReference.ServiceSoap>("ServiceSoap");

しかし、あなたの設定では、そのようなエンドポイントはありません:

 <client>
      <endpoint address="http://localhost:8723/DelinquencyService"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServiceContract"
        contract="ServiceContract.IServiceContract" name="BasicHttpBinding_IServiceContract" />
 </client>  

構成には、「BasicHttpBinding_IServiceContract」という名前のエンドポイント要素が含まれていname=ます (ノードの属性によって定義され<endpoint>ます)。

したがって、テスト アプリの行を変更して、そのエンドポイント要素を要求します。

 var factory = new ChannelFactory<ServiceReference.ServiceSoap>("BasicHttpBinding_IServiceContract");

または、テスト アプリのapp.configを名前としてServiceSoapを使用するように変更します。

<client>
   <endpoint name="ServiceSoap"
        address="http://localhost:8723/DelinquencyService"
        binding="basicHttpBinding" 
        bindingConfiguration="BasicHttpBinding_IServiceContract"
        contract="ServiceContract.IServiceContract" />
</client>  

2つのどちらかが問題を解決するはずです。

「通常の」クライアント アプリでは、クライアント プロキシを作成するときにエンドポイント要素名をまったく指定しないため、これは機能します。WCF は、存在する唯一の要素を使用するだけです。複数のエンドポイント要素が必要な場合 (たとえば、異なるプロトコルを使用する場合)、使用するエンドポイント要素を指定せずにこの呼び出しを行うと、例外がスローされるため、使用するエンドポイント要素を (その名前で) 指定するように変更する必要があります。 、 それも。

于 2009-12-30T09:46:03.757 に答える