尽管对Web配置和主机工厂进行了更改,仍然会收到WCF错误

时间:2011-11-19 05:30:56

标签: wcf wcf-binding wcf-security

在我的开发人员框中,我的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'。   参数名称:item

以下是相关的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或主机名问题有关吗?这让我很难过。

2 个答案:

答案 0 :(得分:2)

如果您正在使用localhost并使用框架4.0,请通过设置此选项仅使用一个端点:

<serviceHostingEnvironment multipleSiteBindingsEnabled="False" />

使用它,它将会运行。

答案 1 :(得分:1)

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

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

这应该清除错误。如果您没有运行.NET 4,则必须像我一样创建工厂,但您应该创建服务主机并在列表中指定地址。您选择的地址并非无足轻重。错误的可能是不需要的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;
    }
}