title: Programmatically configure ServiceHost endpoints with HTTPS?
body: <p>I'm using Fileless Activation, here is my full web.config on the server side, which has two endpoints:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;configuration&gt;
    &lt;configSections&gt;
      &lt;section name="entityFramework" 
               type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
               requirePermission="false" /&gt;
    &lt;/configSections&gt;
    &lt;connectionStrings&gt;
      &lt;add name="RedStripe"
           connectionString="Data Source=S964;Initial Catalog=MyDatabase;Persist Security Info=True;User ID=sa;Password=***;MultipleActiveResultSets=True"
           providerName="System.Data.SqlClient" /&gt;
    &lt;/connectionStrings&gt;
    &lt;system.web&gt;
      &lt;compilation debug="true" targetFramework="4.5" /&gt;
      &lt;httpRuntime targetFramework="4.5" /&gt;
    &lt;/system.web&gt;
    &lt;entityFramework&gt;
      &lt;defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"&gt;
        &lt;parameters&gt;
          &lt;parameter value="mssqllocaldb" /&gt;
        &lt;/parameters&gt;
      &lt;/defaultConnectionFactory&gt;
      &lt;providers&gt;
        &lt;provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /&gt;
      &lt;/providers&gt;
    &lt;/entityFramework&gt;
    &lt;system.web&gt;
      &lt;customErrors mode="Off"/&gt;
    &lt;/system.web&gt;
    &lt;system.serviceModel&gt;
      &lt;serviceHostingEnvironment&gt;
        &lt;!-- where virtual .svc files are defined --&gt;
        &lt;serviceActivations&gt;     
          &lt;add service="Company.Project.Business.Services.AccountClassService" 
               relativeAddress="Account/AccountClassService.svc" 
               factory="Company.Project.WebHost.CustomServiceHostFactory"/&gt;
  
          &lt;add service="Company.Project.Business.Services.AccountService"
               relativeAddress="Account/AccountService.svc"
               factory="Company.Project.WebHost.CustomServiceHostFactory"/&gt;
  
        &lt;/serviceActivations&gt;
      &lt;/serviceHostingEnvironment&gt;
    &lt;/system.serviceModel&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>Here is my CustomServiceHostFactory:</p>
  
  <pre><code>public class CustomServiceHostFactory : ServiceHostFactory
  {
      protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
      {
          return new CustomServiceHost(serviceType, baseAddresses);
      }
  }
  </code></pre>
  
  <p>And here is my CustomServiceHost:</p>
  
  <pre><code>public class CustomServiceHost : ServiceHost
  {        
      public CustomServiceHost(Type serviceType, Uri[] baseAddresses)
          : base(serviceType, baseAddresses)
      {
      }
  
      protected override void InitializeRuntime()
      {
          AddServiceDebugBehavior();
          AddWcfMessageLoggingBehavior();
          AddGlobalErrorHandlingBehavior();
          AddServiceCredentialBehavior();
          AddEndpoints();
          ConfigureThrottling();
          base.InitializeRuntime();
      }
  
      private void AddEndpoints()
      {
          var wsHttpBinding = WcfHelpers.ConfigureWsHttpBinding();
  
          foreach (Uri address in BaseAddresses)
          {
              var endpoint = new ServiceEndpoint(
                  ContractDescription.GetContract(Description.ServiceType),
                  wsHttpBinding, new EndpointAddress(address));
  
              AddServiceEndpoint(endpoint);
  
              //adding mex
              AddServiceMetadataBehavior();
              AddServiceEndpoint(
                  ServiceMetadataBehavior.MexContractName,
                  MetadataExchangeBindings.CreateMexHttpBinding(),
                  address.AbsoluteUri + "/mex");
  
              break;
          }
      }
      private void AddGlobalErrorHandlingBehavior()
      {
          var errorHanlderBehavior = Description.Behaviors.Find&lt;GlobalErrorBehaviorAttribute&gt;();
  
          if (errorHanlderBehavior == null)
          {
              Description.Behaviors.Add(new GlobalErrorBehaviorAttribute(typeof(GlobalErrorHandler)));
          }
      }
  
      private void AddServiceCredentialBehavior()
      {
          var credentialBehavior = Description.Behaviors.Find&lt;ServiceCredentials&gt;();
  
          if (credentialBehavior == null)
          {
              var customAuthenticationBehavior = new ServiceCredentials();
              customAuthenticationBehavior.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
              customAuthenticationBehavior.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNamePasswordValidator();
              Description.Behaviors.Add(customAuthenticationBehavior);
          }
      }
      private void AddServiceDebugBehavior()
      {
          var debugBehavior = Description.Behaviors.Find&lt;ServiceDebugBehavior&gt;();
  
          if (debugBehavior == null)
          {
              Description.Behaviors.Add(
                  new ServiceDebugBehavior() {IncludeExceptionDetailInFaults = true});
          }
          else
          {
              if (!debugBehavior.IncludeExceptionDetailInFaults)
                  debugBehavior.IncludeExceptionDetailInFaults = true;
          }
      }
      private void AddServiceMetadataBehavior()
      {
          var metadataBehavior = Description.Behaviors.Find&lt;ServiceMetadataBehavior&gt;();
  
          if (metadataBehavior == null)
          {
              ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
              serviceMetadataBehavior.HttpsGetEnabled = true;
              Description.Behaviors.Add(serviceMetadataBehavior);
          }
      }
      private void AddWcfMessageLoggingBehavior()
      {
          var messageInspectorBehavior = Description.Behaviors.Find&lt;WcfMessageInspector&gt;();
  
          if (messageInspectorBehavior == null)
          {
              Description.Behaviors.Add(new WcfMessageInspector());
          }
      }
      private void ConfigureThrottling()
      {
          var throttleBehavior = Description.Behaviors.Find&lt;ServiceThrottlingBehavior&gt;();
  
          if (throttleBehavior != null) return;
  
          throttleBehavior = new ServiceThrottlingBehavior
          {
              MaxConcurrentCalls = 100,
              MaxConcurrentInstances = 100,
              MaxConcurrentSessions = 100
          };
  
          Description.Behaviors.Add(throttleBehavior);
      }
  }
  </code></pre>
  
  <p>Finally here is the WcfHelper where the binding is defined. This is in a shared location so I can programmatically configure the client side binding using the same:</p>
  
  <pre><code>public class WcfHelpers
  {
      public static WSHttpBinding ConfigureWsHttpBinding()
      {
          return new WSHttpBinding
          {
              Name = "myWSHttpBinding",                
              OpenTimeout = new TimeSpan(0, 10, 0),
              CloseTimeout = new TimeSpan(0, 10, 0),
              SendTimeout = new TimeSpan(0, 10, 0),
              MaxBufferPoolSize = 104857600,
              MaxReceivedMessageSize = 104857600,
              Namespace = Constants.RedStripeNamespace,
              ReaderQuotas = new XmlDictionaryReaderQuotas()
              {
                  MaxDepth = 104857600,
                  MaxStringContentLength = 104857600,
                  MaxArrayLength = 104857600,
                  MaxBytesPerRead = 104857600,
                  MaxNameTableCharCount = 104857600
              },
              Security =
              {
                  Mode = SecurityMode.TransportWithMessageCredential,
                  Message = { ClientCredentialType = MessageCredentialType.UserName }
              }
          };
  
      }
  }
  </code></pre>
  
  <p>When I publish this WebHost project and try to browse to one of the two addreses like so:
  <a href="https://myserver/Project/Account/AccountService.svc" rel="nofollow noreferrer">https://myserver/Project/Account/AccountService.svc</a>
  I get the following error:</p>
  
  <blockquote>
    <p>The provided URI scheme 'http' is invalid; expected 'https'. Parameter
    name: context.ListenUriBaseAddress</p>
  </blockquote>
  
  <p>I notice that in the CustomServiceHost AddEndpoints() method, when looping over BaseAddresses, if I hardcode an address there like so:
  <a href="https://myserver/Project/Account/AccountService.svc" rel="nofollow noreferrer">https://myserver/Project/Account/AccountService.svc</a>
  I can then browse to it successfully. How do the BaseAddresses get built when using fileless activation and relative addressing? Where can I specify they use https (where it seems they are using http now)? </p>
  
  <p>Thanks in advance.</p>
  
  <hr>
  
  <p><strong>Edit 1:</strong> This will fix the problem but seems like a total hack, where do I specify https using fileless activation so the relative address builds with https? </p>
  
  <pre><code>var endpoint = new ServiceEndpoint(ContractDescription.GetContract(Description.ServiceType),
  wsHttpBinding, new EndpointAddress(address.OriginalString.Replace("http:", "https:")));
  </code></pre>
  
  <hr>
  
  <p><strong>Edit 2:</strong> I think I'm gaining an understanding of what is going on here. Thank you @Andreas K for pointing me in the right direction. If I go into IIS and look at the bindings for the site, there are multiple as indicated by the image:<img src="https://i.stack.imgur.com/qnQvh.png" alt="enter image description here"></p>
  
  <p>I put some code to write to a database inside my AddEndpoints() method when looping over BaseAddresses. When I try to use the browser to get to the service like so: <a href="https://my.server.local/Project/Account/AccountService.svc" rel="nofollow noreferrer">https://my.server.local/Project/Account/AccountService.svc</a>, TWO entries are created in the database.
  <a href="http://my.server.local/Project/Account/AccountService.svc" rel="nofollow noreferrer">http://my.server.local/Project/Account/AccountService.svc</a>
  <a href="https://my.server.local/Project/Account/AccountService.svc" rel="nofollow noreferrer">https://my.server.local/Project/Account/AccountService.svc</a></p>
  
  <p>Thus, it seems the IIS SITE BINDING is being picked up. However, now I'm not sure why there aren't more entries in the database for the BaseAddresses. Where are the net.pipe, net.tcp, etc? </p>