WCF,ChannelFactory,“找不到端点元素...”

发布于 2024-08-16 07:30:53 字数 3980 浏览 12 评论 0 原文

我正在尝试从另一个服务中调用 WCF 服务,部分使用我在 StackOverflow 上找到的实现 ChannelFactory 的示例。

我在我的测试解决方案中创建了一个单独的控制台应用程序项目(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”。这可能是因为没有为您的应用程序找到配置文件,或者因为在客户端元素中找不到与此名称匹配的端点元素。


我很困惑,我在应用程序中到底在哪里缺少端点元素本地服务的 .config(定义了指向远程服务的服务引用)、测试应用程序的 app.config,还是其他地方?!


更新:在阅读 这篇 MSDN 文章,或者我猜只是实例化 ChannelFactory 的一种不同方式:

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

我没有尝试从 app.config 中不存在或不正确的信息中获取信息,而是手动插入以下值Binding (BasicHttpBinding) 和远程服务的地址。这似乎让我克服了“无法找到端点元素”错误,但我不确定这是否是最好的解决方案。

I'm trying to call a WCF service from within another service, in part using an example I found here on StackOverflow which implements ChannelFactory.

I've created a separate console app project within my solution for testing (VS 2008, btw),

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
            }
        }
    }
}

This is from the local service's App.Config showing the endpoint:

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

This is from the test project's own App.Config:

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

This is the method I've exposed in my local service, which in turn passes a request object to the remote service:

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;
}

The error I receive is this:

Could not find endpoint element with name 'ServiceSoap' and contract 'ServiceReference.ServiceSoap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.


I'm confused, where exactly am I missing the endpoint element, in the app.config for the local service (which has a Service Reference defined that points to the remote service), the app.config for the test app, or elsewhere?!


UPDATE: I found a workaround of sorts after reading this MSDN article, or I guess just a different way of instantiating the ChannelFactory:

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

Instead of trying to grab from nonexistent or incorrect info in my app.config, I'm instead manually plugging in the values for the Binding (BasicHttpBinding), and the address to the remote service. This seems to get me past the "Could not find endpoint element" error, but I'm not sure if this is the best solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

能否归途做我良人 2024-08-23 07:30:53

好吧,在您的测试应用程序的代码中,您通过名称“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= 属性)。

因此,要么更改测试应用程序中的行以请求该端点元素:

 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>  

两者之一都应该可以解决您的问题。

在“普通”客户端应用程序中,这是可行的,因为当您创建客户端代理时,您根本不指定端点元素名称 - WCF 将仅使用存在的唯一元素。如果您应该有多个端点元素(例如使用不同的协议),则在不指定要使用哪个端点元素的情况下进行此调用将引发异常,并且您必须更改它以指定要使用哪个端点元素(按其名称) , 也。

Well, in your test app's code, you request the endpoint element by the name of "ServiceSoap":

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

but in your config, there's no such endpoint:

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

The config contains an endpoint element by the name of "BasicHttpBinding_IServiceContract" (defined by the name= attribute on your <endpoint> node).

So either you change the line in your test app to request that endpoint element:

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

or you change your app.config for the test app to use ServiceSoap as the name:

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

Either of the two should solve your problem.

In your "normal" client app, this works because when you create the client proxy, you don't specify an endpoint element name at all - WCF will just use the one and only element that's present. If you should have more than one endpoint element (e.g. using different protocols), this call without specifying which endpoint element to use would throw an exception, and you'd have to change it to specify which endpoint element (by its name) to use, too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文