2009-03-18 18 views
6

Để có được một dịch vụ WCF làm việc với JQuery Tôi đã thêm một thuộc tính WebInvoke trên hợp đồng hoạt động để kiểm soát serialization JSON như sau:thể WebInvoke thuộc tính được thay thế bằng cấu hình ràng buộc

[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] 

Có cách nào để kiểm soát việc tuần tự hóa này thông qua các ràng buộc dịch vụ trong cấu hình thay vì nó giới hạn dịch vụ này từ việc cung cấp các nối tiếp khác nhau đến các điểm cuối khác nhau.

Trả lời

5

Tôi có một giải pháp khác, hoạt động ở đầu đối diện từ @Marc Gravell: thay vì sao chép hợp đồng, lấy được 2 lớp khác nhau từ dịch vụ triển khai. Đây chỉ là bí danh loại; chúng là cần thiết vì hệ thống kích hoạt WCF (ít nhất là trên IIS) sẽ không cho phép bạn kích hoạt cùng một loại dịch vụ tại các URL khác nhau (Tôi không chắc tại sao giải pháp của Gravell không chạy vào vấn đề này - lỗi mà tôi nhận được là "Đăng ký đã tồn tại cho URI ..." khi tôi cố gắng kích hoạt cùng một lớp dịch vụ tại các URL khác nhau trên cùng một trang web). Lưu ý rằng đây chỉ là vấn đề nếu bạn muốn chạy cùng một dịch vụ với pox và json đồng thời. Nếu tất cả những gì bạn muốn là kiểm soát định dạng phản hồi, bạn không cần giải pháp này.

Khái niệm chính đằng sau giải pháp của tôi là sử dụng 2 URI khác nhau cho cùng một dịch vụ, sau đó sử dụng hành vi điểm cuối để đặt định dạng phản hồi đi mặc định. Bạn có thể tìm hiểu thêm trong this question, cũng liên quan đến độ tinh khiết của câu hỏi: chúng ta có nên sử dụng các thuộc tính hợp đồng để chỉ định các thuộc tính là một phần của giao thức mạng không? Tôi nghĩ rằng Marc Gravell của vấn đề này là hợp lệ cho mỗi se, nhưng nó không phù hợp khái niệm ban đầu của WCF, trong đó hợp đồng được cho là trừu tượng ra khỏi ngăn xếp giao thức. Nhưng các hành vi điểm cuối sẽ không cho phép bạn chỉ định tất cả các thuộc tính liên quan đến REST, bạn sẽ phải sử dụng các thuộc tính cho các mẫu URI và định dạng gửi đến.

REST có thể đã được triển khai khác nhau không? Mặc dù các nhà thiết kế của WCF đã làm một công việc tuyệt vời của việc thiết kế một khuôn khổ chung, tôi không nghĩ rằng họ thấy REST sắp tới. Một số thứ, như mẫu URI, thực sự dường như thuộc về hợp đồng.

Đủ nói chuyện! Đây là mã. Đầu tiên là tệp web.config. Đây là nơi ma thuật xảy ra. Lưu ý rằng tôi đang sử dụng kích hoạt dựa trên cấu hình WCF 4 trong ví dụ này, nhưng bạn cũng có thể thực hiện điều tương tự bằng cách có 2 tệp svc đại diện cho 2 URI.

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <services> 
     <service name="StackOverflow.QuoteOfTheDayAsJson"> 
     <endpoint binding="webHttpBinding" contract="StackOverflow.IQuoteOfTheDay" 
        behaviorConfiguration="jsonBehavior" /> 
     </service> 
     <service name="StackOverflow.QuoteOfTheDayAsPox"> 
     <endpoint binding="webHttpBinding" contract="StackOverflow.IQuoteOfTheDay" 
        behaviorConfiguration="poxBehavior" /> 
     </service> 
    </services> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name="jsonBehavior"> 
      <webHttp defaultOutgoingResponseFormat="Json" /> 
     </behavior> 
     <behavior name="poxBehavior"> 
      <webHttp defaultOutgoingResponseFormat="Xml"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false"> 
     <serviceActivations> 
     <add relativeAddress="QuoteOfTheDayJson.svc" 
      service="StackOverflow.QuoteOfTheDayAsJson"/> 
     <add relativeAddress="QuoteOfTheDayPox.svc" 
      service="StackOverflow.QuoteOfTheDayAsPox"/> 
     </serviceActivations> 
    </serviceHostingEnvironment> 
    </system.serviceModel> 
</configuration> 

Và đây là các mã, trong đó có hợp đồng dịch vụ, thực hiện dịch vụ, và các bí danh kiểu đó là cần thiết để làm cho công việc này:

namespace StackOverflow 
{ 
    [DataContract] 
    public class Quotation 
    { 
     [DataMember] 
     public string Text { get; set; } 

     [DataMember] 
     public string Author { get; set; } 
    } 

    [ServiceContract] 
    public interface IQuoteOfTheDay 
    { 
     [OperationContract] 
     [WebInvoke(Method="GET", UriTemplate="GetTodaysQuote")] 
     Quotation GetTodaysQuote(); 
    } 

    public class QuoteOfTheDayImp : IQuoteOfTheDay 
    { 
     public Quotation GetTodaysQuote() 
     { 
      return new Quotation() 
      { 
       Text = "Sometimes it's better to appologize for not asking permission", 
       Author = "Admiral Grace Murray Hopper" 
      }; 
     } 
    } 

    /// <summary> 
    /// A type alias used for json activation 
    /// </summary> 
    public class QuoteOfTheDayAsJson : QuoteOfTheDayImp 
    {} 

    /// <summary> 
    /// A type alias used for pox activation 
    /// </summary> 
    public class QuoteOfTheDayAsPox : QuoteOfTheDayImp 
    {} 
} 

Nếu nó không được cho sự cần thiết của các bí danh loại , Tôi muốn nói đây là một giải pháp hoàn chỉnh. Đó là một giải pháp hoàn chỉnh nếu bạn không muốn hỗ trợ nhiều định dạng cùng một lúc. Điều này vượt trội so với giải pháp hợp đồng nhiều về mặt này, vì chỉ có một hợp đồng, bạn không cần phải đồng bộ hóa 2 hợp đồng.

+0

Câu trả lời tuyệt vời! –

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