C# 使用SOAP web服务而不依赖app.config

C# 使用SOAP web服务而不依赖app.config,c#,.net,vb.net,web-services,app-config,C#,.net,Vb.net,Web Services,App Config,我正在构建一个.NET组件,它将调用外部web服务。我使用“添加服务引用”对话框将web服务添加到我的组件中,该组件生成使用该服务所需的代码,并将设置添加到app.config文件中 我正在测试该组件,方法是从控制台应用程序添加对其DLL的引用,并调用相应的方法来创建web服务的新实例:…=新建MyServiceSoapClient()。但是,当我执行此操作时,会出现以下异常: 无效操作例外 在ServiceModel客户端配置部分中找不到引用约定“MyServicesSoap”的默认终结点元素

我正在构建一个.NET组件,它将调用外部web服务。我使用“添加服务引用”对话框将web服务添加到我的组件中,该组件生成使用该服务所需的代码,并将设置添加到app.config文件中

我正在测试该组件,方法是从控制台应用程序添加对其DLL的引用,并调用相应的方法来创建web服务的新实例:
…=新建MyServiceSoapClient()
。但是,当我执行此操作时,会出现以下异常:

无效操作例外

在ServiceModel客户端配置部分中找不到引用约定“MyServicesSoap”的默认终结点元素。这可能是因为找不到应用程序的配置文件,或者在客户端元素中找不到与此约定匹配的端点元素

这是有意义的,因为app.config没有随组件的DLL一起提交。如何调用web服务而不必依赖App.Config中的设置?

如果这是一个WCF服务(从错误消息中听起来像),那么,在大多数情况下,您需要的是App.Config,因为它是App.Config,它告诉WCF的其余部分MyServiceSoapClient是一个web服务(只需对两个app.config文件进行一点更改,就可以成为命名管道服务,而无需重新编译代码……)

现在,如果您真的想在没有app.config的情况下执行此操作,那么您必须抛出生成的
MyServiceSoapClient()
,并根据
HttpWebRequest

编写您自己的。app.config文件中
中的设置将告诉组件如何连接到外部web服务。xml只是与web服务建立默认连接所需的必要类和枚举的文本表示

例如,这是为我添加的web服务生成的代码:

<system.serviceModel>
 <bindings>
  <basicHttpBinding>
   <binding name="MyServicesSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
     receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
     bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
     maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
     messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
     useDefaultWebProxy="true">
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
       maxBytesPerRead="4096" maxNameTableCharCount="16384" />
     <security mode="None">
      <transport clientCredentialType="None" proxyCredentialType="None"
        realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
     </security>
    </binding>
   </basicHttpBinding>
  </bindings>
 <client>
  <endpoint address="http://services.mycompany.com/WebServices/MyServices.asmx"
    binding="basicHttpBinding" bindingConfiguration="MyServicesSoap"
    contract="MyServices.MyServicesSoap" name="MyServicesSoap" />
 </client>
</system.serviceModel>
通常,当您使用无参数构造函数时(即
newmyServicesOAPClient()
),将使用app.config文件中的设置。但是,您可以通过在代码中显式设置
绑定
端点
值并将这些实例传递给构造函数来绕过app.config文件。

在代码中设置绑定和端点配置是一种方法,但使用consum的方法有另一种er DLL并让配置保留在现有的App.config文件中

出现上述InvalidOperationException的原因是DLL中不包含配置设置。它始终依赖App.config来提供配置,但由于您在另一个控制台应用程序中使用DLL,因此找不到配置设置

当我们使用“添加服务引用”时对话框将web服务添加到客户端组件并创建web服务实例,我们让Visual Studio处理通信通道的创建并加载配置设置。因此,如果我们能够自己显式创建此类通道,那么我们可以管理配置设置

Microsoft为此提供了类,
ConfigurationChannelFactory
类是其中之一。MSDN声明:

提供为特定类型创建通道配置元素的常规功能

配置ChannelFactory允许集中管理WCF客户端配置

使用“添加服务引用”对话框将web服务添加到客户端组件,因为我们需要服务通道接口实例

首先将生成的App.config文件重命名为App.dll.config,并在其文件属性中将复制到输出目录属性更改为始终复制

创建一个类,该类具有返回通道对象以访问web服务的方法,如下所示:

public class ManageService
{
    public static T CreateServiceClient<T>(string configName)
    {
        string _assemblyLocation = Assembly.GetExecutingAssembly().Location;
        var PluginConfig = ConfigurationManager.OpenExeConfiguration(_assemblyLocation);
        ConfigurationChannelFactory<T> channelFactory = new ConfigurationChannelFactory<T>(configName, PluginConfig, null);
        var client = channelFactory.CreateChannel();
        return client;
    }
}
SampleService
是我的web服务的名称空间。
Client
保存web服务的实例


如果您需要处理双工通信和回调,那么您可以查看配置DuplexChannelFactory类。

简单地说,组件中的配置设置需要复制到ConsoleApplication1.exe。config@Josh那对我来说不行,我没提到是我的问题,但是这个.NET DLL将从VB6 COM应用程序调用,因此我正在编写的.NET组件必须能够成功调用web服务,而不依赖消费应用程序中的任何内容。+1太好了,谢谢。尽管我确实发现在绑定上,我只需要添加少量的集合tings。我只在绑定上使用了超时,结果正常。我遇到了一个VB6应用程序的问题,该应用程序引用了一个调用web服务的.NET dll。问题源于dll的app.config文件,因为从dll读取配置文件并不完全简单,这允许我完全绕过配置文件。
public class ManageService
{
    public static T CreateServiceClient<T>(string configName)
    {
        string _assemblyLocation = Assembly.GetExecutingAssembly().Location;
        var PluginConfig = ConfigurationManager.OpenExeConfiguration(_assemblyLocation);
        ConfigurationChannelFactory<T> channelFactory = new ConfigurationChannelFactory<T>(configName, PluginConfig, null);
        var client = channelFactory.CreateChannel();
        return client;
    }
}
Client = ManageService.CreateServiceClient<SampleService.IKeyServiceChannel>("MetadataExchangeTcpBinding_IKeyService");