C# 根据环境更改 WCF 服务引用 URL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/797539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:34:07  来源:igfitidea点击:

Changing WCF Service reference URL based on environment

c#.netwcfweb-config

提问by Richard Ev

I have a web application that uses a number of WCF Services. I deploy my web application in various environments (dev, UAT, production etc). The URL of each WCF Service is different for each environment. I am using .NET 3.5 andbasicHttpBindings

我有一个使用多个 WCF 服务的 Web 应用程序。我在各种环境(开发、UAT、生产等)中部署了我的 Web 应用程序。每个 WCF 服务的 URL 因环境而异。我正在使用 .NET 3.5 和basicHttpBindings

The web application uses a framework to support machine-specific settings in my web.config file. When instantiating an instance of a WCF Service client I call a function that creates the instance of the WCF Service client using the constructor overload that takes the arguments:

Web 应用程序使用框架来支持我的 web.config 文件中特定于机器的设置。在实例化 WCF 服务客户端的实例时,我调用一个函数,该函数使用带参数的构造函数重载创建 WCF 服务客户端的实例:

System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress

In essence the <system.serviceModel><bindings><basicHttpBinding><binding>configuration in web.config has been replicated in C# code.

本质上<system.serviceModel><bindings><basicHttpBinding><binding>,web.config 中的配置已被复制到 C# 代码中。

This approach works well.

这种方法效果很好。

However, I now have to enhance this approach to work with a WCF service that uses an X509 certificate. This means that I have to replicate the following additional settings in web.config in C# code:

但是,我现在必须增强这种方法才能使用使用 X509 证书的 WCF 服务。这意味着我必须在 C# 代码中的 web.config 中复制以下附加设置:

<!-- inside the binding section -->
<security mode="Message">
  <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
  <message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>


<behaviors>
  <endpointBehaviors>
    <behavior name="MyServiceBehaviour">
      <clientCredentials>
        <clientCertificate storeLocation="LocalMachine" storeName="My"
          x509FindType="FindByThumbprint" findValue="1234abcd" />
        <serviceCertificate>
          <defaultCertificate storeLocation="LocalMachine" storeName="My"
            x509FindType="FindByThumbprint" findValue="5678efgh" />
          <authentication trustedStoreLocation="LocalMachine"
            certificateValidationMode="None" />
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

I am having some difficulty figuring out how to code this configuration in C#.

我在弄清楚如何在 C# 中编写此配置时遇到了一些困难。

Two questions

两个问题

  • Can anyone recommend a better approach for managing WCF Service reference URLs across multiple environments?
  • Alternatively, any suggestions on how to replicate the above web.config section in C# will be welcomed
  • 谁能推荐一种更好的方法来管理跨多个环境的 WCF 服务引用 URL?
  • 或者,欢迎任何有关如何在 C# 中复制上述 web.config 部分的建议

采纳答案by Richard Ev

The following code replicates the configuration in my original question:

以下代码复制了我原始问题中的配置:

myClient.ClientCredentials.ClientCertificate.SetCertificate(
    StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindByThumbprint,
    "1234abcd");

myClient.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
    StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindByThumbprint,
    "5678efgh");

myClient.ClientCredentials.ServiceCertificate.Authentication.TrustedStoreLocation = StoreLocation.LocalMachine;
myClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

In the production code the two thumbprint values are stored in appSettingsin the web.config file.

在生产代码中,两个指纹值存储在appSettingsweb.config 文件中。

回答by marc_s

One possible approach would be to "externalize" certain parts of your <system.serviceModel> configuration into external files, one per environment.

一种可能的方法是将 <system.serviceModel> 配置的某些部分“外部化”到外部文件中,每个环境一个。

E.g. we have "bindings.dev.config" and "bindings.test.config", which we then reference in our main web.config like this:

例如,我们有“bindings.dev.config”和“bindings.test.config”,然后我们在我们的主 web.config 中像这样引用它们:

<system.serviceModel>
  <bindings configSource="bindings.dev.config" />
</system.serviceModel>

That way, all you need to change from DEV to PROD is this one line of config XML.

这样,您需要从 DEV 更改为 PROD 的只是这一行配置 XML。

Basically, in .NET 2.0 config, any configuration element can be "externalized". You cannot however externalize configGroups (such as "system.serviceModel") directly - you have to be on the "configuration element" level.

基本上,在 .NET 2.0 配置中,任何配置元素都可以“外部化”。但是,您不能直接将 configGroups(例如“system.serviceModel”)外部化 - 您必须处于“配置元素”级别。

Marc

马克

EDIT: OK, so NOconfig edit changes to switch between environments..... In that case, you probably have to dream up a naming scheme, e.g. name your bindings, behaviors and endpoints in such a way, that you can distinguish them at runtime.

编辑:好的,所以没有配置编辑更改以在环境之间切换.....在这种情况下,您可能必须想出一个命名方案,例如以这样的方式命名您的绑定、行为和端点,以便您可以区分它们在运行时。

Something like:

就像是:

<bindings>
  <binding name="Default_DEV">
    .....
  </binding>
  <binding name="Default_PROD">
    .....
  </binding>
</bindings>

that way, you could build up the name of the element you want (e.g. binding "Default_PROD") from your code and the environment you're running in, and then grab the according config from the config file which contains all the config settings for all environments.

这样,你可以从你的代码和你正在运行的环境中建立你想要的元素的名称(例如绑定“Default_PROD”),然后从包含所有配置设置的配置文件中获取相应的配置所有环境。

回答by Bigtoe

We don't use web.config files at all, we specify everything programmatically and load all configuration from a centralized database.

我们根本不使用 web.config 文件,我们以编程方式指定所有内容并从中央数据库加载所有配置。