web-dev-qa-db-fra.com

le service wcf n'a pas pu être activé

Il s’agit d’un service hébergé .svc IIS avec ssl et appartenance.

Mon client wcf rapporte:

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"

Je reçois sur le serveur: System.ArgumentException Cette collection contient déjà une adresse avec le schéma http. Il peut y avoir au plus une adresse par schéma dans cette collection. Nom du paramètre: item

La chose étrange est que cela ne se produit que sur le serveur de production, le même code et le même code config Sur le serveur de développement localhost fonctionnent correctement. Je ne modifie que l'adresse du noeud final et À partir du nom de l'ordinateur. sur www.webdomain.com

plus de trace du serveur

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

config:

<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>
10
Medo

Le problème est dû à la manipulation de IIS de plusieurs en-têtes d’hôte. Comme blowdart l’a dit: Erreur: cette collection contient déjà une adresse avec le schéma http.

et un peu plus élaboré ici http://forums.silverlight.net/forums/p/12883/274592.aspx

l'utilisation de la première baseAddresses [0] n'est pas une option pour moi car mes basesAddresses étaient http: //localhost/WebServices/OrderService.svchttp: // www. greenjump.nl/WebServices/OrderService.svchttps://vps2051.xlshosting.net/WebServices/OrderService.svc dans cet ordre de parcours que je pourrais faire [1 ] mais je n'aime pas cette dépendance à la configuration.

Il semble que mon problème soit un peu plus complexe en raison de la liaison https. Voici le ServiceHostFactory que j'ai créé:

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

Néanmoins, cela semble hacky et devrait être résolu par Microsoft.

1
Medo

Si vous hébergez dans IIS, vous n'avez pas besoin de la section d'adresse de base, car c'est la configuration du site IIS qui la fournit, alors supprimez-la.

Il existe un "problème" lorsque IIS est configuré pour plusieurs en-têtes d'hôte. Dans ce cas, vous devez utiliser une fabrique personnalisée qui supprime toutes les adresses, à l'exception de celle de votre choix. Un exemple simple est

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

Ensuite, vous utiliseriez cela dans votre fichier .svc

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

Deux suppositions: vous avez plusieurs entrées <endpoint address = "" quelque part.

Ils peuvent ne pas avoir les mêmes valeurs, mais ils peuvent résoudre le même nom.

Ou puisqu'il semble que vous utilisiez https: //, utilisez-vous http sur la machine de développement et https sur la version en direct?

Si oui, avez-vous des adresses de points de terminaison distinctes pour les deux? En théorie, vous ne devriez pas faire cela. Vous devriez activer la sécurité du transport sur une adresse de base http, ce qui l'empêchera de pouvoir être appelé autrement que par https.

Techniquement, http et https sont deux schémas http.

1
Andras Zoltan

J'ai pu résoudre le problème en suivant les étapes ci-dessous à l'aide de Visual Studio 2013:

  1. Allez dans le dossier de votre projet où vous avez votre fichier * .svc

  2. Clic droit sur le fichier * .svc -> Afficher dans le navigateur

  3. Validez si vous êtes capable de parcourir le service

  4. Accédez au dossier de votre projet dans lequel vous avez votre fichier app.config ou à celui où vous souhaitez utiliser le service.

  5. Faites un clic droit sur le projet -> Ajouter -> Référence du service

  6. Cliquez sur Découvrir -> Sous Services. Sélectionnez Service -> Donnez le nom souhaité à la référence de votre service -> Cliquez sur OK.

  7. Il créera "ServiceReference1" sous le dossier "Service References" et créera/mettra à jour automatiquement le fichier app.config  enter image description here

0
Ajay Shankar

Essayez d’ajouter un préfixe à votre serveur de production dans la configuration Web:

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

Ce serait ajouté à <system.serviceModel>

Et votre point final devrait ressembler à ceci:

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

Sinon, vous pouvez toujours surcharger le ServiceFactory comme l’a suggéré un autre commentateur.

0
Waleed Al-Balooshi