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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

c#进阶(5)—— WCF 实现简单预订功能

發布時間:2023/12/10 C# 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c#进阶(5)—— WCF 实现简单预订功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、WCF概述

WCF全稱為Windows Communication Foundation,在.Net 3.0 中引入,用于客戶端與服務端通信,替換了之前的一些技術,如.Net Remoting 及 WSE。

WCF 相比ASP.NET Web API 復雜,但提供了更多的功能,如

(1)、可靠性

(2)、事務

(3)、Web服務安全

如果不需要這些先進的通信功能,ASP.NET Web API是更好的選擇。

2、WCF 主要功能

(1)、存儲組件和服務,可以將WCF服務存放在ASP.NET 運行庫、Windows服務、COM+進程或WPF應用程序中,進行對等計算

(2)、聲明行為,不需要繼承基類,可以使用屬性定義服務。

(3)、通信信道,WCF提供了用HTTP、TCP、IPC信道進行通信的多條信道,支持自定義信道。

(4)、安全結構,為實現獨立于平臺的WEB服務,必須使用標準化的安全環境,標準用WSE3.0實現。

(5)、可擴展性,支持將功能注入客戶端和服務端的消息流。

(6)總結

!最終目標:通過進程或不同系統,通過本地網絡或Internet收發客戶端和服務之間的消息,如果需要以獨立于平臺的方式盡快收發消息,就應該使用WCF。

!遠距離視圖

服務提供了一個端點,由協定、綁定、地址描述。

a:協定,定義了服務提供的操作

b:綁定,給出了協議和編碼信息

c:地址,是服務的位置,客戶端需要一個兼容的端點來進行訪問。

3、WCF 組件及步驟解讀

?

步驟解讀:

(1)、客戶端,客戶端調用代理的一個方法

(2)、代理,代理將方法調用轉化為一條消息,并把該消息傳輸到信道上。

(3)、信道,包含客戶端部分及服務端部分,他們通過網絡協議進行通信,在信道上,把消息傳遞給調度程序。

(4)、調度程序,將消息轉換為服務調用的方法調用。

4、WCF 其他重要技術

(1)、SOAP協議

服務從客戶端接收SOAP消息,并返回一條SOAP響應消息,SOAP消息包含信封,信封包含標題和正文。

(2)、WSDL

WSDL文檔描述了服務的操作和消息,WSDL定義了服務的元數據,這些元數據用于為客戶端應用程序創建代理。

WSDL包含如下信息:

a:消息的類型——用XML架構描述

b:從服務中收發的信息——消息的各部分用XML架構定義的類型

c:端口類型——映射服務協定,列出用服務協定定義的操作,操作包含信息,如與請求和響應序列一起使用的輸入和輸出消息

d:綁定信息——包含用端口類型列出的操作,并定義使用的SOAP變體

e:服務信息——把端口類型映射到端點地址

5、WCF實戰——預定會議室

5.1 前言

業務場景,存儲會議室預訂信息,應用mysql數據庫中的roomreservations表存儲預訂信息,

a:主要實施步驟包括

(1)創建服務和數據協定

(2)使用 自定義類庫 訪問數據庫

(3)實現服務

(4)使用WCF服務宿主(Service Host)和WCF測試客戶端(Test Client)

(5)創建定制的服務宿主

(6)使用元數據創建客戶應用程序

(7)使用共享的協定創建客戶應用程序

(8)配置診斷設置

b:主要包括:數據訪問類、協定(服務協定、數據協定)、自定義宿主程序、客戶端、服務實現。

類說明:

(1)Net.BCloudSoft.Core.DataAccess 數據訪問底層代碼。

RoomReservationData 調用數據訪問提供的ExecuteNonQuery方法,實現數據的寫入。

(2)RoomReservationContracts ,定義數據協定及服務協定,其中數據協定是數據實體映射,采用DataContract 及 DataMemeber 分別標記類及屬性。服務協定,是一個接口類,包括服務協定及操作協定,接口類中聲明方法,如ReserveRoom等,在類上添加ServiceContract,在方法上標記OperationContract。

(3)RoomReservationHost,自定義服務宿主,控制臺程序,由StartService、StopService組成,Open方法會啟動服務的監聽器信道,Close方法會停止信道,主要用到的核心類是ServiceHost,ServiceHost類實例化時,可以將服務及服務地址進行處理。

(4)RoomReservationService 服務實現,實現服務協定中定義的接口方法。

(5)RoomReservationClient ,WPF作為客戶端,右鍵添加服務引用,選取Service服務,此時會為RoomReservationService服務生成代理,代理類中會自動生成異步方法,使用async及await關鍵字調用ReserveRoomAsync() 異步方法,使訂閱功能支持異步。

5.2 具體實現

(1)創建數據協定和服務協定

  整體結構:

1.1 創建數據協定

創建RoomReservationContracts類庫,新建RoomReservation類,該類主要包含數據協定,具體屬性字段與數據庫中表對應。

using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace RoomReservationContracts {/// <summary>/// 數據協定/// </summary>[DataContract]public class RoomReservation : INotifyPropertyChanged{private int _id;private string _roomName;private DateTime _startTime;private DateTime _endTime;private string _contact;private string _text;/// <summary>///要通過WCF服務發送數據, 引入DataContract 和 DataMember 特性對該類進行注解/// </summary>[DataMember]public int Id{get { return _id; }set { SetProperty(ref _id, value); }}[DataMember][StringLength(45)]public string RoomName{get { return _roomName; }set { SetProperty(ref _roomName, value); }}[DataMember]public DateTime StartTime{get { return _startTime; }set { SetProperty(ref _startTime, value); }}[DataMember]public DateTime EndTime{get { return _endTime; }set { SetProperty(ref _endTime, value); }}[DataMember][StringLength(45)]public string Contact{get { return _contact; }set { SetProperty(ref _contact, value); }}[DataMember][StringLength(45)]public string Text{get { return _text; }set { SetProperty(ref _text, value); }}/// <summary>/// 接口需實現的事件方法/// </summary>public event PropertyChangedEventHandler PropertyChanged;/// <summary>/// 得知屬性發生變更時(定義為protected virtual 允許子類覆寫本方法)/// </summary>/// <param name="propertyName">屬性字段</param>protected virtual void OnNotifyPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}/// <summary>/// 設置屬性/// </summary>/// <typeparam name="T">傳入的類型參數</typeparam>/// <param name="item">字段名</param>/// <param name="value">字段值</param>/// <param name="propertyName"></param>protected virtual void SetProperty<T>(ref T item,T value,[CallerMemberName] string propertyName = null){//如果兩個類型的對象T 是否不等if (!EqualityComparer<T>.Default.Equals(item, value)){item = value;OnNotifyPropertyChanged(propertyName);}}} }

1.2 創建服務協定

服務提供的操作可由接口定義,服務協定用ServiceContract特性定義,操作由OperationContract特性定義

using System; using System.ServiceModel; namespace RoomReservationContracts {/// <summary>/// 服務協定/// </summary>[ServiceContract(Namespace ="http://www.myfirstwcfservice.com/RoomReservation/2017")]public interface IRoomService{[OperationContract]bool ReserveRoom(RoomReservation roomReservation);[OperationContract]RoomReservation[] GetRoomReservations(DateTime fromTime, DateTime dateTime);} }

(2)、創建數據訪問接口及實現類

本實例中使用自定義的數據訪問類,基于反射實現的數據訪問接口。采用該類添加RoomReservationData 類庫,實現具體操作協定。

using System; using RoomReservationContracts; using Net.BCloudSoft.Core.DataAccess; using System.Data; using System.Collections.Generic;namespace RoomReservationData {/// <summary>/// 實現服務類/// </summary>public class RoomReservationRepository{/// <summary>/// 預訂房間/// </summary>/// <param name="roomReservation"></param>public bool ReserveRoom(RoomReservation roomReservation){try{IDataAccess dataAccess = DataAccessFactory.Instance().GetDataAccess("server=127.0.0.1;database=wcfstudy_db;uid=root;pwd=admin;");string insertSql = string.Format("INSERT INTO wcfstudy_db.roomreservations VALUES" +"({0},'{1}','{2}','{3}','{4}','{5}')",roomReservation.Id,roomReservation.RoomName,roomReservation.StartTime,roomReservation.EndTime,roomReservation.Contact,roomReservation.Text);dataAccess.ExecuteNonQuery(insertSql);return true;}catch (Exception ex){throw ex;}}/// <summary>/// 獲取所有預訂信息/// </summary>/// <param name="fromTime"></param>/// <param name="toTime"></param>/// <returns></returns>public RoomReservation[] GetReservations(DateTime fromTime,DateTime toTime){try{IDataAccess dataAccess = DataAccessFactory.Instance().GetDataAccess("MySqlDataAccess");DataTable dt = dataAccess.ExecuteDataTable(string.Format("SELECT * FROM [wcfstudy_db].[roomreservations] WHERE [StartTime] > '{0}' AND [EndTime] <'{1}'", fromTime, toTime));List<RoomReservation> list = new List<RoomReservation>();foreach (DataRow row in dt.Rows){RoomReservation roomReservation = new RoomReservation();roomReservation.Id = int.Parse(row["Id"].ToString());roomReservation.RoomName = row["RoomName"].ToString();roomReservation.StartTime = Convert.ToDateTime(row["StartTime"]);roomReservation.EndTime = Convert.ToDateTime(row["EndTime"]);roomReservation.Contact = row["Contact"].ToString();roomReservation.Text = row["Text"].ToString();list.Add(roomReservation);}return list.ToArray();}catch (Exception ex){throw ex;}}} }

(3)、服務的實現

  3.1 基于 WCF 服務庫直接生成的模型,默認包含服務協定和服務實現。

  a:根據模板創建的服務實現

?

  b:根據模板創建的服務協定

  3.2 如果客戶應用程序只使用 元數據 信息來創建訪問服務的代理,則使用visio studio 創建基于 WCF 服務庫的模板是可行的。

但是,如果客戶端直接使用協定類型,則最好把協定放在一個獨立的程序集中如本例所示

?

  3.3 本案例中服務的實現

using System; using RoomReservationContracts; using RoomReservationData; using System.ServiceModel;namespace RoomReservationService {[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]public class RoomReservationService : IRoomService{/// <summary>/// 獲取所有預訂信息/// </summary>/// <param name="fromTime">開始時間</param>/// <param name="dateTime">結束時間</param>/// <returns></returns>public RoomReservation[] GetRoomReservations(DateTime fromTime, DateTime dateTime){RoomReservationRepository repository = new RoomReservationRepository();return repository.GetReservations(fromTime, dateTime);}/// <summary>/// 預訂房間/// </summary>/// <param name="roomReservation"></param>/// <returns></returns>public bool ReserveRoom(RoomReservation roomReservation){RoomReservationRepository repository = new RoomReservationRepository();return repository.ReserveRoom(roomReservation);}} }

    3.4 配置AppConfig

  在創建WCF 服務庫時會創建AppConfig 文件,主要用于配置服務實現及服務協定,具體配置方法如下所示

<?xml version="1.0" encoding="utf-8" ?> <configuration><appSettings><add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /></appSettings><system.web><compilation debug="true" /></system.web><!-- 部署服務庫項目時,必須將配置文件的內容添加到主機的 app.config 文件中。System.Configuration 不支持庫的配置文件。 --><system.serviceModel><services><!--service 節點中 配置 實現類--><service name="RoomReservationService.RoomReservationService"><!--contract 節點中配置接口類--><endpoint address="" binding="basicHttpBinding" contract="RoomReservationContracts.IRoomService"><identity><dns value="localhost" /></identity></endpoint><endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /><host><baseAddresses><add baseAddress="http://localhost:8733/Design_Time_Addresses/RoomReservationService/Service1/" /></baseAddresses></host></service></services><behaviors><serviceBehaviors><behavior><!-- 為避免泄漏元數據信息,請在部署前將以下值設置為 false --><serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/><!-- 要接收故障異常詳細信息以進行調試,請將以下值設置為 true。在部署前設置為 false 以避免泄漏異常信息 --><serviceDebug includeExceptionDetailInFaults="False" /></behavior></serviceBehaviors></behaviors></system.serviceModel></configuration>

?(4)使用WCF服務宿主和WCF測試客戶端

  將RoomReservationService 類設置為啟動項目,啟動項目,WCF服務主機會啟動WCF測試客戶端,該測試客戶端可用于測試應用程序,在輸入參數后,點擊‘調用’,會執行操作,輸入測試數據可查看到響應結果。如下圖:

   查看數據庫,可知數據已經完成寫入操作

?

(5)創建定制的服務宿主

使用WCF可以在任何宿主上運行服務,可以為對等服務創建一個WPF應用程序,可以創建一個Windows 服務,使用WAS 或 IIS 存放該服務,控制臺程序也可以演示簡單的自定義宿主。創建自定義宿主必須引入 System.ServiceModel和RoomReservationService。具體實現思路是,調用Open方法啟動服務的監聽器信道,該服務準備用于監聽請求。Close方法會停止信道。代碼如下:

using System; using System.ServiceModel; using System.ServiceModel.Description; using RoomReservationService; using static System.Console;/// <summary> /// 自定義服務宿主 /// </summary> namespace RoomReservationHost {public class Program{internal static ServiceHost _serviceHost = null;/// <summary>/// 開啟服務監聽/// </summary>internal static void StartService(){try{//ServiceHost的構造函數第二個參數定義了服務的基地址,可以設置默認綁定,HTTP//的默認值是basicHttpBinding_serviceHost = new ServiceHost(typeof(RoomReservationService.RoomReservationService),new Uri("http://localhost:9000/RoomReservation"));_serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior{//獲取設置一個值,指示是否發布服務元數據以使用Http/Get請求進行檢索。HttpGetEnabled = true});}catch (AddressAccessDeniedException){WriteLine("地址禁止訪問,使用netsh.exe 注冊監聽端口");throw;}}/// <summary>/// 停止服務監聽/// </summary>internal static void StopService(){if(_serviceHost != null && _serviceHost.State== CommunicationState.Opened){_serviceHost.Close();}}static void Main(){StartService();WriteLine("服務正在運行,請退出");ReadLine();StopService();}} }

除以上使用編碼方式實現WCF配置外,還可以通過,右鍵RoomReservationServcie 的App.config文件,點擊 編輯 WCF 配置,如下圖所示

?

(6)使用元數據創建客戶應用程序

  此業務場景下,創建一個包含控件的WPF應用程序,命名為RoomReservationClient。如下圖所示

添加服務引用,右鍵選取RoomReservationClient類庫,添加 服務引用,點擊發現,查找當前解決方案下的服務,將名稱空間設置為RoomReservationService,這將為生成的代理類定義名稱。如下圖所示:

? 根據數據協定把RoomReservation 引入到RoomReservationClient 中,RoomServiceClient 是RoomReservationService的客戶端代理類(RoomServiceClient 是由上圖執行后生成的),該客戶端包含由操作協定定義的方法,使用這個客戶端,可以將會議室預定信息發送給正在運行的服務。

在代碼MainWindow.xaml.cs中,通過click 事件調用的OnReserveRoom方法,通過代理類調用ReserveRoomAsync。_roomReservation 為操作的數據源。代碼如下

using System; using System.Windows; using RoomReservationClient.RoomReservationService;namespace RoomReservationClient {/// <summary>/// MainWindow.xaml 的交互邏輯/// </summary>public partial class MainWindow : Window{private RoomReservationService.RoomReservation _roomReservation;public MainWindow(){InitializeComponent();_roomReservation.StartTime = DateTime.Now;_roomReservation.EndTime = DateTime.Now.AddHours(1);this.DataContext = _roomReservation;}private async void onReserveRoom(object sender, RoutedEventArgs e){//RoomServiceClient 是客戶端的代理,該客戶端包含由操作協定定義的方法,使用這個客戶端,//可以將會議室預定信息發送給正在運行的服務。var client = new RoomServiceClient();bool reserved = await client.ReserveRoomAsync(_roomReservation);client.Close();if (reserved){MessageBox.Show("實體保存成功!");}}} }

6、最后

  參考的案例還有診斷及與客戶端共享協定程序集兩部分內容,兩部分內容的具體實現并沒有跟著書本完成,有興趣的同學可以自行查看,參考的源代碼路徑為http://www.wrox.com/go/professionalcsharp6

總結

以上是生活随笔為你收集整理的c#进阶(5)—— WCF 实现简单预订功能的全部內容,希望文章能夠幫你解決所遇到的問題。

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