2008-09-17 31 views
14

Tôi có một bộ các dịch vụ web WCF được kết nối với một ứng dụng máy tính để bàn.Làm cho WCF dễ cấu hình

Vấn đề của tôi là cài đặt cấu hình thực sự chi tiết mà WCF yêu cầu hoạt động. Bắt SSL để làm việc liên quan đến cài đặt tùy chỉnh. Bắt MTOM hoặc bất cứ điều gì khác để làm việc đòi hỏi nhiều hơn nữa. Bạn muốn nén? Ở đây chúng tôi đi một lần nữa ...

WCF thực sự mạnh mẽ - bạn có thể sử dụng một loạt các cách khác nhau để kết nối, nhưng tất cả dường như liên quan đến rất nhiều cấu hình chi tiết. Nếu máy chủ và máy khách không khớp hoàn toàn, bạn sẽ gặp khó khăn khi giải mã lỗi.

Tôi muốn làm cho ứng dụng dành cho máy tính để bàn dễ định cấu hình hơn - lý tưởng nhất là một số loại khám phá tự động. Người dùng ứng dụng dành cho máy tính để bàn chỉ có thể nhập URL và thực hiện phần còn lại.

Có ai biết cách tốt để làm điều này không?

Tôi biết Visual Studio có thể đặt cấu hình cho bạn, nhưng tôi muốn ứng dụng dành cho máy tính để bàn có thể thực hiện dựa trên nhiều thiết lập máy chủ khác nhau.

Tôi biết rằng công cụ của VS có thể được sử dụng bên ngoài, nhưng tôi đang tìm người dùng ứng dụng dành cho máy tính để bàn không phải là chuyên gia WCF. Tôi biết MS thực hiện điều này một cách có chủ ý hơn là phức tạp.

Có cách nào, cơ chế, thư viện của bên thứ ba hoặc bất kỳ thứ gì để tự động phát hiện cài đặt WCF có thể không?

+0

"Tôi biết MS đã thực hiện điều này một cách có chủ ý hơn" [cần dẫn nguồn] –

+0

Có thể điều đó không công bằng. MS cố ý làm cho nó để mọi thiết lập duy nhất mà bạn có thể muốn thay đổi có thể được, nhưng rằng bạn sẽ cần một cuốn sách WCF và kinh nghiệm lập trình để thiết lập những điều cơ bản. – Keith

Trả lời

9

Tất cả thông tin về điểm cuối có sẵn trong siêu dữ liệu của dịch vụ, bạn có thể viết ứng dụng khách sẽ khám phá siêu dữ liệu của dịch vụ và sẽ định cấu hình ứng dụng khách. Ví dụ về mã, bạn có thể xem xét điều này xuất sắc Mex Explorer từ Juval Lowy.

1

Cảm ơn, đó là mã hữu ích (+1).

Mặc dù nó hơi lộn xộn nhưng có một số lỗi (ví dụ như kiểm tra phân biệt chữ hoa chữ thường không nên có chức năng giao diện người dùng mà tôi không cần và lặp lại nhiều mã.

Tôi đã lấy nó từ cơ chế khám phá thực tế, viết lại nó và hầu như đã làm việc (kết nối, nhưng cần một số finessing).

Đầu tiên một số chức năng util sử dụng theo phương pháp chính:

/// <summary>If the url doesn't end with a WSDL query string append it</summary> 
static string AddWsdlQueryStringIfMissing(string input) 
{ 
    return input.EndsWith("?wsdl", StringComparison.OrdinalIgnoreCase) ? 
     input : input + "?wsdl"; 
} 

/// <summary>Imports the meta data from the specified location</summary> 
static ServiceEndpointCollection GetEndpoints(BindingElement bindingElement, Uri address, MetadataExchangeClientMode mode) 
{ 
    CustomBinding binding = new CustomBinding(bindingElement); 
    MetadataSet metadata = new MetadataExchangeClient(binding).GetMetadata(address, mode); 
    return new WsdlImporter(metadata).ImportAllEndpoints(); 
} 

Sau đó, một phương pháp mà cố gắng cách khác nhau để kết nối và trả về các điểm cuối:

public static ServiceEndpointCollection Discover(string url) 
{ 
    Uri address = new Uri(url); 
    ServiceEndpointCollection endpoints = null; 

    if (string.Equals(address.Scheme, "http", StringComparison.OrdinalIgnoreCase)) 
    { 
     var httpBindingElement = new HttpTransportBindingElement(); 

     //Try the HTTP MEX Endpoint 
     try { endpoints = GetEndpoints(httpBindingElement, address, MetadataExchangeClientMode.MetadataExchange); } 
     catch { } 

     //Try over HTTP-GET 
     if (endpoints == null) 
      endpoints = GetEndpoints(httpBindingElement, 
       new Uri(AddWsdlQueryStringIfMissing(url)), MetadataExchangeClientMode.HttpGet); 
    } 
    else if (string.Equals(address.Scheme, "https", StringComparison.OrdinalIgnoreCase)) 
    { 
     var httpsBindingElement = new HttpsTransportBindingElement(); 

     //Try the HTTPS MEX Endpoint 
     try { endpoints = GetEndpoints(httpsBindingElement, address, MetadataExchangeClientMode.MetadataExchange); } 
     catch { } 

     //Try over HTTP-GET 
     if (endpoints == null) 
      endpoints = GetEndpoints(httpsBindingElement, 
       new Uri(AddWsdlQueryStringIfMissing(url)), MetadataExchangeClientMode.HttpGet); 
    } 
    else if (string.Equals(address.Scheme, "net.tcp", StringComparison.OrdinalIgnoreCase)) 
     endpoints = GetEndpoints(new TcpTransportBindingElement(), 
      address, MetadataExchangeClientMode.MetadataExchange); 

    else if (string.Equals(address.Scheme, "net.pipe", StringComparison.OrdinalIgnoreCase)) 
     endpoints = GetEndpoints(new NamedPipeTransportBindingElement(), 
      address, MetadataExchangeClientMode.MetadataExchange); 

    return endpoints; 
} 
1

Hiện nay có một cách khác để làm điều này không có sẵn khi tôi hỏi câu hỏi gốc. Microsoft hiện hỗ trợ REST cho các dịch vụ WCF.

  • Nhược điểm của việc sử dụng REST là bạn mất WSDL.
  • Phía trên là cấu hình tối thiểu và giao diện hợp đồng WCF của bạn sẽ vẫn hoạt động!

Bạn sẽ cần một tài liệu tham khảo mới để System.ServiceModel.Web

Đánh dấu hoạt động của bạn với một trong hai WebInvoke hoặc WebGet

//get a user - note that this can be cached by IIS and proxies 
[WebGet] 
User GetUser(string id) 

//post changes to a user 
[WebInvoke] 
void SaveUser(string id, User changes) 

Thêm những đến một trang web rất dễ dàng - thêm một tập tin .svc:

<%@ServiceHost 
    Service="MyNamespace.MyServiceImplementationClass" 
    Factory="System.ServiceModel.Activation.WebServiceHostFactory" %> 

Dòng nhà máy cho ASP.net biết cách kích hoạt điểm cuối - bạn không cần cấu hình phía máy chủ nào cả!

Sau đó xây dựng của bạn ChannelFactory là khá nhiều thay đổi, ngoại trừ việc bạn không cần phải xác định một thiết bị đầu cuối nữa (hoặc tự động phát hiện ra một như tôi có trong câu trả lời khác)

var cf = new WebChannelFactory<IMyContractInterface>(); 
var binding = new WebHttpBinding(); 

cf.Endpoint.Binding = binding; 
cf.Endpoint.Address = new EndpointAddress(new Uri("mywebsite.com/myservice.svc")); 
cf.Endpoint.Behaviors.Add(new WebHttpBehavior()); 

IMyContractInterface wcfClient = cf.CreateChannel(); 

var usr = wcfClient.GetUser("demouser"); 
// and so on... 

Lưu ý rằng tôi chưa chỉ định hoặc phát hiện cấu hình máy khách - không cần cấu hình cục bộ!

Một ưu điểm lớn khác là bạn có thể dễ dàng chuyển sang chuỗi tuần tự JSON - cho phép các dịch vụ WCF giống như Java, ActionScript, Javascript, Silverlight hoặc bất kỳ thứ gì khác có thể xử lý JSON và REST dễ dàng.

+0

Tôi cũng đã viết blog về lý do tại sao điều này đã thay đổi: http://bizvprog.blogspot.com/2009/11/giving-up-on-soap-for-good.html – Keith

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