У меня есть приложение службы WCF (wsHttpBinding), размещенное в IIS7.5 (.NET 4), и я могу перемещаться по файлу .svc в браузере, и страница метаданных успешно отображается, и клиенты могут быть сгенерированы из wsdl.

Я добавил свое собственное поведение службы для регистрации необработанных исключений («ErrorHandling» ниже), и я использую MembershipProvider для учетных данных службы. Вот моя полная конфигурация system.serviceModel:

<system.serviceModel>
  <diagnostics wmiProviderEnabled="true">
    <messageLogging
      logEntireMessage="true"
      logMalformedMessages="true"
      logMessagesAtServiceLevel="true"
      logMessagesAtTransportLevel="true"
      maxMessagesToLog="3000"
      maxSizeOfMessageToLog="-1" />
  </diagnostics>
  <extensions>
    <behaviorExtensions>
      <add name="ErrorHandling" type="MyCompany.MyProduct.Services.ErrorHandlerBehavior, MyCompany.MyProduct.Services" />
    </behaviorExtensions>
  </extensions>
  <services>
    <service name="MyCompany.MyProduct.Services.ApplicationService" behaviorConfiguration="MyProductServiceBehavior">
      <endpoint bindingConfiguration="MyProductWsHttpBinding" binding="wsHttpBinding" contract="MyCompany.MyProduct.Services.IApplicationService" />
    </service>
    <service name="MyCompany.MyProduct.Services.AccountService" behaviorConfiguration="MyProductServiceBehavior">
      <endpoint bindingConfiguration="MyProductWsHttpBinding" binding="wsHttpBinding" contract="MyCompany.MyProduct.Services.IAccountService" />
    </service>
    <service name="MyCompany.MyProduct.Services.InvoiceService" behaviorConfiguration="MyProductServiceBehavior">
      <endpoint bindingConfiguration="MyProductWsHttpBinding" binding="wsHttpBinding" contract="MyCompany.MyProduct.Services.IInvoiceService" />
    </service>
    <service name="MyCompany.MyProduct.Services.ReportService" behaviorConfiguration="MyProductServiceBehavior">
      <endpoint bindingConfiguration="MyProductWsHttpBinding" binding="wsHttpBinding" contract="MyCompany.MyProduct.Services.IReportService" />
    </service>
    <service name="MyCompany.MyProduct.Services.PaymentService" behaviorConfiguration="MyProductServiceBehavior">
      <endpoint bindingConfiguration="MyProductWsHttpBinding" binding="wsHttpBinding" contract="MyCompany.MyProduct.Services.IPaymentService" />
    </service>
  </services>
  <bindings>
    <wsHttpBinding>
      <binding name="MyProductWsHttpBinding">
        <security mode="Message">
          <message clientCredentialType="UserName" establishSecurityContext="true" negotiateServiceCredential="true" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MyProductServiceBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceCredentials>
          <serviceCertificate findValue="MyProductServices" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" />
          <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="AspNetSqlMembershipProvider" />
        </serviceCredentials>
        <ErrorHandling />
        <serviceSecurityAudit auditLogLocation="Application" suppressAuditFailure="false" serviceAuthorizationAuditLevel="SuccessOrFailure" messageAuthenticationAuditLevel="SuccessOrFailure" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
</system.serviceModel>

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

У меня также включена трассировка:

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel"
            switchValue="All"
            propagateActivity="true" >
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
    <source name="System.ServiceModel.MessageLogging" switchValue="All">
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
    <source name="myUserTraceSource"
            switchValue="Information, ActivityTracing">
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add name="xml"
         type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="C:\Users\Public\Documents\services.svclog" />
  </sharedListeners>
</system.diagnostics>

Когда клиент вызывает основную операцию в первичной службе, он получает исключение протокола с этим сообщением:

Тип содержимого text / html; charset = UTF-8 ответного сообщения не соответствует типу содержимого привязки (application / soap + xml; charset = utf-8). При использовании настраиваемого кодировщика убедитесь, что метод IsContentTypeSupported реализован правильно. Первые 1024 байта ответа были: '#content {FONT-SIZE: 0.7em; НАПОЛНИТЕЛЬ-НИЖНИЙ: 2em; MARGIN-LEFT: 30px} BODY {MARGIN-TOP: 0px; ПОЛЯ-СЛЕВА: 0 пикселей; ЦВЕТ: # 000000; FONT-FAMILY: Verdana; ЦВЕТ ФОНА: белый} P {ВЕРХНЯЯ ПОЛЯ: 0px; ПОЛЯ-НИЖНИЙ: 12 пикселей; ЦВЕТ: # 000000; FONT-FAMILY: Verdana} PRE {BORDER-RIGHT: # f0f0e0 1px solid; НАБИВКА-ПРАВАЯ: 5 пикселей; BORDER-TOP: # f0f0e0 1px solid; MARGIN-TOP: -5px; НАПОЛНИТЕЛЬ-СЛЕВА: 5 пикселей; РАЗМЕР ШРИФТА: 1.2em; НАПОЛНИТЕЛЬ-НИЖНИЙ: 5 пикселей; ЛЕВАЯ ГРАНИЦА: # f0f0e0 1px solid; НАПОЛНИТЕЛЬНЫЙ ВЕРХ: 5 пикселей; ГРАНИЦА-НИЖНИЙ: # f0f0e0 1px solid; FONT-FAMILY: Courier New; ЦВЕТ ФОНА: # e5e5cc} .heading1 {MARGIN-TOP: 0px; НАПОЛНИТЕЛЬ-СЛЕВА: 15 пикселей; ВЕС ШРИФТА: нормальный; РАЗМЕР ШРИФТА: 26 пикселей; ПОЛЯ-НИЖНИЙ: 0 пикселей; НАПОЛНИТЕЛЬ-НИЖНИЙ: 3px; ПОЛЯ-СЛЕВА: -30 пикселей; ШИРИНА: 100%; ЦВЕТ: #ffffff; PADDING-TOP: 10 пикселей; ФОНТ-СЕМЬЯ: Тахома; ЦВЕТ ФОНА: # 003366} .intro {MARGIN-LEFT: -15px} ApplicationService Service '.

Это HTML-код страницы метаданных, которую вы видите при переходе к файлу .svc. Таким образом, создается впечатление, что служба возвращает эту страницу в качестве ответа на операцию.

Просмотр services.svclog рассказывает ту же историю, на самом деле журнал имеет неверный формат xml, потому что этот ответ включен в него без экранирования тегов. Нет никакой полезной информации, так что когда-либо в трассировке.

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

Какие инструменты и методы могут помочь мне выяснить, в чем корень проблемы?

http://pastebin.com/mksL0FFY

4
WheatControm 26 Авг 2011 в 21:16

2 ответа

Лучший ответ

Проверьте правила перезаписи URL-адресов в IIS для сайта. Если один из них выполняет перенаправление, это может привести к тому, что клиенты получат страницу метаданных в качестве ответа на операцию. Я видел такое раньше, это может ввести в заблуждение.

0
sethdeckard 8 Сен 2011 в 16:46

Поскольку журнал событий пуст, вам следует проверить журнал IIS, чтобы убедиться, что вызов выполнен успешно. У меня были похожие сообщения об ошибках, и проблема обычно была связана с разрешениями. Убедитесь, что учетные записи, используемые для пула приложений и веб-сайта, имеют достаточные привилегии. Я думаю, вы бы увидели сообщение журнала событий, если бы возникла проблема с аутентификацией у поставщика членства. Кроме того, попробуйте вызвать метод с помощью приложения WcfTestClient, чтобы вы могли видеть, как XML передается в разные стороны.

1
Richard 6 Сен 2011 в 22:59