How do I configure a client to provide the certificate for certificate credentials?
You need to use the client credentials behavior to provide the credentials that the client will use to authenticate to the service. Here’s the basic template that you can fill out and stick in the behaviors section of your client configuration for client certificate credentials. You then need to reference this behavior configuration when you define the client endpoint.
<behavior name="…"> <clientCredentials> <clientCertificate findValue="…" storeLocation="…" storeName="…" x509FindType="…" /> </clientCredentials> </behavior>
The same method works for other types of client credentials by replacing the client certificate element with the appropriate elements for windows, digest, or the like.
Why do I get an error “configuration evaluation context not found” when I try to create a custom binding using bindings or binding elements from a library?
The evaluation context not found error (or in traces with the identifier System.ServiceModel.EvaluationContextNotFound) is generally caused by using a configuration element defined in a library that is not included in the application’s configuration as an extension. Depending on how the configuration is being used you might instead get a more helpful message directing you to check the configuration extensions section.
When you use a custom configuration element in another assembly, you need to register the extension that defines the configuration element with the configuration system. That would look something like this:
<configuration> <system.serviceModel> <extensions> <bindingExtensions> <add name="basicHttpContextBinding" type="System.ServiceModel.Configuration.BasicHttpContextBindingCollectionElement, System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </bindingExtensions> </extensions> </system.serviceModel> </configuration>
I’ve used one of our binding extensions added in Orcas as an example. There are a variety of different extension sections for items such as bindings, binding elements, and behaviors. I talked about the use of strong names in configuration extension references in the past if this pains you during development.
In .Net 4 Beta 1 you might get this error despite having properly registered the extension in configuration. That’s because there is a bug that causes the registered extensions to not be handled properly when reading a configuration file other than the one for the current application. This will be fixed in the next beta and isn’t a problem in any of the past releases.
When generating a proxy I’m getting an error about the extendedProtectionPolicy element not being supported. Why didn’t I see this error before?
Extended protection policy is a change to how integrated Windows authentication works that is intended to enhance security. The use of extended protection is supposed to mitigate certain types of forwarding attacks during the credential challenge process. However, the platform support for extended protection is being delivered in different pieces so support is still inconsistent. You most likely have used a mix of different platforms to develop the client and server pieces of the application.
If you’re getting an error about the extended protection policy element on the client, check to see if your client application config file contains a line referencing extended protection, such as:
<extendedProtectionPolicy policyEnforcement="Never" />
You’ve probably picked this up on a machine that supports extended protection but are now on a machine that doesn’t support extended protection. Deleting the extended protection policy element and trying again to generate the proxy on the target machine should resolve the problem.
The NCL team has released their list of new networking features for .Net framework 4 beta 2. A partial summary of the features is:
New networking features don’t automatically show up in WCF. Some features aren’t applicable, either because we don’t use the protocol or because an existing WCF feature already solves the problem, but for the most part we’ll be waiting for you to tell us if there’s something important to support to improve your applications. You don’t have to (and shouldn’t) wait for beta 2 to actually be available to start asking.
Yesterday I talked about the algorithm the TCP transport uses to reserve a unique port when listening on both IPv4 and IPv6 addreses is enabled for a service. Why are the random port numbers drawn from the range 49152-65535?
Because that’s the range the operating system uses for dynamic port allocations. Sometimes.
The IANA divides the range of ports into three parts: well-known ports which are less than 1024, registered ports which are 1024 through 49151, and dynamic ports which are greater than 49151. Well-known and registered ports are different kinds of classifications for ports that have an assigned application use. Dynamic ports are intended for transient use by applications, which is what we want in this case.
Up through Windows Server 2003 though, the dynamic port range was 1025 to 5000 (you could use a registry setting to increase the maximum port number). Starting in Windows Vista the dynamic port range was changed to match the IANA recommendation (you can use the netsh command to change both the minimum and maximum port number).
WCF runs on versions of Windows back to Windows XP so there was a question of what dynamic port range to use. What we ultimately decided was to use a fixed range rather than duplicate the operating system settings for controlling the dynamic port range and to use the standardized port range on both new and old systems.
One of the options for the listen URI for the TCP transport is to let the transport make the address unique by filling in details such as the port number. The socket API allows specifying a wildcard port but at the time WCF was written the wildcard port option could only be used with a single IP version. Since WCF listens on both IPv4 and IPv6 addresses, how did this work?
First, there are several cases where the process is simple. If the network stack only supports a single IP version, for example if IPv6 is not installed, then we don’t have to do anything special to get a wildcard port. Similarly, if the address you’re listening on is specified as an IP address, then we don’t need to worry about IP protocol versions besides the one you picked since we’ll only be listening on that specific address.
If we find that both IPv4 and IPv6 are allowed and you asked for a unique port, then that is the case where we actually have a problem. The solution we chose is brute force. We start by generating ten random numbers between 49152 and 65535. Then, we try binding sockets for each of our randomly chosen ports until we find one that works for both IPv4 and IPv6. This means that there’s a chance we’ll give up and say that there are no free ports even when some are unused.
The chances of giving up too soon are negligible for the first 5000 ports. By the time you get to 10,000 unique open ports though, the chances of giving up are in the neighborhood of 1%. It only gets worse from there as by the time you get to 15,000 unique open ports you’ll be seeing failures about half the time.
I was recently trying to reinstall the .Net 4 beta at home and came across this particular error:
Windows6.1-KB958488-v6001-x64.msu returned non-MSI error code: 0x80092004 - Cannot find object or property
When rebooting didn’t fix the problem I figured it was unlikely to be caused by files being held open or not updated during uninstallation. Since I didn’t want to wipe the machine just for this I decided to poke at the problem a bit further. I found that this error is known to occur if you try to uninstall and reinstall too quickly. After uninstalling there is a background update done to a catalog of components. If something delays that update and you try to reinstall right away, you can end up with this error due to incorrectly cached component information.
After uninstalling, rebooting and then waiting for an hour solved the problem.
Why does a message encoder have to be specified before the transport when constructing a binding?
A message encoder doesn’t directly fit into a channel stack because the message encoder type doesn’t implement any of the channel shapes. Instead, a message encoder is an auxilliary piece used by one of the channels in the channel stack.
When a channel stack is constructed from a binding, the message encoder binding element therefore doesn’t actually build anything. During the message encoder binding element’s time to build, the binding element saves a copy of itself to the BindingContext in the BindingParameters collection. Later on, when a transport binding element is encountered, the transport may decide to search through the binding parameters to find the deferred messag encoder. It’s the transport that builds the message encoder rather than the binding itself.
That’s also why the message encoder has to be specified before the transport. If the transport binding element is encountered before the message encoder binding element, then the transport just has to assume that the binding doesn’t contain a message encoder. Most transports use a default message encoder if you don’t specify one in the binding so the build process continues for a while longer. However, if you’ve stacked the binding elements out of order, then the message encoder binding element will still be in the binding context at the end of the build process, from which you can infer that one of the binding elements wasn’t handled correctly.
Can I use a centralized configuration repository in a distributed WCF application?
Yes, configuration is something that’s abstracted from the service or client logic in WCF although replacing the implementation behind that abstraction can be quite a bit of work. The System.Configuration system that drives the default file-based configuration system is hard to reuse on a piecemeal basis so making small changes to how configuration works can sometimes cost as much as large changes.
Replacing configuration settings after they’re loaded is fairly straightforward but this doesn’t work in all cases as you sometimes need to replace the initially loaded value or have an entirely separate notion of what configuration means.
One example of significantly altering how configuration works in a distributed application is demonstrated by the StockTrader sample that I mentioned last year. There have been several minor updates since then. You can get the latest version to see what has changed as well as a description of the included configuration service.
The configuration service sample is probably more complex than something that you’d want to directly copy into your application unless you’re looking for a configuration system that works in exactly the same way. There are many different patterns for configuring a distributed application demonstrated by the configuration service though so you might want to flip through the source code and included documentation for inspiration.
Poor network utilization for large TCP data transfers is often a symptom of an overly small ConnectionBufferSize. The ConnectionBufferSize is the size of the send and receive buffers used by the connection oriented transports, and in particular the TCP transport where the default size is 8 KB.
If all of the following factors are present, then you might want to investigate whether tuning the connection buffer size will improve the performance of your application:
On the other hand, the following factors might discourage you from increasing the connection buffer size:
I’ve previously recommended increasing the ConnectionBufferSize up to 64 KB once the network speed exceeds 100 Mbps and keeping the default for slower networks. I’ve found recently though several deployments where performance has benefited from bumping up the connection buffer size more aggressively. The exact optimal values for a deployment depend on many factors besides the bandwidth, such as the frequency of dropped packets, transmission latency, and the presence of routers or bridges.
I’m now considering recommended ranges of 8 KB-32 KB for connection up to 100 Mbps and 32 KB-256 KB for faster connections. If you’ve tried tuning the ConnectionBufferSize of a WCF application and seen optimal values significantly outside these ranges, I’d be interested in hearing from you.
The CLR team has a survey for .Net 4.0 Beta 1 covering different aspects of performance, hosting, security, and application compatibility. If you’ve built new applications using beta 1 or you’ve tried recompiling or running older applications using beta 1 then you might have some useful feedback about the CLR.
I’ve been relatively happy with the beta CLR except when it comes to performance. Computationally intensive tasks appear to take quite a bit longer in this release, particularly on 64-bit machines. We tend to see this pattern in every release when working on WCF, and it takes a while to work thorugh the issues one-by-one.
What options can I use with WSHttpBinding to make it friendlier to load balancing?
The primary difficulty encountered when using WSHttp with a load balancer is that WSHttp is easy to configure to produce application-level sessions between the client and service.
Many load balancers support the concept of sticky sessions, which pins the traffic from a client to a particular machine after the first exchange. This pinning is predictive though as very few general-purpose load balancers do the necessary record keeping and protocol parsing to unambiguously route sessions. It’s possible for the load balancer to associate both too few messages with the session, causing an error when one of the messages is processed without the session context, as well associate too many messages with the session, causing an uneven distribution of load.
Going in the other direction, you can also look to avoid using the features that result in creating application-level sessions. On the WSHttp binding, reliable messaging and message level security are the two sources of application-level sessions.
The use of reliable messaging is controlled by the ReliableSession property (and defaults to optional).
The use of message security is controlled by the Security property (and defaults to enabled). Alternatives to the default message security settings are to use transport security, by setting the Security.Mode property to Transport, or to use non-sessionful message security, by setting the Security.Message.EstablishSecurityContext property to false.
The WCFProxyGenerator tool on CodePlex has been updated, which is a community contributed tool that generates proxy classes that help manage the lifetimes of the proxy objects. As you might guess from the name the primary way that the proxy class helps manage object lifetimes is to deal with factories and proxies that have encountered a communication exception.
You can also get two videos that go along with the tool and help explain proxy management:
It looks like this is still a work in progress so the code has changed somewhat since the videos were made. Since these are generated classes however, you do get a chance to look at and play with any part of it you’d like.
How do I setup a test environment for a service that is using HTTPS? Certificate validation fails because the test machine doesn’t have the right machine name.
Included in the definition of a certificate is the fully qualified domain name that you gave to the certificate authority when the certificate was created. This definition is incorporated into the signature of the certificate so there’s no way to change the certificate without being issued a new one.
The certificate can then only be used with a machine of that particularly signed name or else a name mismatch error occurs. There is some additional flexibility if the certificate you’re using is a wildcard certificate, but you still won’t be able to use in a test setup as the address of the service the IP address, localhost, or other domain names besides the one that the certificate was created for.
Instead, to test the HTTPS service you need to make the certificate appear acceptable. There’s two ways to do that.
The first way to make the certificate acceptable is to tell the machine to trust you. In a test environment you control both of the machines communicating. This means you can create your self-signed certificate and install a new trusted root certificate authority telling the machine to trust the certificates that you’ve signed.
The second way to make the certificate acceptable is to override how the application checks the certificate. The System.Net.ServicePointManager class has a property called ServerCertificateValidationCallback, to which you can install your own validation routine. The validation routine is an implementation of the RemoteCertificateValidationCallback delegate.
public delegate bool RemoteCertificateValidationCallback ( Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors )
If you write a validation callback that returns true, then you can install that callback on the test machine to use certificates even if they don’t pass the normal validation logic.
The next version of Silverlight is now available. I had a series of articles back in April listing off some of the new features in the beta release including runnning Silverlight applications outside the browser, media features, and of course improvements to the version of WCF we ported to Silverlight. You can read a more detailed list of new features on the Silverlight site.
I’ve been thinking about switching at least part of the time to a new format that updates less frequently but covers topics in more depth.
That would allow me to put together in a single shot what I currently have to do in multipart series.
A longer format would also allow me to bring together past articles on related topics into unified guides.
Is having less frequent but more detailed coverage something you’d be interested in instead of the current arrangement of frequent but short articles? Are there particular topics you’d like to see done in the longer format?
A beta release of the Web Services Contract First tool is available on CodePlex. This is a Visual Studio 2008 add-in targetting WCF made by the same group in the web services community that did a tool of the same name for ASMX (to tell the two apart, the WCF version is called WSCF Blue while the ASMX version is now called WSCF Classic).
The basic idea of contract first development is the same though, which is to start work from the description or specification of the service, such as WSDL or XSD, rather than a service contract captured in code. If you’re developing integration with an existing service then you’re probably doing at least some contract first development. If you’re building new services then you might or might not be familiar with the style. The tooling then provides features in support of contract first development, such as stub and code generation and wizards to work with contract descriptions without having to know all of the intricacies of the specification languages.
In the recommendation for designing versionable contract names, there was no mention of the deployment environment of the service. Should this be included by, for example, having different namespaces for development and production deployments of the service?
I generally don’t recommend including the deployment environment in the contract name. Instead, base the versioning scheme on the technical compatibility of the two implementations. As a service moves between development, testing, and production deployments, keep the same name if the implementation is stable and use a different name when the implementation changes.
There are a few reasons for this:
You want to be able to test exactly what will be used in production. Even supposedly insignificant changes can introduce defects. There should be no difference between using a namespace that contains the word “test” and a namespace that contains the word “final”. However, what if some library that’s being used has a size limit for the namespace and adding one character causes it to stop working? What if someone’s written some debugging code that’s looking for the word “test” to appear?
After initial deployment of the system, the transition between environments is likely to be haphazard. If you’re working on a bug for a specific component you might have a few of the services running locally, a few deployed somewhere else, and for the components that you’re not working on, using data from the actual production services. Having a mishmash of names as you pull parts of the system from one environment to another can be error prone.
Changing names adds another task to the list of steps needed to move between environments. Many systems already have a fairly extensive task list to perform during deployment. Simplifying this process is always appreciated, particularly if the tasks are difficult to automate or require special skills. It may be easy for you to remember how to create a special build with the right options set for the staging environment, but a lab technician or new developer coming in is going to have to learn all of that too before they can be productive.
After creating a WCF service application in Visual Studio you might have noticed that the project configuration has three choices of web servers for testing the application:
The development server (coming from a heritage of web server samples called Cassini) exists to make it really easy to work on your application without having a machine configured to service requests. The development server is not intended to be the actual host for your service. There’s a lot of things that the development server doesn’t try to support. By the time you want people to start using your service you should be self hosting the service or get a real server to run it in.
Do I need IIS7 to use binary with HTTP for WCF?
No, all you need is a custom binding because we don’t include a standard binding with that configuration out of the box.
Here’s a quick example of putting binary and HTTP together with either code or configuration:
BinaryMessageEncodingBindingElement encoding = new BinaryMessageEncodingBindingElement();HttpTransportBindingElement transport = new HttpTransportBindingElement();Binding binding = new CustomBinding(encoding, transport);
<bindings><customBinding><binding name="BinaryHttpBinding"><binaryMessageEncoding /><httpTransport /></binding></customBinding></bindings>
You could also make a subclass of Binding if you didn’t want to build a custom binding every time, but no special version of IIS is required.