Примеры устранения неполадок WCF

В этом разделе приведено несколько известных проблем, с которыми столкнулись пользователи при разработке клиентов и служб WCF. Если проблема, с которой столкнулись вы, отсутствует в этом списке, рекомендуется настроить трассировку для данной службы. При этом будет создан файл трассировки, который можно просмотреть с помощью средства просмотра файлов трассировки и получить подробные сведения об исключениях, которые могут возникать в службе. Дополнительные сведения о настройке трассировки см. в разделе Configuring Tracing. Дополнительные сведения о средстве просмотра файлов трассировки см. в разделе Service Trace Viewer Tool (SvcTraceViewer.exe).

  1. После установки Windows 7 и IIS при попытке перейти к службе WCF выдается следующее сообщение об ошибке: «Ошибка HTTP 404.3 - не найдено»

    Ошибка HTTP 404.3 - не найдено. Запрашиваемая страница не может быть выдана из-за конфигурации расширения. Если страница - скрипт, добавьте обработчик. Если файл должен загружаться, добавьте MIME-сопоставление. Подробное описание ошибки InformationModule StaticFileModule.

  2. Иногда при втором запросе возникает исключение MessageSecurityException, если клиент бездействует некоторое время после первого запроса. Что происходит?

  3. Когда со службой взаимодействует около 10 клиентов, она отклоняет подключение новых клиентов. Что происходит?

  4. Можно ли загружать конфигурацию службы из расположения, отличного от файла конфигурации приложения WCF?

  5. Служба и клиент работают нормально, но их не удается запустить, если клиент находится на другом компьютере. В чем причина?

  6. При вызове исключения> FaultException, в котором тип является исключением, я всегда получаю общий тип FaultException<на клиенте, а не универсальный тип. В чем причина?

  7. Создается впечатление, что односторонние операции, а также операции запроса-ответа возвращаются примерно с той же скоростью, что и ответы без данных. Что происходит?

  8. В службе используется сертификат X.509, при этом получается исключение System.Security.Cryptography.CryptographicException. В чем причина?

  9. В имени первого параметра операции прописные буквы были заменены на строчные, и теперь в клиенте выдается исключение. Что происходит?

  10. При использовании одного из средств трассировки получено исключение EndpointNotFoundException. В чем причина?

  11. При вызове веб-приложения HTTP WCF из приложения службы протокола SOAP WCF возвращается следующая ошибка: «405 Метод запрещен»

Что такое базовый адрес? Как он связан с адресом конечной точки?

После установки Windows 7 и IIS при попытке перейти к службе WCF выдается следующее сообщение об ошибке: «Ошибка HTTP 404.3 - не найдено»

Полный текст сообщения об ошибке:

Ошибка HTTP 404.3 - не найдено. Запрашиваемая страница не может быть выдана из-за конфигурации расширения. Если страница - скрипт, добавьте обработчик. Если файл должен загружаться, добавьте MIME-сопоставление. Подробное описание ошибки InformationModule StaticFileModule.

Это сообщение об ошибке возникает, когда в панель управления не задано явное значение "Активация HTTP в Windows Communication Foundation". Чтобы задать этот пункт панель управления, щелкните "Программы" в левом нижнем углу окна. Установите переключатель «Включение компонентов Windows». Разверните элемент Microsoft .NET Framework 3.5.1 и выберите «Активация Windows Communication Foundation по HTTP».

Иногда при втором запросе возникает исключение MessageSecurityException, если клиент бездействует некоторое время после первого запроса. Что происходит?

Сбой второго запроса может произойти по двум причинам: (1) истекло время ожидания сеанса или (2) перезапущен веб-сервер, на котором размещена служба. В первом случае сеанс действителен до истечения времени ожидания службы. Если служба не получает запрос от клиента в течение периода времени, указанного в привязке службы (ReceiveTimeout), служба завершает сеанс безопасности. Последующие сообщения клиента приводят к исключению MessageSecurityException. Клиент должен повторно установить безопасный сеанс со службой, чтобы отправлять будущие сообщения, или использовать маркер контекста безопасности с отслеживанием состояния. Токены контекста безопасности с отслеживанием состояния также позволяют защитить сеанс во время перезапуска веб-сервера. Дополнительные сведения об использовании маркеров безопасного контекста с отслеживанием состояния в безопасном сеансе см. в разделе "Практическое руководство. Создание маркера контекста безопасности для безопасного сеанса". Кроме того, можно отключить безопасные сеансы. При использовании привязки <wsHttpBinding> можно задать establishSecurityContext для свойства false отключение безопасных сеансов. Чтобы отключить безопасные сеансы для других привязок, необходимо создать пользовательскую привязку. Подробные сведения о создании пользовательской привязки см. в разделе How to: Create a Custom Binding Using the SecurityBindingElement. Перед применением этих параметров необходимо разобраться с требованиями безопасности приложения.

Когда со службой взаимодействует около 10 клиентов, она отклоняет подключение новых клиентов. Что происходит?

По умолчанию службы поддерживают не более 10 параллельных сеансов. Поэтому при использовании в привязках службы сеансов, служба принимает подключения новых клиентов до достижения этого числа. После этого служба отклоняет подключения новых клиентов, пока не будет закрыт один из текущих сеансов. Поддержку большего количества клиентов можно обеспечить несколькими способами. Если для службы не требуются сеансы, не используйте сеансовую привязку. (Дополнительные сведения см. в разделе Использование сеансов.) Другой вариант — увеличить ограничение сеанса MaxConcurrentSessions , изменив значение свойства на число, соответствующее вашему обстоятельству.

Можно ли загружать конфигурацию службы из расположения, отличного от файла конфигурации приложения WCF?

Да, но необходимо создать пользовательский класс ServiceHost , переопределяющий метод ApplyConfiguration . Внутри этого метода можно вызвать базовый класс, чтобы сначала загрузить конфигурацию (если дополнительно требуется загрузить сведения о стандартной конфигурации), но можно также полностью заменить систему загрузки конфигурации. Если вы хотите загрузить конфигурацию из файла конфигурации, отличного от файла конфигурации приложения, необходимо проанализировать файл конфигурации самостоятельно и загрузить конфигурацию.

В следующем примере кода показано, как переопределить метод ApplyConfiguration и напрямую настроить конечную точку.

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;  
    }  
}  

Служба и клиент работают нормально, но их не удается запустить, если клиент находится на другом компьютере. В чем причина?

В зависимости от исключения возможны следующие причины.

  • Возможно, потребуется использовать для адреса конечной точки клиента имя узла, а не "localhost".

  • Возможно, для приложения потребуется открыть порт. Дополнительные сведения см. в разделе Firewall Instructions примеров SDK.

  • Дополнительные сведения о других возможных проблемах см. в разделе примеров, в котором выполняются примеры Windows Communication Foundation.

  • Если в клиенте используются учетные данные Windows и создается исключение SecurityNegotiationException, настройте Kerberos, как указано ниже.

    1. Добавьте учетные данные идентификации в элемент конечной точки в файле конфигурации клиента App.config.

      <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. Для этого запустите службу от имени учетной записи System или NetworkService. Чтобы создать командное окно в учетной записи System, выполните следующую команду.

      at 12:36 /interactive "cmd.exe"  
      
    3. Разместите службу в службах IIS, которые по умолчанию используют учетную запись имени участника службы (SPN).

    4. Зарегистрируйте в домене новое имя участника службы (SPN) с помощью программы SetSPN. Для этого необходимо быть администратором домена.

Дополнительные сведения о протоколе Kerberos см. в разделе "Основные понятия безопасности", используемые в WCF и:

При вызове исключения> FaultException, в котором тип является исключением, я всегда получаю общий тип FaultException<на клиенте, а не универсальный тип. В чем причина?

Настоятельно рекомендуется создать свой собственный пользовательский тип данных об ошибке и объявить его в качестве типа сведений в контракте сбоя. Это необходимо, так как при использовании типов исключений, предоставляемых системой, могут возникнуть следующие проблемы.

  • Создается зависимость типов, которая не дает возможности воспользоваться одним из главных преимуществ приложений, ориентированных на службы.

  • Не удается воспользоваться стандартной сериализацией исключений. Некоторые из них, например SecurityException, могут вообще не сериализоваться.

  • Внутренние сведения сериализации доступны для клиентов. Дополнительные сведения см. в разделе "Указание и обработка ошибок" в контрактах и службах.

Однако при отладке приложения можно сериализовать сведения об исключении и возвратить их клиенту с помощью класса ServiceDebugBehavior .

Создается впечатление, что односторонние операции, а также операции запроса-ответа возвращаются примерно с той же скоростью, что и ответы без данных. Что происходит?

Если указывается, что операция является односторонней, это лишь означает, что контракт операции принимает входящее сообщение и не возвращает выходное сообщение. В WCF все вызовы клиента возвращаются, когда исходящие данные записываются в провод или возникает исключение. Односторонние операции выполняются таким же образом, и они могут создавать исключение, если не удается обнаружить службу, или заблокировать выполнение, если служба не готова к приему данных из сети. Как правило, в WCF это приводит к одностороннему вызову, возвращающимся клиенту быстрее, чем запрос-ответ; но любое условие, замедляющее отправку исходящих данных по сети, замедляет одностороннее выполнение операций, а также операций ответа на запрос. Дополнительные сведения см. в разделе "Односторонние службы" и "Доступ к службам" с помощью клиента WCF.

В службе используется сертификат X.509, при этом получается исключение System.Security.Cryptography.CryptographicException. В чем причина?

Обычно это происходит после изменения учетной записи пользователя, в которой выполняется рабочий процесс IIS. Например, в Windows XP, если изменить учетную запись пользователя по умолчанию, которая Aspnet_wp.exe выполняется из ASPNET в пользовательскую учетную запись, может появиться эта ошибка. Если используется закрытый ключ, его процесс должен иметь разрешение для доступа к файлу с этим ключом.

В этом случае необходимо предоставить учетной записи процесса права доступа для чтения файла с закрытым ключом. Например, если рабочий процесс IIS выполняется в учетной записи Бориса, ему необходимо предоставить права доступа для чтения файла, содержащего закрытый ключ.

Дополнительные сведения о том, как предоставить правильный доступ к учетной записи пользователя к файлу, который содержит закрытый ключ для определенного сертификата X.509, см. в разделе "Практическое руководство. Предоставление доступа к сертификатам X.509 для WCF".

В имени первого параметра операции прописные буквы были заменены на строчные, и теперь в клиенте выдается исключение. Что происходит?

Значения имен параметров в сигнатуре операции являются частью контракта и чувствительны к регистру. Используйте атрибут System.ServiceModel.MessageParameterAttribute , чтобы различать имя локального параметра и метаданные, описывающие операцию для клиентских приложений.

При использовании одного из средств трассировки получено исключение EndpointNotFoundException. В чем причина?

Если вы используете средство трассировки, которое не является системным механизмом трассировки WCF, и вы получаете EndpointNotFoundException сообщение о несоответствии фильтра адресов, необходимо использовать ClientViaBehavior класс для перенаправления сообщений в программу трассировки и перенаправления этих сообщений в адрес службы. Класс ClientViaBehavior изменяет заголовок адресации Via , чтобы задать следующий сетевой адрес отдельно от конечного получателя, указанного заголовком адресации To . Однако при этом не следует изменять адрес конечной точки, используемый для установки значения To .

В следующем примере кода показан пример файла конфигурации клиента.

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

Что такое базовый адрес? Как он связан с адресом конечной точки?

Базовый адрес - это корневой адрес для класса ServiceHost . По умолчанию, если в конфигурацию службы добавлен класс ServiceMetadataBehavior , язык описания веб-служб (WSDL) для всех конечных точек, публикуемых узлом, извлекается из базового HTTP-адреса, относительного адреса, предоставленного поведением метаданных, а также "?wsdl". Если вы знакомы с ASP.NET и IIS, базовый адрес эквивалентен виртуальному каталогу.

Совместное использование порта конечными точками службы и обмена метаданными при помощи NetTcpBinding

Если указать в качестве адреса базы службы net.tcp://MyServer:8080/MyService и добавить следующие конечные точки:

<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>  

А если модифицировать один из параметров NetTcpBinding, как показано в следующем фрагменте конфигурации:

<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>  

Вы увидите ошибку, как показано ниже: Необработанное исключение: System.ServiceModel.AddressAlreadyInUseException: в конечной точке IP 0.0.0.0.0:9000 вы можете обойти эту ошибку, указав полный URL-адрес с другим портом для конечной точки MEX, как показано в следующем фрагменте кода конфигурации:

<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>  

При вызове веб-приложения HTTP WCF из приложения службы протокола SOAP WCF возвращается следующая ошибка: «405 Метод запрещен»

Вызов веб-HTTP-приложения WCF (службы, использующей WebHttpBinding и WebHttpBehavior) из службы WCF, может создать следующее исключение: Unhandled Exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: The remote server returned an unexpected response: (405) Method Not Allowed. это исключение возникает из-за того, что WCF перезаписывает исходящую OperationContext с входящей OperationContext. Чтобы решить эту проблему, создайте OperationContextScope в рамках операции веб-службы WCF Web HTTP. Например:

public string Echo(string input)  
{  
    using (new OperationContextScope(this.InnerChannel))  
    {  
        return base.Channel.Echo(input);  
    }  
}  

См. также