支持HTTP/HTTPS的WCF服务单IIS绑定时失效问题求助
Hey, I’ve tackled this exact issue a few times with WCF services hosted in IIS—your problem boils down to how your endpoints are configured. When you remove either HTTP or HTTPS binding from IIS, WCF still tries to initialize both endpoints you’ve defined, and since one binding doesn’t exist anymore, the whole service crashes on startup. Let’s fix this step by step.
Solution 1: Adaptive Configuration (No Code Needed)
This is the simplest approach if you prefer keeping changes in your Web.config:
1. Use Relative Endpoint Addresses
First, stop hardcoding absolute HTTP/HTTPS addresses in your endpoints. Use empty or relative addresses so WCF automatically uses IIS’s site bindings:
<services> <service name="YourNamespace.YourService"> <!-- HTTP endpoint (uses IIS HTTP binding automatically) --> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="HttpBindingConfig" contract="YourNamespace.IYourService" /> <!-- HTTPS endpoint (uses IIS HTTPS binding automatically) --> <endpoint address="" binding="basicHttpsBinding" bindingConfiguration="HttpsBindingConfig" contract="YourNamespace.IYourService" /> <!-- Optional metadata endpoints --> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" /> </service> </services>
2. Enable Multi-Site Binding Support
Add this to your <system.serviceModel> section—it tells WCF to automatically adapt to IIS’s current bindings and ignore missing ones:
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
3. Configure HTTP/HTTPS Binding Settings
Define separate configurations for each protocol, making sure HTTPS has transport security enabled:
<bindings> <basicHttpBinding> <binding name="HttpBindingConfig"> <!-- Add custom HTTP settings (e.g., max message size, timeouts) here --> </binding> </basicHttpBinding> <basicHttpsBinding> <binding name="HttpsBindingConfig"> <security mode="Transport"> <transport clientCredentialType="None" /> <!-- Adjust based on your auth needs --> </security> </binding> </basicHttpsBinding> </bindings>
4. Update Metadata Behavior (Optional but Recommended)
Ensure metadata works with whichever protocol is active:
<behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors>
Solution 2: Dynamic Endpoint Creation (More Flexible)
If you need custom logic (like conditional endpoint rules), use a custom ServiceHostFactory to add endpoints only for bindings that exist in IIS:
1. Create the Custom Factory
Add this class to your project:
using System; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Description; using System.Web; namespace YourNamespace { public class AdaptiveServiceHostFactory : ServiceHostFactory { protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { var host = base.CreateServiceHost(serviceType, baseAddresses); // Add endpoints only for protocols that exist in IIS's base addresses foreach (var addr in baseAddresses) { if (addr.Scheme == Uri.UriSchemeHttp) { host.AddServiceEndpoint(typeof(IYourService), new BasicHttpBinding(), ""); } else if (addr.Scheme == Uri.UriSchemeHttps) { var httpsBinding = new BasicHttpsBinding(); httpsBinding.Security.Mode = BasicHttpsSecurityMode.Transport; host.AddServiceEndpoint(typeof(IYourService), httpsBinding, ""); } } // Add metadata endpoints for active protocols var mexBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>() ?? new ServiceMetadataBehavior(); if (!host.Description.Behaviors.Contains(mexBehavior)) { host.Description.Behaviors.Add(mexBehavior); } foreach (var addr in baseAddresses) { if (addr.Scheme == Uri.UriSchemeHttp) { host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex"); mexBehavior.HttpGetEnabled = true; } else if (addr.Scheme == Uri.UriSchemeHttps) { host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpsBinding(), "mex"); mexBehavior.HttpsGetEnabled = true; } } return host; } } }
2. Update Your .svc File
Tell WCF to use your custom factory instead of the default one:
<%@ ServiceHost Language="C#" Debug="true" Service="YourNamespace.YourService" Factory="YourNamespace.AdaptiveServiceHostFactory" %>
Key Notes
- Permission Check: If using the code-based approach with
Microsoft.Web.Administration(for deeper IIS binding inspection), ensure your app pool identity has read access to IIS configuration. - Test All Scenarios: After making changes, test three cases: only HTTP, only HTTPS, and both enabled to confirm the service works in all scenarios.
- Binding Consistency: Keep HTTP/HTTPS binding settings (like message limits, timeouts) aligned with your application’s requirements.
内容的提问来源于stack exchange,提问作者Luca Andrei

