Служба WCF возвращает 404 по https, но не http

Я переношу существующий сервис из HTTP (Dev/UAT) в HTTPS (Production), и у меня возникают проблемы с конфигурацией. Вот раздел system.serviceModel моего web.config:

<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
    <services>
      <service name="MyService">
        <endpoint name="MyEndpoint" address="" binding="wsHttpBinding"
            bindingConfiguration="secureBinding" contract="IMyService" />
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="secureBinding">
          <security mode="Transport"></security>
        </binding>
      </wsHttpBinding>
    </bindings>
</system.serviceModel>

Я пробовал это, используя как basicHttpBinding, так и wsHttpBinding, с теми же результатами:

  • Я могу позвонить службе с моего клиента SOAP с помощью http://server.domain.com/MyService.svc
  • Я могу воспользоваться службой из браузера, используя https://server.domain.com/MyService.svc
  • Я не могу позвонить службе с моего клиента SOAP с помощью https://server.domain.com/MyService.svc - всегда вызываются ошибки с 404: not found.

Мой сайт https сертифицирован с использованием сертификата, который был выпущен центром сертификации в корпоративном домене, и я подтвердил, что у меня есть сертификат CA, установленный в Trusted Root Certification Authorities в системе, из которой я звоню.

Соответствующий код клиента:

Service service = new Service();
service.Url = "http://server.domain.com/MyService.svc";
//service.Url = "https://server.domain.com/MyService.svc";
service.WebMethodCall();

ИЗМЕНИТЬ

Вот запрошенные части WSDL:

<wsdl:types/>
<wsdl:portType name="IMyService"/>
<wsdl:binding name="BasicHttpBinding_IMyService" type="tns:IMyService">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
</wsdl:binding>
<wsdl:service name="MyService">
    <wsdl:port name="BasicHttpBinding_IMyService" 
        binding="tns:BasicHttpBinding_IMyService">
        <soap:address location="http://server.domain.com/MyService.svc"/>
    </wsdl:port>
</wsdl:service>

ИЗМЕНИТЬ

Дополнительная информация:

Когда я изменяю элемент serviceMetadata, чтобы иметь httpGetEnabled="false" и httpsGetEnabled="true", страница .svc показывает мне следующую ссылку:

https://boxname.domain.com/MyService.svc?wsdl

а не ожидаемый

https://server.domain.com/MyService.svc?wsdl

Ответ 1

Убедитесь, что имя вашего служебного элемента в файле web.config соответствует полностью квалифицированному имени класса, который реализует ваш контракт.

<services>
  <service name="MyNamespace.MyService">
    <endpoint name="MyEndpoint" address="" binding="wsHttpBinding" ...

Ответ 2

В WSDL вы видите, что ваша служба не предоставляет порт на HTTPS, а только по HTTP. Кроме того, вы также можете увидеть, что ваша служба использует BasicHttpBinding (см. Имя порта и имя привязки). Это означает, что ваша конфигурация службы не используется вообще. Проверьте, что имя в элементе службы совпадает с именем в вашей разметке .svc. Он должен быть определен, включая пространства имен.

Ответ 3

HTTP и HTTPS обслуживаются с разных виртуальных хостов. Вы уверены, что ваш сервис правильно установлен в обоих?

Ответ 4

Благодаря Johann Blais для ответа, я выяснил, что вам нужно будет указать полное имя для класса, который определяет контракт на обслуживание.

Например, если ваша служба

namespace MyCompany.WcfService
{

    [ServiceContract(Namespace="http://xsd.mycompany.com/mcy/1_0_0")]
    public interface IService
    {
        [OperationContract(IsOneWay = false)]
        void DoStuff()
    }

    public class Service : IService
    {
        void DoStuff()
        {
        }
    }
}

Соответствующее определение службы в вашем web.config будет

<system.serviceModel>
    <services>
        <service name="MyCompany.WcfService.IService">
            <endpoint address="" binding="basicHttpBinding" contract="MyCompany.WcfService.IService" />
        </service>
    </services>
    ...
</system.serviceModel>