尽管更改了 Web 配置和主机工厂,但仍不断收到 WCF 错误

发布于 2024-12-17 02:44:05 字数 3772 浏览 0 评论 0原文

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

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

服务“/admin/myservice/service.svc”无法激活,因为 编译期间出现异常。异常消息是:这个 集合已包含一个带有 http 方案的地址。可以有 该集合中的每个方案至多有一个地址。如果您的服务是 托管在 IIS 中,您可以通过设置来解决问题 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' 为 true 或指定 'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'。 参数名称:项目;该集合已包含地址 与方案http。此方案中每个方案最多可以有一个地址 收藏。如果您的服务托管在 IIS 中,您可以修复 通过设置出现问题 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' 为 true 或指定 '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 问题或主机名问题有关?这让我难住了。

On my developer box, my WCF service works well with no problems, but when I deploy it on my shared server, I get the following error message when I try to access my service

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

The service '/admin/myservice/service.svc' cannot be activated due to
an exception during compilation. The exception message is: This
collection already contains an address with scheme http. There can be
at most one address per scheme in this collection. If your service is
being hosted in IIS you can fix the problem by setting
'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled'
to true or specifying
'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'.
Parameter name: item.; This collection already contains an address
with scheme http. There can be at most one address per scheme in this
collection. If your service is being hosted in IIS you can fix the
problem by setting
'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled'
to true or specifying
'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'.
Parameter name: item

Here's the pertinent web.config configuration:

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

Here's my host factory code:

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;
    }
}

Why am I getting this error? Every technical document says that I am doing things correctly according to the documentation. Could this be related to a problem with SSL or the host name issues? This has me stumped.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘿嘿嘿 2024-12-24 02:44:05

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

<serviceHostingEnvironment multipleSiteBindingsEnabled="False" />

使用此选项,它将运行。

If you're working on localhost and using framework 4.0, use only one endpoint by setting this:

<serviceHostingEnvironment multipleSiteBindingsEnabled="False" />

Use this and it will run.

酷遇一生 2024-12-24 02:44:05

我找到了一个解决方案,尽管目前还不够。如果您正在运行 .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;
    }
}

I found a solution although inadequate for now. If you're running .NET 4 and guaranteed to run it, you add the following configuration:

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

This should clear up the error. If you're not running .NET 4, you have to create a factory as I did, but you should create a service host and specify an address on the list. The address you pick isn't trivial. The wrong one could be an unwanted Url or worse the wrong scheme, resulting in other service errors. Ideally, you should construct your Url from the HttpContext and your desired scheme.

Here's a trimmed down version:

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文