WCF:如何以编程方式重新创建这些App.config值?

10

我有一个WCF服务,如果我创建服务时不指定任何绑定或终结点(通过Visual Studio注册WCF时从App.config中生成的值读取),它可以正常工作。

我有一个简单的方法,返回服务引用:

return new SmsServiceReference.SmsEngineServiceClient();

这个代码可以正常工作(因为值是从配置文件中读取的)。但是,我想将其中一些值存储在数据库中(例如URI),并且希望能像这样实现:

        Binding binding = new BasicHttpBinding();
        EndpointAddress endpointAddress = new EndpointAddress( "my.uri.com/service.svc" );

        return new SmsServiceReference.SmsEngineServiceClient(binding,endpointAddress);

这行代码不起作用。当我尝试使用服务引用时,它会抛出异常。

我怀疑是因为我的 App.config 提供了更多信息,而上面那两行代码并没有提供(显然)。问题是,我该如何在程序中复制以下 App.Config 的值?

这是我的 App.Config 片段:(URI已被修改以保护当事人)。

  <system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_ISmsEngineService" 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://www.myuri.com/Services/Services.svc/basic"
      binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISmsEngineService"
      contract="SmsServiceReference.ISmsEngineService" name="BasicHttpBinding_ISmsEngineService" />
</client>

2个回答

16

应用配置中的大多数值也是绑定中的属性,可以通过编程方式重新创建。个人而言,我使用以下类似的方法创建绑定:


public static BasicHttpBinding CreateBasicHttpBinding()
{
    // 创建BasicHttpBinding实例
    BasicHttpBinding binding = new BasicHttpBinding();
    // 设置属性值
    binding.AllowCookies = false;
    binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
    binding.OpenTimeout = new TimeSpan(0, 1, 0);
    binding.SendTimeout = new TimeSpan(0, 1, 0);
// 进一步设置属性值,根据配置文件需要添加更多属性... // 缓冲区大小 binding.MaxBufferSize = 65536; binding.MaxBufferPoolSize = 534288; binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
// Quotas限制 binding.ReaderQuotas.MaxDepth = 32; binding.ReaderQuotas.MaxStringContentLength = 8192; // 根据配置文件需要添加更多属性...
return binding; }

我用类似这样的方法来创建我的终端地址


public static EndpointAddress CreateEndPoint()
        {
            return new EndpointAddress(Configuration.GetServiceUri());
        }

这段代码的作用是创建一个终结点地址(Endpoint Address),该地址由 Configuration.GetServiceUri() 方法返回的服务 URI 构造而成。

serviceUri 将是服务的URL,例如 http://www.myuri.com/Services/Services.svc/basic

最后创建服务客户端


创建基本 HTTP 绑定:Binding httpBinding = CreateBasicHttpBinding();
创建终结点地址:EndpointAddress address = CreateEndPoint();
使用上述绑定和终结点地址实例化 MyServiceClient:var serviceClient = new MyServiceClient(httpBinding, address);


1

好的,配置文件中的客户端终端点指定了这个URL:

 <endpoint address="http://www.myuri.com/Services/Services.svc/basic"

但在你的代码示例中,你创建了:

 EndpointAddress endpointAddress = new EndpointAddress( "my.uri.com/service.svc" );

地址必须匹配 - 如果配置文件中的地址可用,您需要更改代码为:

 EndpointAddress endpointAddress = new EndpointAddress( "http://www.myuri.com/Services/Services.svc/basic" );

请注意 - 你的代码示例中有各种小错别字 (my.uri.com与www.myuri.com,/service.svc而不是/Services/Services.svc)。
更正后的终结点地址是否有效?
马克

我为“小错字”道歉,我只是想保持简单。代码中使用的端点地址(以及应用程序配置中的地址)相同,但它却不起作用。有一个区别,即App.config有/basic这个东西。那不是URI的一部分,也不知道为什么VSTUDIO会添加它。如果你浏览该URL(带有/basic),它就不能正常工作。不用说,我已经试过两种方式了。我认为在我的“端点”创建中漏掉了App.config的某些信息。事实上,除了URI之外,我没有为我的端点提供任何参数,其他APp.config的信息呢? - Martin Marconcini
URL的确切拼写非常重要,因此在这里“简单”会导致混淆。您能展示一下服务器部分的配置文件吗? - marc_s
嗨,马克,问题不在于URI,而是我在客户端web.config中有一些参数没有在程序创建绑定时传递。我按照web.config中的一切都传递了(使用Emmanuel的建议),它起作用了。感谢您的帮助!+1给你。 - Martin Marconcini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接