به صورت معمول برای پیاده سازی Content Negotiation، مصرف کننده باید در Accept هدر درخواست، برای سرویس مورد نظر، نوع Content-Type را نیز تعیین نمایید. از طرفی سرویس دهنده نیز باید معادل Mime Type درخواست شده، یک Formatter جهت سریالایز دادهها در اختیار داشته باشد. در WCF از طریق کتابخانه WcfRestContrib میتوانیم به صورت زیر Content Negotiation را پیاده سازی نماییم:
ابتدا از طریق Nuget کتابخانه زیر را نصب کنید:
install-package WcfRestContrib
[ServiceContract] public interface IBooksService { [OperationContract] void AddBook(string isbn, Book book); }
[ServiceContract] public interface IBooksService { [WebInvoke(UriTemplate = "/{isbn}", Method=Verbs.Put)] [WebDispatchFormatter] [OperationContract] void AddBook(string isbn, Book book); .... }
گام بعدی مشخص کردن انواع MimeTypeها برای این سرویس است. در WcfRestContrib به صورت پیش فرض چهار Formatter تعبیه شده است:
»Xml : از DataContractSerializer موجود در WCF برای سریالاز و دی سریالایز دادهها استفاده میکند.
»Json : از طریق DataContactJsonSerializer برای سریالاز و دی سریالایز دادهها استفاده میکند.
POX : همانند مورد اول از DataContractSerializer استفاده میکند با این تفاوت که DataContractها بدون Namesapce و Attribute و DataMemberها نیز بدون Order میباشند.
»Form Url Encoded
در صورتی که نیاز به formatter دیگری دارید میتوانید با استفاده از CustomFormatter موجود در این کتابخانه، Formatter دلخواه خود را پیاده سازی نمایید.
همان طور که در بالا ذکر شد، در صورتی که MimeType درخواست شده از سوی مصرف کننده، سمت سرور تعریف نشده باشد، MimeType پیش فرض انتخاب میشود. برای تعریف MimeType پیش فرض میتوان از خاصیت WebDispatchFormatterConfigurationAttribute که در فضای نام WcfRestContrib.ServiceModel.Description قرار دارد استفاده کرد. تعاریف سایر MimeTypeها نیز با استفاده از WebDispatchFormatterMimeTypeAttribute انجام میشود. به صورت زیر:
[WebDispatchFormatterConfiguration("application/xml")] [WebDispatchFormatterMimeType(typeof(WcfRestContrib.ServiceModel.Dispatcher.Formatters.PoDataContract), "application/xml", "text/xml")] [WebDispatchFormatterMimeType( typeof(WcfRestContrib.ServiceModel.Dispatcher.Formatters.DataContractJson), "application/json")] [WebDispatchFormatterMimeType( typeof(WcfRestContrib.ServiceModel.Dispatcher.Formatters.FormUrlEncoded), "application/x-www-form-urlencoded")] public class Books : IBooksService { public void AddBook(string isbn, Book book) { } }
<system.serviceModel> <extensions> <behaviorExtensions> <add name="webFormatter" type="WcfRestContrib.ServiceModel.Configuration.WebDispatchFormatter.ConfigurationBehaviorElement, WcfRestContrib, Version=x.x.x.x, Culture=neutral, PublicKeyToken=89183999a8dc93b5"/> </behaviorExtensions> </extensions> <serviceBehaviors> <behavior name="Rest"> <webFormatter> <formatters defaultMimeType="application/xml"> <formatter mimeTypes="application/xml,text/xml" type="WcfRestContrib.ServiceModel.Dispatcher.Formatters.PoxDataContract, WcfRestContrib"/> <formatter mimeTypes="application/json" type="WcfRestContrib.ServiceModel.Dispatcher.Formatters.DataContractJson, WcfRestContrib"/> <formatter mimeTypes="application/x-www-form-urlencoded" type="WcfRestContrib.ServiceModel.Dispatcher.Formatters.FormUrlEncoded, WcfRestContrib"/> </formatters> </webFormatter> </behavior> </serviceBehaviors> </system.serviceModel>
در صورتی که قصد داشته باشیم که باتوجه به direction مورد نظر (نظیر Outgoing یا Incoming) دادهها سریالایز/ دی سریالایز شوند، میتوان این مورد را در هنگام تعریف OperationContract تعیین کرد:
[WebDispatchFormatter(WebDispatchFormatter.FormatterDirection.Outgoing)]
مطلب تکمیلی:
مشاهده پیاده سازی Content Negotiation در Asp.Net MVC