Udostępnij za pośrednictwem


WCF Troubleshooting Quickstart

This topic lists a number of known issues customers have run into while developing WCF clients and services. If the issue you are running into is not in this list, we recommend you configure tracing for your service. This will generate a trace file that you can view with the trace file viewer and get detailed information about exceptions that may be occurring within the service. For more information on configuring tracing, see: Configuring Tracing. For more information on the trace file viewer, see: Service Trace Viewer Tool (SvcTraceViewer.exe).

  1. Sometimes I receive a MessageSecurityException on the second request if my client is idle for a while after the first request. What is happening?

  2. My service starts to reject new clients after about 10 clients are interacting with it. What is happening?

  3. Can I load my service configuration from somewhere other than the WCF application’s configuration file?

  4. My service and client work great, but I can’t get them to work when the client is on another computer? What’s happening?

  5. When I throw a FaultException<Exception> where the type is an exception, I always receive a general FaultException type on the client and not the generic type. What’s happening?

  6. It seems like one-way and request-reply operations return at roughly the same speed when the reply contains no data. What's happening?

  7. I’m using an X.509 certificate with my service and I get a System.Security.Cryptography.CryptographicException. What’s happening?

  8. I changed the first parameter of an operation from uppercase to lowercase; now my client throws an exception. What's happening?

  9. I’m using one of my tracing tools and I get an EndpointNotFoundException. What’s happening?

What is the base address? How does it relate to an endpoint address?

Sometimes I receive a MessageSecurityException on the second request if my client is idle for a while after the first request. What is happening?

The second request can fail primarily for two reasons: (1) the session has timed out or (2) the Web server that is hosting the service is recycled. In the first case, the session is valid until the service times out. When the service does not receive a request from the client within the period of time specified in the service's binding (ReceiveTimeout), the service terminates the security session. Subsequent client messages result in the MessageSecurityException. The client must re-establish a secure session with the service to send future messages or use a stateful security context token. Stateful security context tokens also allow a secure session to survive a Web server being recycled. For more information about using stateful secure context tokens in a secure session, see How to: Create a Security Context Token for a Secure Session. Alternatively, you can disable secure sessions. When you use the <wsHttpBinding> binding, you can set the establishSecurityContext property to false to disable secure sessions. To disable secure sessions for other bindings, you must create a custom binding. For details about creating a custom binding, see How to: Create a Custom Binding Using the SecurityBindingElement. Before you apply any of these options, you must understand your application's security requirements.

My service starts to reject new clients after about 10 clients are interacting with it. What is happening?

By default, services can have only 10 concurrent sessions. Therefore, if the service bindings use sessions, the service accepts new client connections until it reaches that number, after which it refuses new client connections until one of the current sessions ends. You can support more clients in a number of ways. If your service does not require sessions, do not use a sessionful binding. (For more information, see Using Sessions.) Another option is to increase the session limit by changing the value of the MaxConcurrentSessions property to the number appropriate to your circumstance.

Can I load my service configuration from somewhere other than the WCF application’s configuration file?

Yes, however, you have to create a custom ServiceHost class that overrides the ApplyConfiguration method. Inside that method, you can call the base to load configuration first (if you want to load the standard configuration information as well) but you can also entirely replace the configuration loading system. Note that if you want to load configuration from a configuration file that is different from the application configuration file, you must parse the configuration file yourself and load the configuration.

The following code example shows how to override the ApplyConfiguration method and directly configure an endpoint.

public class MyServiceHost : ServiceHost
{
  public MyServiceHost(Type serviceType, params Uri[] baseAddresses)  
    : base(serviceType, baseAddresses)
  { Console.WriteLine("MyServiceHost Constructor"); }

  protected override void ApplyConfiguration()
  {
    string straddress = GetAddress();
    Uri address = new Uri(straddress);
    Binding binding = GetBinding();
    base.AddServiceEndpoint(typeof(IData), binding, address);
  }

  string GetAddress()
  { return "http://MyMachine:7777/MyEndpointAddress/"; }

  Binding GetBinding()
  {
    WSHttpBinding binding = new WSHttpBinding();
    binding.Security.Mode = SecurityMode.None;
    return binding;
  }
}

My service and client work great, but I can’t get them to work when the client is on another computer? What’s happening?

Depending upon the exception, there may be several issues:

  • You might need to change the client endpoint addresses to the host name and not "localhost".

  • You might need to open the port to the application. For details, see Firewall Instructions from the SDK samples.

  • For other possible issues, see the samples topic Running the Samples in a Workgroup and Across Machines.

  • If your client is using Windows credentials and the exception is a SecurityNegotiationException, configure Kerberos as follows.

    1. Add the identity credentials to the endpoint element in the client’s App.config file:

      <endpoint 
        address="http://MyServer:8000/MyService/" 
        binding="wsHttpBinding" 
        bindingConfiguration="WSHttpBinding_IServiceExample" 
        contract="IServiceExample" 
        behaviorConfiguration="ClientCredBehavior" 
        name="WSHttpBinding_IServiceExample">
        <identity>
          <userPrincipalName value="name@corp.contoso.com"/>
        </identity>
      </endpoint>
      
    2. Run the self-hosted service under the System or NetworkService account. You can run this command to create a command window under the System account:

      at 12:36  /interactive "cmd.exe"
      
    3. Host the service under Internet Information Services (IIS), which, by default, uses the service principal name (SPN) account.

    4. Register a new SPN with the domain using SetSPN. Note that you will need to be a domain administrator in order to do this.

For more information about the Kerberos protocol, see Security Concepts Used in WCF and:

When I throw a FaultException<Exception> where the type is an exception, I always receive a general FaultException type on the client and not the generic type. What’s happening?

It is highly recommended that you create your own custom error data type and declare that as the detail type in your fault contract. The reason is that using system-provided exception types:

If you are debugging an application, however, you can serialize exception information and return it to the client by using the ServiceDebugBehavior class.

It seems like one-way and request-reply operations return at roughly the same speed when the reply contains no data. What's happening?

Specifying that an operation is one way means only that the operation contract accepts an input message and does not return an output message. In WCF, all client invocations return when the outbound data has been written to the wire or an exception is thrown. One-way operations work the same way, and they can throw if the service cannot be located or block if the service is not prepared to accept the data from the network. Typically in WCF, this results in one-way calls returning to the client more quickly than request-reply; but any condition that slows the sending of the outbound data over the network slows one-way operations as well as request-reply operations. For more information, see One-Way Services and Accessing Services Using a Client.

I’m using an X.509 certificate with my service and I get a System.Security.Cryptography.CryptographicException. What’s happening?

This commonly occurs after changing the user account under which the IIS worker process runs. For example, in Windows XP, if you change the default user account that the Aspnet_wp.exe runs under from ASPNET to a custom user account, you may see this error. If using a private key, the process that uses it will need to have permissions to access the file storing that key.

If this is the case, you must give read access privileges to the process's account for the file containing the private key. For example, if the IIS worker process is running under the Bob account, then you will need to give Bob read access to the file containing the private key.

For more information about how to give the correct user account access to the file that contains the private key for a specific X.509 certificate, see How to: Make X.509 Certificates Accessible to WCF.

I changed the first parameter of an operation from uppercase to lowercase; now my client throws an exception. What's happening?

The value of the parameter names in the operation signature are part of the contract and are case-sensitive. Use the System.ServiceModel.MessageParameterAttribute attribute when you need to distinguish between the local parameter name and the metadata that describes the operation for client applications.

I’m using one of my tracing tools and I get an EndpointNotFoundException. What’s happening?

If you are using a tracing tool that is not the system-provided WCF tracing mechanism and you receive an EndpointNotFoundException that indicates that there was an address filter mismatch, you need to use the ClientViaBehavior class to direct the messages to the tracing utility and have the utility redirect those messages to the service address. The ClientViaBehavior class alters the Via addressing header to specify the next network address separately from the ultimate receiver, indicated by the To addressing header. When doing this, however, do not change the endpoint address, which is used to establish the To value.

The following code example shows an example client configuration file.

<endpoint 
  address=https://localhost:8000/MyServer/
  binding="wsHttpBinding"
  bindingConfiguration="WSHttpBinding_IMyContract"
  behaviorConfiguration="MyClient" 
  contract="IMyContract" 
  name="WSHttpBinding_IMyContract">
</endpoint>
<behaviors>
  <endpointBehaviors>
    <behavior name="MyClient">
      <clientVia viaUri="https://localhost:8001/MyServer/"/>
    </behavior>
  </endpointBehaviors>
</behaviors>

What is the base address? How does it relate to an endpoint address?

A base address is the root address for a ServiceHost class. By default, if you add a ServiceMetadataBehavior class into your service configuration, the Web Services Description Language (WSDL) for all endpoints the host publishes are retrieved from the HTTP base address, plus any relative address provided to the metadata behavior, plus "?wsdl". If you are familiar with ASP.NET and IIS, the base address is equivalent to the virtual directory.

Sharing a port between a service endpoint and a mex endpoint using the NetTcpBinding

If you specify the base address for a service as net.tcp://MyServer:8080/MyService and add the following endpoints:

<services>
      <service name="Microsoft.Samples.NetTcp.CalculatorService">
        <endpoint address="calcsvc" binding ="netTcpBinding" contract="Microsoft.Samples.NetTcp.ICalculator"/>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>

And if you modify one of the NetTcpBinding settings as shown in the following configuration snippet:

<bindings>
      <netTcpBinding>
        <binding closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="11" maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>

You will see an error like the following: Unhandled Exception: System.ServiceModel.AddressAlreadyInUseException: There is already a listener on IP endpoint 0.0.0.0:9000 You can work around this error by specifying a fully qualified URL with a different port for the MEX endpoint as shown in the following configuration snippet:

<services>
      <service name="Microsoft.Samples.NetTcp.CalculatorService">
        <endpoint address="calcsvc" binding ="netTcpBinding" contract="Microsoft.Samples.NetTcp.ICalculator"/>
        <endpoint address="net.tcp://localhost:9001/servicemodelsamples/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>

See Also

Concepts

Debugging Windows Authentication Errors