WCF串說
1、通過在上一篇博客中我們建立第一個自宿主的wcf服務,我們基本上了解了Wcf的作用以及wcf的基本建立方式。我的上一篇博文鏈接: WCF應用(一)
2、這篇博文我就通過建立wcf的另一種宿主方式,iis宿主服務,對wcf的數據契約,操作契約,錯誤契約做個了解應用。
創建wcf的iis宿主服務
創建第一步:在解決方案中添加新建項目IISserver
創建第二步:在添加的新建項目IISserver中客戶端要調用的方法
IService1.cs中代碼:

namespace IISserver { // 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼和配置文件中的接口名“IService1”。 [ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); [OperationContract] //定義為操作契約 int sum(int i,int j); // TODO: 在此添加您的服務操作 } // 使用下面示例中說明的數據約定將復合類型添加到服務操作。 [DataContract] public class CompositeType { bool boolValue = true; string stringValue = "Hello "; [DataMember] public bool BoolValue { get { return boolValue; } set { boolValue = value; } } [DataMember] public string StringValue { get { return stringValue; } set { stringValue = value; } } } }
Service1.svc中代碼

namespace IISserver { // 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼、svc 和配置文件中的類名“Service1”。 public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } //實現接口層中寫入的方法簽名 public int sum(int i, int j) { return i + j; } } }
創建第三步:創建客戶端的應用程序,c#語言可以為控制台程序,web應用程序,winForm應用程序。上一篇博文中穿件的是WinForm程序,這一篇我創建一個Web應用程序。
1、運行創建的iis宿主服務的Service1.svc文件,右鍵點擊文件在瀏覽器中查看即可。復制運行后的地址。
2、在創建的應用程序中,添加服務引用,在出現的對話框中,要求輸地址的框中粘帖上復制過的地址。點擊前往,等發現服務后,點擊確定即可。
在創建的web應用程序中使用服務。代碼。

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; //注意這里添加的引用 using WCFUsing.IIsServiceReference; namespace WCFUsing { public partial class WCFusing : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //在客戶端實例化服務端可操作的類 Service1Client Server1 = new Service1Client(); //使用剛才自己寫在服務端的sum方法 string sumReslut =Server1.sum(1,2).ToString(); Response.Write(sumReslut); } } }
這時候你點擊運行頁面,頁面運行結果就出現了。
注意:
1、我這里沒有部署到iis上,使用的是微軟提供的模擬的iis服務器(ASP.NET Development server),這個服務器是本地測試用的,使用的時候端口不一定,所以鏈接wcf服務的時候要檢查更新服務引用中的地址。
2、由於使用的是微軟提供的本地web服務,所以我們每次使用wcf服務的時候還要注意先運行創建iis宿主服務項目中的sav文件。
3、如果你在服務端更改或添加了方法。那么你就要在客戶端右鍵你添加的服務應用,然后更新。
了解使用數據契約
WCF數據契約(Data Contract)是用來標識用戶自定義類型和序列化。DataContractAttribute、 DataMemberAttribute 來標注自定義數據類型,這樣我們就可以在服務方法中傳遞復雜的數據體了。
1、創建一個Person類,注意添加應用using System.Runtime.Serialization;

namespace IISserver { [DataContract]//數據契約屬性聲明 public class Person { [DataMember(Name = "myName")]//數據成員標記,支持別名定義 public string Name { get; set; } [DataMember(Name="myAge")] public int Age { get; set; } //方法不能被放在數據契約里面,否則編譯失敗。 //[DataMember] //public string SayHello(string name,int age) //{ // return name + ":你好,你明年" + (age + 1).ToString() + "歲!"; //} } }
2、寫一個方法給Person類中的屬性賦值,由於方法不能直接定義在數據契約中,只能定義在服務契約和操作契約中。所以在IService1.cs中添加方法代碼:

public interface IService1 { [OperationContract] string GetData(int value); [OperationContract] CompositeType GetDataUsingDataContract(CompositeType composite); [OperationContract] //定義為操作契約 int sum(int i,int j); [OperationContract] //定義為操作契約 Person SetPerson(Person p); // TODO: 在此添加您的服務操作 }
3、 Service1.svc中實現方法代碼

namespace IISserver { // 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼、svc 和配置文件中的類名“Service1”。 public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { if (composite == null) { throw new ArgumentNullException("composite"); } if (composite.BoolValue) { composite.StringValue += "Suffix"; } return composite; } //實現接口層中寫入的方法簽名 public int sum(int i, int j) { return i + j; } //設置數據契約中Person類中屬性的值 public Person SetPerson(Person p) { p.Name = "小"; p.Age = 3; return p; } } }
4、在重新運行svc文件,在客戶端更新服務引用。應用程序中寫代碼。

using System.Web.UI.WebControls; //注意這里添加的引用 using WCFUsing.IIsServiceReference; namespace WCFUsing { public partial class WCFusing : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //在客戶端實例化服務端可操作的類 Service1Client Server1 = new Service1Client(); //定義為數據契約,這里就能訪問到了 Person p = new Person(); p.myAge = 10; p.myName = "Tom"; //注意這里的p已經是在服務端更新過的。 p=Server1.SetPerson(p); Response.Write(p.myName+p.myAge); //顯示結果是“小三” } } }
附帶說明:在定義表示為數據契約的時候有以下屬性:
DataContract 的屬性
Name / Namespace:自定義名稱和命名空間。
DataMember 的屬性
Name:自定義名稱。
IsRequired:指示該成員序列化前必須被賦值。
了解使用wcf錯誤契約
在默認情況下,服務拋出的異常均以FaultException類型傳遞到客戶端。原因在於任何服務希望與客戶端共享的基於通信錯誤之上的任何異常,都必 須屬於服務契約行為的一部分。為此,WCF提供了錯誤契約,通過它列出服務能夠拋出的錯誤類型。這些錯誤類型應該與 FaultException<T>使用的類型參數的類型相同。只要它們在錯誤契約中列出,WCF客戶端就能夠分辨契約錯誤與其他錯誤之間的區別。
IService1.cs中代碼:

[OperationContract] //定義為操作契約 [FaultContract(typeof(Exception))] //定義為錯誤契約 int sum(int i,int j);
Service1.svc中代碼:

//實現接口層中寫入的方法簽名 public int sum(int i, int j) { if (j == 0) { Exception er = new Exception(); throw new FaultException<Exception>(er, "除數不能為0"); } else { return i / j; } }
Web應用程序中的代碼:

protected void Page_Load(object sender, EventArgs e) { try { Service1Client Server1 = new Service1Client(); Response.Write(Server1.sum(0,0)); //這里設置的為能引發異常的參數 } catch (Exception ex) { Response.Write(ex.Message); //輸出異常信息,輸出“除數不能為零” } }
小結:這樣,你應該也對wcf的應用又有了個進一步的了解吧。呵呵。