日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

传说中的WCF(6):数据协定(b)

發布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 传说中的WCF(6):数据协定(b) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們繼續,上一回我們了解了數據協定的一部分內容,今天我們接著來做實驗。好的,實驗之前先說一句:實驗有風險,寫代碼須謹慎。

實驗開始!現在,我們定義兩個帶數據協定的類——Student和AddrInfo。

[DataContract]public class Student{[DataMember]public string Name;[DataMember]public string Phone;[DataMember]public AddrInfo Address;} [DataContract]public class AddrInfo{[DataMember]public string Province;[DataMember]public string City;[DataMember]public string DetailAddr;}


這兩個類有一個特征,Student類的Address字段是一個AddrInfo對象,而我們的服務定義如下:

[ServiceContract(Namespace = "MyNamespace")]public interface IService{[OperationContract]Student GetStudentInfo();} public class MyService : IService{public Student GetStudentInfo(){Student stu = new Student();AddrInfo info = new AddrInfo();info.Province = "廣東省";info.City = "佛山市";info.DetailAddr = "火星路-300號";stu.Name = "小陳";stu.Phone = "1388888888";stu.Address = info;return stu;}}

方法返回的Student對象,那么,我們來測試一下,AddrInfo能不能被成功序列化和反序列化。下面是注冊和啟動服務的代碼:

static void Main(string[] args){// 服務器基址Uri baseAddress = new Uri("http://localhost:1378/services");// 聲明服務器主機using (ServiceHost host = new ServiceHost(typeof(MyService), baseAddress)){// 添加綁定和終結點WSHttpBinding binding = new WSHttpBinding();host.AddServiceEndpoint(typeof(IService), binding, "/test");// 添加服務描述host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });try{// 打開服務host.Open();Console.WriteLine("服務已啟動。");}catch (Exception ex){Console.WriteLine(ex.Message);}Console.ReadKey();}}

在客戶端生成的代碼中,兩個類都可以正確生成。

客戶端測試代碼如下:

static void Main(string[] args){WS.ServiceClient cli = new WS.ServiceClient();WS.Student stu = cli.GetStudentInfo();string msg = "學生姓名:{0}\n聯系電話:{1}\n" +"地址信息:-----------\n" +"省份:{2}\n" +"市區:{3}\n" +"詳細地址:{4}";Console.WriteLine(msg, stu.Name, stu.Phone, stu.Address.Province, stu.Address.City, stu.Address.DetailAddr);Console.ReadKey();}


其運行結果如下:

?

?

下面我們繼續實驗。

每個學生可能有多個學科的成績,因此,我們為學生類再添加一個成績屬性。

[DataContract]public class Student{[DataMember]public string Name;[DataMember]public string Phone;[DataMember]public AddrInfo Address;[DataMember]public object Scores;} public class MyService : IService{public Student GetStudentInfo(){Student stu = new Student();AddrInfo info = new AddrInfo();info.Province = "廣東省";info.City = "佛山市";info.DetailAddr = "火星路-300號";stu.Name = "小陳";stu.Phone = "1388888888";stu.Address = info;Dictionary<string, float> m_scores = new Dictionary<string, float>();m_scores.Add("語文", 97f);m_scores.Add("英語", 64.5f);m_scores.Add("數學", 38f);m_scores.Add("歷史", 77.6f);m_scores.Add("地理", 82.3f);stu.Scores = m_scores;return stu;}}


客戶端測試代碼改為:

static void Main(string[] args){WS.ServiceClient cli = new WS.ServiceClient();WS.Student stu = cli.GetStudentInfo();string msg = "學生姓名:{0}\n聯系電話:{1}\n" +"地址信息:-----------\n" +"省份:{2}\n" +"市區:{3}\n" +"詳細地址:{4}";Console.WriteLine(msg, stu.Name, stu.Phone, stu.Address.Province, stu.Address.City, stu.Address.DetailAddr);Console.WriteLine("---------------------------------------");Console.WriteLine("學生成績單:");Dictionary<string, float> scores = stu.Scores as Dictionary<string, float>;foreach (var item in scores){Console.Write("{0}:{1}\n", item.Key, item.Value);}Console.ReadKey();}

現在來測試,就會發生異常,因為我們為Student類加的成績屬性是object類型,而我們在協定方法中給它賦的是 Dictionary<string, float>類型,這樣一來,就算可以序列化也不能被反序列化,因為Dictionary<string, float>無法識別。

現在,我們再為Student類添加一個KnownType特性,看它能不能識別。

[DataContract]
[KnownType(typeof(Dictionary<string, float>))]
public class Student
{
。。。。。
}


這時候,再運行一下。

很可惜,還是報錯了,

?

怎么辦呢?不要放棄,我們繼續把學生類修改一下。

[DataContract][KnownType("GetKnowTypes")]public class Student{[DataMember]public string Name;[DataMember]public string Phone;[DataMember]public AddrInfo Address;[DataMember]public object Scores;static Type[] GetKnowTypes(){return new Type[] { typeof(Dictionary<string,float>) };}}

GetKnowTypes方法是靜態方法,KnownType的構造函數中傳遞該方法的名字。看看這回調用能否成功?


堅持就是勝利,看到了吧,這回OK了!高興吧。

?

這里我們可以總結一下,在一些比較復雜的類型無法反序列化(不能識別類型)的時候,就得考慮使用KnownTypeAttribute來標注可能涉及到的外部類型,但如果遇到像泛型這些較為復雜的類型,就要考慮在帶數據協定的類中添加一個靜態方法,該方法返回Type 的IEnumerable,一般是Type[]就可以了,而在KnownTypeAttribute的構造函數中使用這個方法的名字。

轉載于:https://www.cnblogs.com/GoogleGetZ/p/5752323.html

總結

以上是生活随笔為你收集整理的传说中的WCF(6):数据协定(b)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。