天天看點

WCF應用 - 簡單的Rest服務

1. 什麼是REST?

  Rest的全稱是Representational State Transfer, 普通的WCF使用SOAP,而使用REST建構的WCF服務

使用其他資料傳輸方式,例如JSON

Rest的四種操作:

GET - Requests a specific representation of a resource

PUT - Creates or updates a resource with the supplied representation

DELETE - Deletes the specified resource

POST - Submits data to be processed by the identified resource

WCF應用 - 簡單的Rest服務

2. 什麼情況下使用REST?

Less overhead (no SOAP envelope to wrap every call in)

Less duplication (HTTP already represents operations like <code>DELETE</code>, <code>PUT</code>, <code>GET</code>, etc. that have to otherwise be represented in a SOAP envelope).

More standardized - HTTP operations are well understood and operate consistently. Some SOAP implementations can get finicky.

More human readable and testable (harder to test SOAP with just a browser).

Don't need to use XML (well, you kind of don't have to for SOAP either but it hardly makes sense since you're already doing parsing of the envelope).

Libraries have made SOAP (kind of) easy. But you are abstracting away a lot of redundancy underneath as I have noted. Yes, in theory, SOAP can go over other transports so as to avoid riding atop a layer doing similar things, but in reality just about all SOAP work you'll ever do is over HTTP.

3. 簡單的例子

  1) 首先,制作服務契約的接口

  IHelloService

using System.ServiceModel;

using System.ServiceModel.Web;

namespace Perseus.WCF.REST.Contract.Service

{

    [ServiceContract]

    public interface IHelloService

    {

        [OperationContract]

        [WebInvoke(Method = "GET",

            ResponseFormat = WebMessageFormat.Xml,

            BodyStyle = WebMessageBodyStyle.Wrapped,

            UriTemplate = "xml/{name}/{age}")]

        string HelloXml(string name, string age);

            ResponseFormat = WebMessageFormat.Json,

            UriTemplate = "json/{name}/{age}")]

        string HelloJson(string name, string age);

    }

}

  2) 然後, 建立一個WCF服務項目,在項目中添加WCF服務檔案svc

HelloService.svc

using Perseus.WCF.REST.Contract.Service;

namespace Perseus.WCF.REST.Service

    public class HelloService : IHelloService

        public string HelloXml(string name, string age)

        {

            return "Hello " + name + " "

                   + "Your Age: " + age;

        }

        public string HelloJson(string name, string age)

  3) 配置檔案

&lt;?xml version="1.0"?&gt;

&lt;configuration&gt;

  &lt;connectionStrings&gt;

    &lt;add name="NorthwindConnectionString" connectionString="Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True" providerName="System.Data.SqlClient"/&gt;

  &lt;/connectionStrings&gt;

  &lt;system.web&gt;

    &lt;compilation debug="true" targetFramework="4.0" /&gt;

  &lt;/system.web&gt;

  &lt;system.serviceModel&gt;

    &lt;services&gt;

      &lt;service name="Perseus.WCF.REST.Service.HelloService" behaviorConfiguration="ServiceBehaviour"&gt;

        &lt;!-- Service Endpoints --&gt;

        &lt;!-- Unless fully qualified, address is relative to base address supplied above --&gt;

        &lt;endpoint address=""  binding="webHttpBinding" contract="Perseus.WCF.REST.Contract.Service.IHelloService" behaviorConfiguration="web"&gt;

          &lt;!-- 

              Upon deployment, the following identity element should be removed or replaced to reflect the 

              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 

              automatically.

          --&gt;

        &lt;/endpoint&gt;

      &lt;/service&gt;

      &lt;/services&gt;

    &lt;behaviors&gt;

      &lt;endpointBehaviors&gt;

        &lt;behavior name="web"&gt;

          &lt;webHttp /&gt;

        &lt;/behavior&gt;

      &lt;/endpointBehaviors&gt;

      &lt;serviceBehaviors&gt;

        &lt;behavior name="ServiceBehaviour"&gt;

          &lt;serviceMetadata httpGetEnabled="true" /&gt;

          &lt;serviceDebug includeExceptionDetailInFaults="false" /&gt;

        &lt;behavior name=""&gt;

      &lt;/serviceBehaviors&gt;

    &lt;/behaviors&gt;

    &lt;serviceHostingEnvironment multipleSiteBindingsEnabled="true" /&gt;

  &lt;/system.serviceModel&gt;

  &lt;system.webServer&gt;

    &lt;modules runAllManagedModulesForAllRequests="true"/&gt;

  &lt;/system.webServer&gt;

&lt;/configuration&gt;

   4) 位址欄調試

<a href="http://localhost:7695/HelloService.svc/xml/david/30">http://localhost:7695/HelloService.svc/xml/david/30</a>

傳回結果:

 &lt;HelloXmlResponse xmlns="http://tempuri.org/"&gt;

  &lt;HelloXmlResult&gt;Hello david Your Age: 30&lt;/HelloXmlResult&gt; 

  &lt;/HelloXmlResponse&gt;

<a href="http://localhost:7695/HelloService.svc/json/david/30">http://localhost:7695/HelloService.svc/json/david/30</a>

{"HelloJsonResult":"Hello david Your Age: 30"}

   5) 編寫用戶端調用代碼

HelloRestTest

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Perseus.WCF.Client

    class HelloRestTest : ITestCase

        public void Run()

            Console.Write("Please Input Your Name: ");

            string name = Console.ReadLine();

            Console.Write("Please Input Your Age: ");

            string age = Console.ReadLine();

            string url = "http://localhost:7695/HelloService.svc";

            using (WebChannelFactory&lt;IHelloService&gt; wcf 

                = new WebChannelFactory&lt;IHelloService&gt;(new Uri(url)))

            {

                var channel = wcf.CreateChannel();

                IClientChannel clientchanel = channel as IClientChannel;

                string result = channel.HelloJson(name, age);

                Console.WriteLine(result);

            }

  運作結果:

Hello david Your Age: 30