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 andbasicHttpBinding
s
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:
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.
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:
<!-- 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#.
Two questions
In Solution Explorer, right-click the name of the project to which you want to add the service, and then click Add Service Reference. The Add Service Reference dialog box appears. Click Discover. All services (both WCF Data Services and WCF services) in the current solution are added to the Services list.
No need to write any code. Just change the URL in app. config and it will work.
NET Standard project, this option is available when you right-click on the Dependencies node of the project in Solution Explorer and choose Manage Connected Services.) On the Connected Services page, select Add Service Reference. The Add service reference page opens. Select WCF Web Service, and then choose Next.
One possible approach would be to "externalize" certain parts of your <system.serviceModel> configuration into external files, one per environment.
E.g. we have "bindings.dev.config" and "bindings.test.config", which we then reference in our main web.config like this:
<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.
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.
Marc
EDIT: OK, so NO config 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.
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 appSettings
in the web.config file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With