2009-09-25 25 views
8

Tôi có một tập hợp các Hợp đồng dịch vụ phân chia giao diện dịch vụ của tôi thành các khối chức năng liên quan. Tôi hiện đang thực hiện tất cả các hợp đồng bằng cách sử dụng một lớp dịch vụ duy nhất (có thể muốn chia các lớp này sau nhưng bây giờ thì lớp dịch vụ đơn lẻ sẽ đủ).WCF IIS lưu trữ dịch vụ nhiều Hợp đồng dịch vụ được thực hiện bởi một dịch vụ duy nhất - làm cách nào để chia sẻ uri giữa các thiết bị đầu cuối thông qua cấu hình

Tôi đang cố gắng sử dụng định cấu hình các điểm cuối bằng cách sử dụng tệp cấu hình (ngược lại với mã thông qua). Vấn đề là tôi nhận được một ServiceActivationException vì hai điểm cuối (một cho mỗi hợp đồng dịch vụ) đang cố gắng lắng nghe trên cùng một uri. Các chi tiết ngoại lệ nói rằng để đạt được điều này, hai thiết bị đầu cuối phải chia sẻ đối tượng liên kết, điều đó có ý nghĩa nhưng tôi không thể tìm ra cách thực hiện điều này thông qua cấu hình (tôi chưa thử làm điều này qua mã như tôi đang lưu trữ trong IIS nhưng Tôi có thể tưởng tượng nó là một bài tập đơn giản để cấu hình trong mã).

Sau đây là cấu hình Tôi hiện đang sử dụng (điều này vẫn dev vì vậy tôi hiện không lo lắng về vấn đề an ninh vv mà một số các thiết lập này có thể phơi bày):

<system.serviceModel> 
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
<services> 
    <service name="CDC.WebPortal.MidTier.MidTierAccessService" 
      behaviorConfiguration="MidTierServiceBehaviour" > 
    <endpoint address="" 
       binding="webHttpBinding" 
       bindingConfiguration="RestBindingConfiguration" 
       contract="****************************.IProductService" /> 

    <endpoint address="" 
       binding="webHttpBinding" 
       bindingConfiguration="RestBindingConfiguration" 
       contract="****************************.ICategoryService" /> 

    <endpoint address="mex" binding="mexHttpBinding" 
       contract="IMetadataExchange" /> 

    </service> 
</services> 

<bindings> 
    <webHttpBinding> 
    <binding name="RestBindingConfiguration" 
      maxReceivedMessageSize="104857600"> 
     <readerQuotas maxStringContentLength="104857600"/> 
    </binding> 
    </webHttpBinding> 
</bindings> 

<behaviors> 
    <serviceBehaviors> 
    <behavior name="MidTierServiceBehaviour"> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="false" /> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

Vì vậy, câu hỏi của tôi là làm thế nào để tôi chia sẻ này ràng buộc giữa hai thiết bị đầu cuối?

Nhận xét trong this SO question đề nghị tôi không thể thực hiện việc này, nhưng tôi không tin điều đó là chính xác.

UPDATE 1 Theo this MS publication gì tôi đang làm nên ok ...

UPDATE2 Dưới đây là nội dung tập tin svc nếu nó giúp:

<%@ ServiceHost Language="VB" Debug="true" 
       Service="*********************.MidTierAccessService" 
       Factory="Microsoft.ServiceModel.Web.WebServiceHost2Factory" %> 

CẬP NHẬT 3 Dưới đây là chi tiết ngoại lệ:

Một instan ràng buộc ce đã được liên kết để nghe URI '********************'. Nếu hai điểm cuối muốn chia sẻ cùng một ListenUri, chúng cũng phải chia sẻ cùng một trường hợp đối tượng ràng buộc. Hai điểm cuối xung đột được xác định trong các lệnh gọi AddServiceEndpoint(), trong tệp cấu hình hoặc kết hợp của AddServiceEndpoint() và định cấu hình.

CẬP NHẬT 4 Ok tôi đã bỏ lỡ this trước, trong đó nêu "Bạn sẽ cần phải sử dụng địa chỉ tương đối khi tiếp xúc nhiều hơn một thiết bị đầu cuối cho một dịch vụ .svc đặc biệt". Nguyên nhân của việc này là liên quan đến thư mục ảo IIS xác định địa chỉ cơ sở của dịch vụ, bất cứ ai có thể giải thích điều này chi tiết hơn một chút, tức là tại sao IIS cần địa chỉ tương đối cho từng hợp đồng.

Trả lời

7

Theo hiểu biết của tôi và tôi đã làm việc rộng rãi với WCF trong tháng trước, bạn không thể chia sẻ cùng một URI chính xác cho nhiều hơn một điểm cuối. Trong WCF, một "dịch vụ" không được xác định bởi việc thực thi hợp đồng, mà theo chính bản thân hợp đồng (cũng tuân theo WSDL và các thực hành SOA chuẩn.) Các điểm cuối cho phép bạn trưng ra một dịch vụ đơn qua nhiều giao thức (và các địa chỉ khác nhau) , nhưng bạn không thể chia sẻ các dịch vụ khác nhau trên cùng một địa chỉ chính xác. Một cách hợp lý sẽ không hoạt động.

Giả sử các tình huống sau (đó là những gì bạn đang cố gắng để thực hiện):

IProductService exposed @ http://localhost/service 
ICategoryService exposed @ http://localhost/service 
IMetadataExchange exposed @ http://localhost/service/mex 

Nó là đủ dễ dàng để truy cập vào thiết bị đầu cuối MEX ... nó có URI độc đáo. Tuy nhiên, làm thế nào để bạn truy cập một trong hai IProductService hoặc ICategoryService? Không có gì cho phép bạn phân biệt hai cái khác với URI. WCF không có gì để cho phép nó định tuyến giữa các thư được cho là đi tới dịch vụ IProductservice và những thư được cho là phải truy cập vào ICategoryService. Vì cả hai đều sử dụng cùng một URI, bạn thực sự có xung đột. Mọi HỢP ĐỒNG dịch vụ phải được hiển thị thông qua một URI duy nhất. Mỗi điểm cuối sử dụng cùng một ràng buộc chính xác phải sử dụng một địa chỉ riêng biệt.

Có cách để đạt được những gì bạn cần. Vấn đề là định tuyến tin nhắn. WCF không hỗ trợ thông điệp định tuyến OOB, tuy nhiên nó cung cấp khả năng thực hiện bộ định tuyến tin nhắn của riêng bạn. (Hoặc, nếu bạn sẵn sàng sử dụng công nghệ beta, .NET 4.0 đi kèm với một bộ định tuyến thư, dựa trên các bài viết được liên kết bên dưới, nhưng với khả năng cấu hình được cải thiện.) Michele Bustamante, một phù thủy thật sự của WCF, đã cung cấp hoàn thành việc thực hiện và bài viết mô tả thông điệp định tuyến tại các liên kết sau đây:

http://msdn.microsoft.com/en-us/magazine/cc500646.aspx http://msdn.microsoft.com/en-us/magazine/cc546553.aspx

ý tưởng chung là bạn thiết lập một dịch vụ duy nhất mà lắng nghe trên một URI duy nhất. Dịch vụ này sử dụng công văn ký tự đại diện cho một thao tác dịch vụ đơn lẻ, sau đó xác định URI duy nhất nào sẽ định tuyến từng thông điệp đến. Bạn có thể đưa ra quyết định theo bất kỳ cách nào bạn muốn, tuy nhiên đơn giản nhất là thông qua hành động yêu cầu, giả sử mỗi hành động trên hai giao diện của bạn, IProductService và ICategoryService, là duy nhất toàn cầu. Bạn sẽ kết thúc với nhiều dịch vụ hơn, tuy nhiên ... bản thân router là một dịch vụ WCF riêng biệt cần được lưu trữ giống như bất kỳ dịch vụ nào khác.

+2

+1 cho 'phù thủy thật sự' – dan

+0

@dan: lol: D Cảm ơn bạn. – jrista

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