Сервис wcf не может быть активирован - PullRequest
10 голосов
/ 04 февраля 2010

Это служба IIS .svc с ssl и членством.

Мой клиент 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. В этой коллекции может быть не более одного адреса на схему. Имя параметра: элемент

Странно то, что это происходит только на рабочем сервере, тот же код и конфиг на сервере разработки localhost работает нормально. Я только меняю адрес конечной точки и от имени компьютера до 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>

Ответы [ 5 ]

8 голосов
/ 05 февраля 2010

Если вы размещаете хостинг в 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"
%>
1 голос
/ 05 февраля 2010

Проблема вызвана обработкой 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);
        }
    }

Тем не менее, это кажется хакерским и должно быть решено Microsoft.

1 голос
/ 04 февраля 2010

Два предположения: у вас где-то есть несколько записей

Возможно, они не имеют одинаковых значений, но могут иметь одно и то же имя.

Или, похоже, вы используете https://, используете ли вы http на компьютере разработчика и https на живом?

Если так, у вас есть отдельные адреса конечных точек для обоих? Теоретически вы не должны этого делать - вы бы включили безопасность транспорта на базовом адресе http, что предотвратит возможность вызова по чему-либо, кроме https.

Технически http и https являются схемами http.

0 голосов
/ 08 апреля 2016

Мне удалось решить проблему, выполнив следующие шаги с помощью Visual Studio 2013:

  1. Перейдите в папку вашего проекта, где у вас есть * .svc файл

  2. Щелкните правой кнопкой мыши * .svc файл -> Просмотреть в браузере

  3. Подтвердите, если вы можете просмотреть услугу

  4. Перейдите в папку вашего проекта, где у вас есть файл app.config или где вы хотите использовать службу.

  5. Щелкните правой кнопкой мыши проект -> Добавить -> Справочник по обслуживанию

  6. Нажмите Обнаружение -> В разделе «Службы» выберите «Служба» -> Присвойте нужное имя своей справочной службе -> Нажмите «ОК»

  7. Он создаст «ServiceReference1» в папке «Service References» и автоматически создаст / обновит файл app.config enter image description here

0 голосов
/ 04 февраля 2010

Попробуйте добавить префикс к вашему производственному серверу в веб-конфигурации:

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

Это будет добавлено к <system.serviceModel>

И ваша конечная точка должна выглядеть так:

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

В противном случае вы всегда можете перегрузить ServiceFactory, как предложил один из других комментаторов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...