2017-02-19 3 views
8

Lorsque vous utilisez le ServiceHost.AddServiceEndpoint ajouter la coutume ProtoEndpointBehavior-je obtenir l'exception suivante:AddServiceEndpoint throws key est null?

System.ArgumentNullException: La valeur ne peut être nulle. Nom du paramètre: touche à System.Collections.Generic.Dictionary 2.FindEntry(TKey key) at System.Collections.Generic.Dictionary 2.ContainsKey (touche TKey) à System.ServiceModel.ServiceHostBase.ImplementedContractsContractResolver.ResolveContract (String contractName) à System.ServiceModel.ServiceHostBase.ServiceAndBehaviorsContractResolver.ResolveContract (String contractName) à System.ServiceModel.Description.ConfigLoader.LookupContractForStandardEndpoint (String contractName, String serviceName) à System.ServiceModel.Description.ConfigLoader.LookupContract (String contractName, String serviceName) à System.ServiceModel.ServiceHostBase.AddServiceEndpoint (ServiceEndpoint endpoi nt) à My.Service.Business.ServiceHandler.StartService (Type serviceType, Chaîne uri, SecureConnectionSettings secureConnectionSettings) dans C: \ My \ Produkter \ My Utveckling \ Solution \ My.Service.Business \ ServiceHandler.cs: ligne 150

Voici comment le code ressemble à:

ServiceHost serviceHost = null; 
Console.WriteLine("Creating service " + serviceType.FullName); 
serviceHost = new MyServiceHost(serviceType, new Uri(uri)); 

var endPointAddress = ""; 

HttpBindingBase binding = null; 
if (secureConnectionSettings != null && secureConnectionSettings.Enabled) 
{ 
    Console.WriteLine("Setting certificates"); 
    X509Store store = new X509Store(secureConnectionSettings.CertificateStore, secureConnectionSettings.CertificateLocation); 
    store.Open(OpenFlags.ReadOnly); 
    X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByThumbprint, secureConnectionSettings.Thumbprint, true); 
    store.Close(); 

    if (certs.Count > 0) 
     serviceHost.Credentials.ServiceCertificate.SetCertificate(secureConnectionSettings.CertificateLocation, 
                   secureConnectionSettings.CertificateStore, 
                   X509FindType.FindByThumbprint, 
                   secureConnectionSettings.Thumbprint); 
    else 
     throw new Exception("Could not finde certificate with thumbprint " + secureConnectionSettings.Thumbprint); 

    endPointAddress = uri + "/BinaryHttpsProto"; 
    binding = CreateNetHttpsBinding(secureConnectionSettings); 
} 
else 
{ 
    endPointAddress = uri + "/BinaryHttpProto"; 
    binding = CreateNetHttpBinding(); 
} 

var endpoint = new System.ServiceModel.Description.ServiceEndpoint(new System.ServiceModel.Description.ContractDescription(typeof(IMyClientService).FullName), 
    binding, 
    new EndpointAddress(endPointAddress)); 

endpoint.EndpointBehaviors.Add(new ProtoBuf.ServiceModel.ProtoEndpointBehavior()); 
serviceHost.AddServiceEndpoint(endpoint); 

Console.WriteLine("Starting service..."); 
serviceHost.Open(); 
Console.WriteLine("Service started successfully (" + uri + ")"); 
return serviceHost; 

-je utiliser pour configurer dans le fichier de configuration comme ceci:

<endpointBehaviors> 
    <behavior name="protoEndpointBehavior"> 
     <protobuf /> 
    </behavior> 
    </endpointBehaviors> 

Maintenant, j'ai besoin de l'ajouter au code à la place.

Qu'est-ce qui ne va pas?

+0

Quelle ligne dans le code que vous avez posté est en train de lancer cette erreur? – Sparrow

+0

@FeryalBadili Il est lancé sur la ligne endpoint.EndpointBehaviors.Add. – Banshee

Répondre

4

Il s'agit d'un known bug et il existe une solution de contournement pour cela.

Lors de l'obtention instance de ContractDescription, utilisez la méthode statique ContractDescription.GetContract(Type) au lieu de constructeur ContractDescription direct():

var endpoint = new System.ServiceModel.Description.ServiceEndpoint(System.ServiceModel.Description.ContractDescription.GetContract(typeof(IMyClientService)), 
    binding, 
    new EndpointAddress(endPointAddress)); 

j'ai pu reproduire votre problème et cette solution de contournement a fonctionné pour moi.

1

La raison pour laquelle vous voyez l'exception est que vous avez supposé que vous utilisez le fichier de configuration ServiceEndpoint. Il essaie de récupérer & résoudre votre contrat, liaison et adresse qui n'existe pas parce que vous n'utilisez pas le fichier de configuration.

ServiceEndpoint (voir remarques)

Utilisez ce constructeur lorsque la liaison et l'adresse du point de terminaison sont fournis dans la configuration.

Il y a plusieurs façons de create or retrieve a ContractDescription objet:

var contractUsingName = new ContractDescription("IProtoBufService"); 
var contractUsingNameWithNameSpace = new ContractDescription("IProtoBufService", "http://www.tempuri.org"); 
var contractUsingContractType = ContractDescription.GetContract(typeof(IProtoBufService)); 
var contractUsingContractTypeAndObjectImp = ContractDescription.GetContract(typeof(IProtoBufService), ProtoBufService); 
var contractUsingContractTypeAndObjectType = ContractDescription.GetContract(typeof(IProtoBufService), typeof(ProtoBufService)); 

Si vous insistez vraiment créer ContractDescription programme vous devez définir certains des éléments suivants:

  • ContractDescription
  • OperationDescription
  • MessageDescription
  • OperationBehaviorAttribute
  • Et d'autres choses ...

Ou vous pouvez suivre cette blog comme kicker.

Avez-vous essayé la réponse de CodeFuller? Sa réponse pourrait vous faciliter la vie. J'ai fait une vérification rapide et ça marche.

class Program 
{ 
    static void Main() 
    { 
     var baseAddress = new Uri("http://localhost:8080/ProtoBuf"); 

     using (var serviceHost = new ServiceHost(typeof(ProtoBufService), baseAddress)) 
     { 
      var endpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IProtoBufService)), 
       new NetHttpBinding(), 
       new EndpointAddress(baseAddress)); 

      endpoint.EndpointBehaviors.Add(new ProtoEndpointBehavior()); 
      serviceHost.AddServiceEndpoint(endpoint); 

      serviceHost.Open(); 
      Console.ReadKey(); 
     } 
    } 
} 

Malheureusement, je ne pouvais pas attaché une image « quelque chose qui ne va pas avec Imgur » mais travailler sur mon navigateur. Bien que je n'ai pas testé en utilisant l'application client, mais je suppose que vous êtes déjà proche de la solution. Ne mélangez pas le fichier de configuration et le code car ils sont très difficiles à maintenir. "Lequel vous avez probablement su" Bonne chance :)

+0

Merci! Oui CodeFuller semble résoudre le problème mais je vérifie toujours si c'est vraiment résolu. – Banshee