0

I have tried implementing a number of suggestions from other questions to fix this frustrating issue. Normally, when I set up a site in IIS, the web apps are somewhat "agnostic" to what is going on at the transport layer. However, for this particular app, I cannot get it to work when I apply an https binding.

My web.config looks like:

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <bindings>
      <basicHttpBinding>
        <binding name="DefaultAPIBinding">
          <security mode="Transport">
            <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
            <message clientCredentialType="Certificate" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>

and my Global.asax.cs looks like

 ContainerBuilder builder = new ContainerBuilder();

  //builder.Register<IContactRepository, ContactRepository>();
  builder.Register<IResourceFactory, Classes.LightCoreResourceFactory>();

  IContainer container = builder.Build();

  var configuration = HttpHostConfiguration.Create().SetResourceFactory(new LightCoreResourceFactory(container));  

  RouteTable.Routes.MapServiceRoute<WebServiceResources>("ws", configuration);

But whenever I add an https binding to my IIS site, I get the error:

The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: context.ListenUriBaseAddress

[ArgumentException: The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: context.ListenUriBaseAddress]
   System.ServiceModel.Channels.TransportChannelListener..ctor(TransportBindingElement bindingElement, BindingContext context, MessageEncoderFactory defaultMessageEncoderFactory, HostNameComparisonMode hostNameComparisonMode) +12800194
   System.ServiceModel.Channels.HttpChannelListener..ctor(HttpTransportBindingElement bindingElement, BindingContext context) +41
   System.ServiceModel.Channels.HttpChannelListener`1..ctor(HttpTransportBindingElement bindingElement, BindingContext context) +28
   System.ServiceModel.Channels.HttpTransportBindingElement.BuildChannelListener(BindingContext context) +133
   System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
   Microsoft.ApplicationServer.Http.Channels.HttpMessageEncodingBindingElement.BuildChannelListener(BindingContext context) +90
   System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
   Microsoft.ApplicationServer.Http.Channels.HttpMessageHandlerBindingElement.BuildChannelListener(BindingContext context) +158
   System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
   System.ServiceModel.Channels.Binding.BuildChannelListener(Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters) +125
   System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, IChannelListener& result, Boolean supportContextSession) +336
   System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result) +716
   System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) +1131
   System.ServiceModel.ServiceHostBase.InitializeRuntime() +65
   System.ServiceModel.ServiceHostBase.OnBeginOpen() +34
   System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +50
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +310
   System.ServiceModel.Channels.CommunicationObject.Open() +36
   System.ServiceModel.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity) +91
   System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity) +598

[ServiceActivationException: The service '/ws' cannot be activated due to an exception during compilation.  The exception message is: The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: context.ListenUriBaseAddress.]
   System.Runtime.AsyncResult.End(IAsyncResult result) +495736
   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +178
   System.ServiceModel.Activation.AspNetRouteServiceHttpHandler.EndProcessRequest(IAsyncResult result) +6
   System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +129

Since the error message does not provide a location in my code to check or any other hints, and since I have already implemented some of the other suggestions on how to fix this, I am at a loss. Any idea of what I can do to make this app allow https bindings?

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
tacos_tacos_tacos
  • 10,277
  • 11
  • 73
  • 126
  • but you get a stacktrace? how about posting that. – shriek Sep 25 '13 at 18:11
  • sure thing... good point – tacos_tacos_tacos Sep 25 '13 at 18:11
  • "But whenever I add an https binding to my IIS site, I get the error:" can you clarify how you add an https binding to your IIS site? Through IIS itself or? – Haney Sep 25 '13 at 18:15
  • Through IIS itself, yes – tacos_tacos_tacos Sep 25 '13 at 18:28
  • I'd wager the problem is with the web.config file. Are there more WCF-related line items in your web.config? e.g. services, behavoirs, etc. See here for a sample: http://msdn.microsoft.com/en-us/library/hh556232.aspx -- also I see you're going for client certificate security on the message itself.. Don't be alarmed any time I've dealt with such requirements it does take some tweaking to get working. – mikey Sep 25 '13 at 19:16

1 Answers1

1

To elaborate on what @thedr said, here is what we did:

  1. Upgrade to MVC4 if you have not done so already
  2. Add the following class ripped straight from this CodePlex discussion
public class HttpsServiceHostFactory : HttpConfigurableServiceHostFactory
{
    public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
    {

        var host = base.CreateServiceHost(constructorString, baseAddresses);

        foreach (var httpBinding in from serviceEndpoint in host.Description.Endpoints
                                    where serviceEndpoint.ListenUri.Scheme == "https"
                                    select (HttpBinding)serviceEndpoint.Binding)
        {
            httpBinding.Security.Mode = HttpBindingSecurityMode.Transport;
        }

        return host;
    }
}

Then when you do RouteTable.Routes.MapServiceRoute, it should look like

RouteTable.Routes.
        MapServiceRoute<WebServiceResources, HttpsServiceHostFactory>("ws", configuration);
tacos_tacos_tacos
  • 10,277
  • 11
  • 73
  • 126