【问题标题】:wcf Service could not be activatedwcf 服务无法激活
【发布时间】:2010-02-04 13:53:26
【问题描述】:

这是一个带有 ssl 和成员资格的 .svc IIS 托管服务。

我的 wcf 客户端报告:

System.ServiceModel.ServiceActivationException was unhandled
  Message="The requested service, 'https://www.greenjump.nl/WebServices/OrderService.svc' could not be activated. See the server's diagnostic trace logs for more information."
  Source="mscorlib"

在我得到的服务器上: System.ArgumentException 这个集合已经包含一个带有 http 方案的地址。此集合中的每个方案最多可以有一个地址。 参数名称:项目

奇怪的是这只发生在生产服务器上,相同的代码和配置 在本地主机开发服务器上工作正常。 我只更改端点地址和 从计算机名到 www.webdomain.com

更多服务器跟踪

<ExceptionType>
  System.ArgumentException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
</ExceptionType>
<Message>
  This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection.
  Parameter name: item
</Message>
<StackTrace>
  at System.ServiceModel.UriSchemeKeyedCollection.InsertItem(Int32 index, Uri item)
  at System.Collections.Generic.SynchronizedCollection`1.Add(T item)
  at System.ServiceModel.UriSchemeKeyedCollection..ctor(Uri[] addresses)
  at System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses)
  at SharpShop.Web.StructureMap.StructureMapServiceHost..ctor(Type serviceType, Uri[] baseAddresses)
  at SharpShop.Web.StructureMap.StructureMapServiceHostFactory.CreateServiceHost(Type serviceType, Uri[] baseAddresses)
  at System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses)
  at System.ServiceModel.ServiceHostingEnvironment.HostingManager.CreateService(String normalizedVirtualPath)
  at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(String normalizedVirtualPath)
  at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
  at System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath)
  at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
  at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
  at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
  at System.ServiceModel.PartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state)
  at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state)
  at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
  at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke()
  at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks()
  at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state)
  at System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
  at System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
  at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>

配置:

<system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttps">
          <readerQuotas maxStringContentLength="128000"/>
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="None"/>
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" >
      <baseAddressPrefixFilters>
        <add prefix="https://www.greenjump.nl"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WsHttpWithAuthBehavior">
          <serviceMetadata httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceAuthorization principalPermissionMode="UseAspNetRoles"
                                roleProviderName="AspNetSqlRoleProvider"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"
              membershipProviderName="AspNetSqlMembershipProvider" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="WsHttpWithAuthBehavior" name="SharpShop.Services.OrderService">
        <endpoint address="https://www.greenjump.nl/WebServices/OrderService.svc" 
                  binding="wsHttpBinding"
                  bindingConfiguration="wsHttps"
                  contract="SharpShop.Services.IOrderService">
          <identity>
            <dns value="www.greenjump.nl" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

【问题讨论】:

标签: iis-7 wcf


【解决方案1】:

如果您在 IIS 中托管,则不需要基地址部分 - 因为它是 IIS 的站点配置提供的 - 所以删除该部分。

但是,当 IIS 配置为多个主机头时会出现“问题”,在这种情况下,您需要使用自定义工厂来删除除您想要的地址之外的所有地址。一个简单的例子是

namespace Example
{
    public class GenericServiceHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, 
                                                         Uri[] baseAddresses)
        {
            //return the first...
            return new ServiceHost(serviceType, baseAddresses[0]);
        }
    }
} 

然后你会在你的 .svc 文件中使用它

<%@ ServiceHost 
    Service="MyImplementationClass"
    Factory="Example.GenericServiceHostFactory"
%>

【讨论】:

    【解决方案2】:

    两个猜测:你在某处有多个

    它们可能具有不同的值,但它们可能解析为相同的名称。

    或者因为看起来您使用的是 https://,您是否在开发机器上使用 http 而在 live 机器上使用 https?

    如果是这样,您是否有两个单独的端点地址?理论上你不应该这样做——你应该在一个 http 基地址上启用传输安全,这将阻止它在 https 以外的任何地方被调用。

    从技术上讲,http 和 https 都是 http 方案。

    【讨论】:

    • 只有一个端点,在开发机器上我也使用 https 做了一个搜索解决方案,只是为了确定,没有找到其他端点。它适用于 devserver 我只替换生产中的域名和端点位置
    • 查看配置 - 您是否尝试过从主服务的端点中删除显式的“地址=”?如果服务将从 .svc 文件“开始”,则无需指定基地址。
    【解决方案3】:

    该问题是由 IIS 处理多个主机标头引起的。 就像吹镖在这里说的那样。 错误:该集合已经包含一个带有 http 方案的地址。

    这里更详细一些 http://forums.silverlight.net/forums/p/12883/274592.aspx

    使用第一个 baseAddresses[0] 对我来说不是一个选项,因为我的 baseAddresses 是 http://localhost/WebServices/OrderService.svc http://www.greenjump.nl/WebServices/OrderService.svc https://vps2051.xlshosting.net/WebServices/OrderService.svc 按这个顺序我当然可以做 [1] 但我不喜欢这种配置依赖。

    由于 https 绑定,我的问题似乎有点复杂,这是我想出的 ServiceHostFactory:

     public class MyServiceHostFactory : ServiceHostFactory
        {
    
            protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
            {
                Uri webServiceAddress = baseAddresses[0]; //default to first
    
                if (HttpContext.Current != null) //this only works when aspNetCompatibilityEnabled=true
                {
                    string host = HttpContext.Current.Request.Url.Host;
                    var goodAddress = baseAddresses.FirstOrDefault(a => a.Host == host);//try to find address with same hostname as request
                    if(goodAddress!=null)
                    {
                        webServiceAddress = goodAddress;
                    }
                    Type[] sslServices = { typeof(OrderService)  };//add all https services here
                    if (sslServices.Any(s => s == serviceType))
                    {
                        UriBuilder builder = new UriBuilder(webServiceAddress);
                        builder.Scheme = "https";
                        builder.Port = 443; //fails if you use another port
                        webServiceAddress = builder.Uri;
                    }
                }
                return new ServiceHost(serviceType, webServiceAddress);
            }
        }
    

    这仍然感觉很hacky,应该由微软解决。

    【讨论】:

    • @Medo 您是否尝试将端口添加到端点和基本前缀?那是一种解决方案,因此您无需执行此自定义工厂。
    【解决方案4】:

    尝试在 Web 配置中为您的生产服务器添加前缀:

    <serviceHostingEnvironment>
      <baseAddressPrefixFilters>
        <add prefix="https://www.greenjump.nl:443" />
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    

    这将被添加到&lt;system.serviceModel&gt;

    您的端点应如下所示:

       <endpoint address="https://www.greenjump.nl:443/WebServices/OrderService.svc" 
                  binding="wsHttpBinding"
                  bindingConfiguration="wsHttps"
                  contract="SharpShop.Services.IOrderService">
    

    否则,您总是可以像其他评论员建议的那样重载 ServiceFactory

    【讨论】:

      【解决方案5】:

      我能够通过以下步骤使用 Visual Studio 2013 解决该问题:

      1. 转到您拥有 *.svc 文件的项目文件夹

      2. 右击*.svc文件-->在浏览器中查看

      3. 验证您是否能够浏览服务

      4. 转到您拥有 app.config 文件或您要使用该服务的项目文件夹。

      5. 右键项目-->添加-->服务参考

      6. 单击发现-->在服务下选择服务-->为您的服务引用提供所需的名称-->单击确定

      7. 它将在“服务引用”文件夹下创建“ServiceReference1”并自动创建/更新 app.config 文件

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-04
        • 2015-01-06
        • 1970-01-01
        • 2010-11-14
        • 1970-01-01
        • 1970-01-01
        • 2013-04-13
        相关资源
        最近更新 更多