WCF服務的建立以及調用


WCF對我來說既陌生又熟悉,陌生是因為沒怎么接觸過,熟悉是聽得太多,今天抽出點時間看了一下WCF,並且自己也寫了一WCF的小程序以及調用WCF。步驟為:

1.創建一個解決方案WCF,和一個控制台項目WCFTestService(這就就是WCF服務)

2.配置WCF服務的App.Config

3.寫WCF服務代碼

4.新建項目WCFTestClient(客戶端項目,用來測試訪問服務)

5.寫客戶端代碼

6.執行訪問服務

下面詳細說明每步的操作以及代碼編寫:

1.創建一個解決方案WCF,和一個控制台項目WCFTestService(這就就是WCF服務)

這一步是基礎,肯定都會創建,就不在累贅。此處省略一萬字··········

2.配置WCF服務的App.Config

 首先我先貼上真個App.Config的內容

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="" maxReceivedMessageSize="300000000" defaultOutgoingResponseFormat="Json" helpEnabled="true" automaticFormatSelectionEnabled="true">
          <readerQuotas maxArrayLength="30000000" />
        </standardEndpoint>
      </webHttpEndpoint>
    </standardEndpoints>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingConfig" sendTimeout="00:10:00" bypassProxyOnLocal="false" maxReceivedMessageSize="2147483646">
          <readerQuotas maxStringContentLength="2147483646" maxArrayLength="2147483646" />
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <!-- 注意: 服務名稱必須與服務實現的名稱相匹配。 -->
      <service name="WCFTestService.DbApiInfo" behaviorConfiguration="RestServiceBehavior">
        <!-- 注意: 服務必須有一個 http 基址以便添加此終結點。 -->
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8888/Service/DbApiInfo" />
          </baseAddresses>
        </host>
        <!-- 添加下列終結點。 -->
        <endpoint address="" behaviorConfiguration="RestEndpointBehavior" binding="webHttpBinding" bindingConfiguration="webHttpBindingConfig" contract="WCFTestService.IApiInfo">
          <identity>
            <dns value="Localhost" />
          </identity>
        </endpoint>
      </service>
      <!-- 注意: 服務名稱必須與服務實現的名稱相匹配。 -->
      <service name="WCFTestService.DbUpLoad" behaviorConfiguration="RestServiceBehavior">
         <!--注意: 服務必須有一個 http 基址以便添加此終結點。--> 
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8888/Service/DbUpLoad" />
          </baseAddresses>
        </host>
         <!--添加下列終結點。--> 
        <endpoint address="" behaviorConfiguration="RestEndpointBehavior" binding="webHttpBinding" bindingConfiguration="webHttpBindingConfig" contract="WCFTestService.IUpLoad">
          <identity>
            <dns value="Localhost" />
          </identity>
        </endpoint>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="RestEndpointBehavior">
          <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="RestServiceBehavior">
          <!-- 將下列元素添加到服務行為配置中。 -->
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
View Code

仔細觀察這個代碼,大家就會發現,這App.Config的內容就比我們新生成的App.Config多了一個節點<system.serviceModel></system.serviceModel>

以及他里面包含大內容。

<system.serviceModel></system.serviceModel>就是我們的服務配置內容。

最重要的是<system.serviceModel></system.serviceModel>里面的節點<services></services>,這才是服務配置的重點,

在這個節點里我們看到有兩個<service></service>節點,每個<service></service>節點就是一個配置服務。

我們拿出一個<service></service>節點來說明:

<!-- 注意: 服務名稱必須與服務實現的名稱相匹配。 -->
<service name="WCFTestService.DbApiInfo" behaviorConfiguration="RestServiceBehavior">
<!-- 注意: 服務必須有一個 http 基址以便添加此終結點。 -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:8888/Service/DbApiInfo" />
</baseAddresses>
</host>
<!-- 添加下列終結點。 -->
<endpoint address="" behaviorConfiguration="RestEndpointBehavior" binding="webHttpBinding" bindingConfiguration="webHttpBindingConfig" contract="WCFTestService.IApiInfo">
<identity>
<dns value="Localhost" />
</identity>
</endpoint>
</service>

name="WCFTestService.DbApiInfo":顧名思義,就是服務的名稱。不同的服務名稱肯定不同。WCFTestService是命名空間

<add baseAddress="http://localhost:8888/Service/DbApiInfo" />:這個是服務的訪問地址。

contract="WCFTestService.IApiInfo">:是服務的接口。WCFTestService是命名空間

注意:每次要新增一個服務的時候,就新建一個節點<service></service>,並且修改上面三個所有對應的名稱,這樣配置文件就OK了。

對於沒有其他特殊需求的時候,配置文件其他地方是不需要修改的。由於只是一個簡單的WCF測試服務,其他的我也就不說了,免得累贅。

3.寫WCF服務代碼

編寫WCF代碼,分為三步:

(1)添加一個服務對應的接口:如服務 "WCFTestService.DbApiInfo"對應的接口:IApiInfo(就是上面提到的接口名稱要和上面一致)

[ServiceContract]
    public interface IApiInfo
    {
        [OperationContract]
        [ServiceKnownType(typeof(string))]
        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
        string CreateApi(Stream name);
    }

我們定義了[ServiceContract]標簽,此標簽代表此接口及實現此接口的類都是對外發布的Service類,在每個需要對外發布的方法上都加上[OperationContract]標簽,以使外部可以訪問到此方法。兩個標簽缺一,方法都不能被外部訪問。
[ServiceContract]和[OperationContract]這兩個標簽需要導入using System.ServiceModel命名空間。

(2)添加接口對應的實現類:DbApiInfo.cs

public class DbApiInfo:IApiInfo
    {

        public string CreateApi(Stream name)
        {
            //name.Position = 0;
            StreamReader reader = new StreamReader(name);
            string text = reader.ReadToEnd();

            return "你的名字是:" + text;
        }
    }

(3)啟動服務的代碼編寫

啟動服務的方法是

 private static List<ServiceHost> _LsSvcHost = new List<ServiceHost>();
public
static void StartSvc() { try { ServicesSection servicesSection = ConfigurationManager.GetSection("system.serviceModel/services") as ServicesSection; foreach (ServiceElement service in servicesSection.Services) { Type serviceType = Type.GetType(service.Name); ServiceHost SvcHost = new ServiceHost(serviceType); string strLog = string.Empty; SvcHost.Opened += delegate { Console.WriteLine(string.Format("服務[{0}]已經啟動,公開服務地址有:", service.Name)); }; SvcHost.Open(); foreach (var endpoint in SvcHost.Description.Endpoints) { Console.WriteLine(string.Format("Endpoint:{0} ", endpoint.Address.ToString())); } //logger.Info(strLog); _LsSvcHost.Add(SvcHost); } } catch (System.Exception ex) { Console.WriteLine("啟動數據服務異常:", ex); } }

然后把方法放到main()函數里調用即可:

static void Main(string[] args)
        {
            StartSvc();
            Console.ReadKey();
            foreach (ServiceHost SvcHosts in _LsSvcHost) SvcHosts.Close();
        }

啟動服務就可以看到服務已啟動:

由於配置文件里配置了兩個服務,這里也就啟動了兩個服務(注意:配置服務之后一定要添加對應的接口和接口實現類)。

4.新建項目WCFTestClient(客戶端項目,用來測試訪問服務)

新建項目這個也簡單,也不多說,只把我的的界面貼出來(由於是測試,界面不好看,大家見諒····)

5.寫客戶端代碼

這個主要就是寫按鈕“獲取返回值”的Click事件,先貼代碼,在講解:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        /// <summary>
        /// 根據提供的服務地址和傳遞的參數值,獲取返回的值
        /// </summary>
        /// <param name="strUri">服務地址</param>
        /// <param name="strBody">傳遞參數值</param>
        /// <returns></returns>
        public string PostHttp(string strUri, string strBody)
        {
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(strUri);

            if (!string.IsNullOrEmpty(string.Empty) && !string.IsNullOrEmpty(string.Empty))
            {
                myRequest.Credentials = GetCredentialCache(strUri, string.Empty, string.Empty);
                myRequest.Headers.Add("Authorization", GetAuthorization(string.Empty, string.Empty));
            }

            //轉成網絡流
            byte[] buf = UnicodeEncoding.UTF8.GetBytes(strBody);
            //設置
            myRequest.Method = "POST";
            myRequest.ContentLength = buf.Length;
            myRequest.ContentType = "application/x-www-form-urlencoded";
            myRequest.KeepAlive = false;
            myRequest.ProtocolVersion = HttpVersion.Version10;
            //發送請求
            Stream newStream = myRequest.GetRequestStream();
            newStream.Write(buf, 0, buf.Length);
            newStream.Close();
            //獲得接口返回值
            HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
            StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
            string strReturn = HttpUtility.HtmlDecode(reader.ReadToEnd());
            reader.Close();
            myResponse.Close();
            string p = @"\\/Date\((\d+)\+\d+\)\\/";
            MatchEvaluator evaluator = new MatchEvaluator(ConvertJsonDateToDateString);

            //對時間進行處理,需要引用System.Text.RegularExpressions;命名空間
            Regex reg = new Regex(p);
            strReturn = reg.Replace(strReturn, evaluator);
            return strReturn;
        }

        private  CredentialCache GetCredentialCache(string uri, string username, string password)
        {
            string authorization = string.Format("{0}:{1}", username, password);

            CredentialCache credCache = new CredentialCache();
            credCache.Add(new Uri(uri), "Basic", new NetworkCredential(username, password));

            return credCache;
        }

        private  string GetAuthorization(string username, string password)
        {
            string authorization = string.Format("{0}:{1}", username, password);

            return "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(authorization));
        }

        private  string ConvertJsonDateToDateString(Match m)  //對時間進行序列化處理
        {
            string result = string.Empty;
            DateTime dt = new DateTime(1970, 1, 1);
            dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
            dt = dt.ToLocalTime();
            result = dt.ToString("yyyy-MM-dd HH:mm:ss");
            return result;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string strUri = "http://localhost:8888/Service/DbApiInfo/CreateApi";
            string getstr=PostHttp(strUri, "劉德華");
            textBox1.Text = getstr;
        }
    }
View Code

 

這里主要就是一個方法PostHttp,這個方法是通用,可作為公用方法被調用。

Click事件里調用方法。

6.執行訪問服務

這個我們只需要把服務運行,在運行客戶端,點擊按鈕,就可以得到服務給我們返回的結果了

至此,一個簡單的WCF服務的建立以及調用就完成了······


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM