Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AddServiceEndpoint throws key is null?

When using the ServiceHost.AddServiceEndpoint to add the custom ProtoEndpointBehavior I get the following exception :

System.ArgumentNullException: Value cannot be null. Parameter name: key at System.Collections.Generic.Dictionary2.FindEntry(TKey key) at System.Collections.Generic.Dictionary2.ContainsKey(TKey key) at System.ServiceModel.ServiceHostBase.ImplementedContractsContractResolver.ResolveContract(String contractName) at System.ServiceModel.ServiceHostBase.ServiceAndBehaviorsContractResolver.ResolveContract(String contractName) at System.ServiceModel.Description.ConfigLoader.LookupContractForStandardEndpoint(String contractName, String serviceName) at System.ServiceModel.Description.ConfigLoader.LookupContract(String contractName, String serviceName) at System.ServiceModel.ServiceHostBase.AddServiceEndpoint(ServiceEndpoint endpoint) at My.Service.Business.ServiceHandler.StartService(Type serviceType, String uri, SecureConnectionSettings secureConnectionSettings) in C:\My\Produkter\My Utveckling\Solution\My.Service.Business\ServiceHandler.cs:line 150

This is how the code looks like :

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;

I use to set this in config file like this :

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

Now I need to add it in code instead.

What is wrong?

like image 511
Banshee Avatar asked Feb 19 '17 13:02

Banshee


1 Answers

It's a known bug and there is workaround for it.

When obtaining instance of ContractDescription, use static method ContractDescription.GetContract(Type) instead of direct ContractDescription() constructor:

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

I was able to reproduce your problem and this workaround worked for me.

like image 87
CodeFuller Avatar answered Oct 04 '22 04:10

CodeFuller