2017-02-19 19 views
8

Khi sử dụng ServiceHost.AddServiceEndpoint để thêm tùy chỉnh ProtoEndpointBehavior tôi nhận được ngoại lệ sau đây:AddServiceEndpoint ném khóa là null?

System.ArgumentNullException: Giá trị không thể null. Tên tham số: chủ chốt tại System.Collections.Generic.Dictionary 2.FindEntry(TKey key) at System.Collections.Generic.Dictionary 2.ContainsKey (key TKey) tại System.ServiceModel.ServiceHostBase.ImplementedContractsContractResolver.ResolveContract (String contractName) tại System.ServiceModel.ServiceHostBase.ServiceAndBehaviorsContractResolver.ResolveContract (String contractName) tại System.ServiceModel.Description.ConfigLoader.LookupContractForStandardEndpoint (string contractName, string serviceName) tại System.ServiceModel.Description.ConfigLoader.LookupContract (string contractName, string serviceName) tại System.ServiceModel.ServiceHostBase.AddServiceEndpoint (ServiceEndpoint endpoi nt) tại My.Service.Business.ServiceHandler.StartService (Loại serviceType, Chuỗi uri, SecureConnectionSettings secureConnectionSettings) trong C: \ My \ Produkter \ My Utveckling \ Solution \ My.Service.Business \ ServiceHandler.cs: line 150

Đây là cách mã trông giống như:

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; 

tôi sử dụng để thiết lập này trong tập tin cấu hình như thế này:

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

Bây giờ, tôi cần phải thêm mã vào mã thay thế.

Điều gì là sai?

+0

Dòng nào trong mã mà bạn đã đăng đang ném lỗi đó? – Sparrow

+0

@FeryalBadili Nó được ném vào dòng endpoint.EndpointBehaviors.Add. – Banshee

Trả lời

4

Đó là số known bug và có giải pháp thay thế cho nó.

Khi lấy ví dụ của ContractDescription, sử dụng phương pháp tĩnh ContractDescription.GetContract(Type) thay vì ContractDescription trực tiếp() constructor:

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

tôi đã có thể để tái tạo vấn đề của bạn và cách giải quyết này làm việc cho tôi.

1

Lý do tại sao bạn thấy ngoại lệ là vì ServiceEndpoint giả sử bạn sử dụng tệp cấu hình. Nó đang cố gắng truy xuất & giải quyết hợp đồng, ràng buộc và địa chỉ không tồn tại vì bạn không sử dụng tệp cấu hình.

ServiceEndpoint (xem các ghi nhận)

Sử dụng constructor này khi các ràng buộc và địa chỉ cho các thiết bị đầu cuối là cung cấp trong cấu hình.

Có nhiều cách để create or retrieve a ContractDescription đối tượng:

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

Nếu bạn thực sự nhấn mạnh để tạo ra ContractDescription lập trình bạn cần xác định một số các nội dung sau:

  • ContractDescription
  • OperationDescription
  • MessageDescription
  • OperationBehaviorAttribute
  • Và những thứ khác ...

Hoặc bạn có thể làm theo blog này như một kicker.

Bạn đã thử câu trả lời của CodeFuller chưa? Câu trả lời của anh có thể làm cho cuộc sống của bạn dễ dàng hơn. Tôi đã kiểm tra nhanh và nó hoạt động.

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

Thật không may, tôi không thể đính kèm một hình ảnh "gì đó không ổn với imgur" nhưng nó hoạt động trên trình duyệt web của tôi. Mặc dù tôi chưa thử nghiệm bằng ứng dụng khách nhưng tôi đoán bạn đã gần với giải pháp.

Mẹo: Không được trộn lẫn tệp cấu hình và mã vì rất khó bảo trì. "Bạn có thể biết" Chúc may mắn :)

+0

Cảm ơn! Có CodeFuller dường như để giải quyết vấn đề nhưng im vẫn kiểm tra nếu nó thực sự giải quyết. – Banshee

Các vấn đề liên quan