尽管对 Web 配置和主机工厂进行了更改,但仍会出现 WCF 错误

Posted

技术标签:

【中文标题】尽管对 Web 配置和主机工厂进行了更改,但仍会出现 WCF 错误【英文标题】:Keep getting WCF error despite making changes to web config and host factory 【发布时间】:2012-01-01 18:58:11 【问题描述】:

在我的开发者机器上,我的 WCF 服务运行良好,没有任何问题,但是当我将它部署在我的共享服务器上时,当我尝试访问我的服务时收到以下错误消息

https://www.mydomain.com/Admin/myservice/service.svc:

服务 '/admin/myservice/service.svc' 无法激活,因为 编译期间出现异常。异常消息是:这 集合已经包含一个带有 http 方案的地址。可以有 此集合中每个方案最多一个地址。如果您的服务是 托管在 IIS 中,您可以通过设置解决问题 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' 为真或指定 'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'。 参数名称:item.;此集合已包含地址 与方案 http。在这个方案中,每个方案最多可以有一个地址 收藏。如果您的服务托管在 IIS 中,您可以修复 通过设置问题 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' 为真或指定 'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'。 参数名称:项目

这是相关的 web.config 配置:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
    <baseAddressPrefixFilters>
        <add prefix="https://www.mydomain.com/"/>
    </baseAddressPrefixFilters>
</serviceHostingEnvironment> 

这是我的主机工厂代码:

public class MyServiceServiceHostFactory : ServiceHostFactory

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    
        ServiceHost serviceHost = null;

        serviceHost = CreateMyServiceServiceHost(baseAddresses);

        return serviceHost;
    

    private static ServiceHost CreateMyServiceServiceHost(Uri[] baseAddresses)
    
        // initialize service host
        ServiceHost serviceHost = new ServiceHost(typeof(OrderServices), baseAddresses);

        // create and add service endpoint binding using message and user name
        WSHttpContextBinding wsHttpContextEndpointBinding = new WSHttpContextBinding(SecurityMode.TransportWithMessageCredential);
        wsHttpContextEndpointBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
        wsHttpContextEndpointBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
        wsHttpContextEndpointBinding.AllowCookies = true;

        // add meta data service
        ServiceMetadataBehavior metadataBehavior = new ServiceMetadataBehavior();
        metadataBehavior.HttpGetEnabled = false;
        metadataBehavior.HttpsGetEnabled = true;
        metadataBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;

        ServiceAuthorizationBehavior serviceAuthorizationBehavior =
        serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
        serviceAuthorizationBehavior.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles;

        ServiceDebugBehavior serviceDebugBehavior =
        serviceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
        serviceDebugBehavior.IncludeExceptionDetailInFaults = true;

        ServiceCredentials serviceCredentials = new ServiceCredentials();
        serviceCredentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
        serviceCredentials.UserNameAuthentication.CustomUserNamePasswordValidator =
            new MyServiceUserNamePasswordValidator((MyServiceMembershipProvider) Membership.Providers["MyServiceMembershipProvider"]);

        serviceHost.Description.Behaviors.Add(metadataBehavior);
        serviceHost.Description.Behaviors.Add(serviceCredentials);

        serviceHost.AddServiceEndpoint(typeof(IOrderServices), wsHttpContextEndpointBinding, "");

        // Add MEX endpoint
        serviceHost.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpsBinding(), "mex");
        return serviceHost;
    

为什么会出现此错误?每个技术文档都说我按照文档正确地做事。这可能与 SSL 问题或主机名问题有关吗?这让我很难过。

【问题讨论】:

在您的部署中,是否可能还有另一个具有这些设置的 web.config(即继承的 web.config)? 【参考方案1】:

如果您在 localhost 上工作并使用框架 4.0,请通过设置仅使用一个端点:

<serviceHostingEnvironment multipleSiteBindingsEnabled="False" />

使用它,它就会运行。

【讨论】:

【参考方案2】:

我找到了一个解决方案,尽管目前还不够。如果您正在运行 .NET 4 并保证运行它,则添加以下配置:

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

这应该可以清除错误。如果您没有运行 .NET 4,则必须像我一样创建一个工厂,但您应该创建一个服务主机并在列表中指定一个地址。您选择的地址不是微不足道的。错误的 URL 可能是不需要的 Url,或者更糟糕的是错误的方案,从而导致其他服务错误。理想情况下,您应该从 HttpContext 和您想要的方案构建您的 Url。

这是一个精简版:

public class MyServiceHostFactory : System.ServiceModel.Activation.ServiceHostFactory

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
                            
        ServiceHost host;

        // This solution is less than ideal because the Uri at baseAddresses[0] could be the wrong Url or
        // the  wrong scheme. 
        host = new ServiceHost(serviceType, baseAddresses[0]);

        // A better solution, is to use the incoming request Uri and pass it in like so:
        host = new ServiceHost(serviceType, *** construct the url from Http Context ***);

        return host;
    

【讨论】:

以上是关于尽管对 Web 配置和主机工厂进行了更改,但仍会出现 WCF 错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Boot 和 Data JPA,尽管有 OpenSessionInViewFilter,但仍会出现 LazyInitializationException

尽管在 Clojure 中对 Java 构造函数有类型提示,但仍会出现反射警告

使用 PowerMock 模拟私有方法,但仍会调用底层方法

CORS 已启用,但仍会收到 405

如何以 root 身份运行 Perl 脚本但仍会影响用户 gconf 设置

Spring CorsFilter 似乎无法正常工作,但仍会收到 401 的预检请求