Поделиться через


Краткое руководство по быстрому устранению неполадок WCF

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

  1. После установки Windows 7 и IIS при попытке перейти к службе WCF я получаю следующее сообщение об ошибке: HTTP Error 404.3 — Not Found

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

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

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

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

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

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

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

  8. Я использую сертификат X.509 с моей службой, и я получаю System.Security.Cryptography.CryptographicException. Что происходит?

  9. Я изменил первый параметр операции с верхнего регистра на нижний регистр; теперь мой клиент выдает исключение. Что происходит?

  10. Я использую один из моих средств трассировки, и я получаю EndpointNotFoundException. Что происходит?

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

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

После установки Windows 7 и IIS при попытке перейти к службе WCF я получаю следующее сообщение об ошибке: HTTP Error 404.3 — Not Found

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

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

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

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

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

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

По умолчанию службы могут иметь только 10 одновременных сеансов. Таким образом, если привязки службы используют сеансы, служба принимает новые клиентские подключения до тех пор, пока не достигнет этого числа, после чего она перестает принимать новые клиентские подключения до тех пор, пока не завершится один из текущих сеансов. Вы можете поддерживать больше клиентов несколькими способами. Если служба не требует сеансов, не используйте сеансовую привязку. (Дополнительные сведения см. в разделе Using Session.) Другой вариант — увеличить ограничение сеанса 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.

  • Возможно, потребуется открыть порт для приложения. Дополнительные сведения см. в разделе "Инструкции по брандмауэру " из примеров пакета 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. Эту команду можно выполнить, чтобы создать окно команд в учетной записи системы:

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

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

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

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

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

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

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

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

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

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

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

Я использую сертификат X.509 с моей службой, и я получаю System.Security.Cryptography.CryptographicException. Что происходит?

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

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

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

Общий доступ к порту между конечной точкой службы и конечной точкой mex с помощью 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: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 из приложения WCF SOAP служба возвращает следующую ошибку: метод 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);  
    }  
}  

См. также