天天看點

一起談.NET技術,使用WCF實作SOA面向服務程式設計——使用AJAX+WCF服務頁面開發

  在上一篇講到,如果将BLL層的每一個類都轉化為*.svc,這是一個不實在的想法。它會使服務變化複雜,難于管理。

  這時候,我們第一時間想到的是23個簡單開發模式中的Factory,在這裡,Factory正好派上用場。我們把這個Factory稱之為管道(pipeline) ,通過這個管道用戶端可以随意調用伺服器BLL層裡面的類。

一起談.NET技術,使用WCF實作SOA面向服務程式設計——使用AJAX+WCF服務頁面開發

  (關于管道的概念,建議參考Cory Isaacson的傑作《多核應用架構關鍵技術—軟體管道與soa》)

  當你使用B/S方式開發UI層時,隻要了解此開發模式,使用Ajax加上WCF裡面的WebHttpBinding綁定和WebHttpBehavior行為,可以說是天衣無縫的組合。

  首先,開發一個資料契約,其中包括程式集名稱,類名,構造函數的參數,方法名,方法中的參數:

[DataContract]

public class Communication

{

[DataMember]

public string Assembly

get;

set;

}

public string Class

public object[] ConstructedParameters

public string Method

public object[] Parameters

  為了證明用戶端可以通過Ajax能夠直接調用伺服器WCF,我們先開發一個MyAssembly程式集:

namespace MyAssembly

public class User

public int ID

{ get; set; }

public string Name

public int Age

public class UserManager

public List<User> GetList()

List<User> entities = new List<User>();

User user = new User();

user.ID = 0;

user.Age = 26;

user.Name = "Leslie";

entities.Add(user);

return entities;

  好,現在已經做好準備,現在我們建立一個“啟動了AJAX的WCF服務”:

一起談.NET技術,使用WCF實作SOA面向服務程式設計——使用AJAX+WCF服務頁面開發

[ServiceContract(Namespace = "myNamespace")]

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

//注意必須将RequirementsMode設定為AspNetCompatibilityRequirementsMode.Allowed

public class Service

private static Hashtable assemblies = new Hashtable();

private static Hashtable types = new Hashtable();

[OperationContract]

[WebGet]

// 要使用 HTTP GET,請添加 [WebGet] 特性。

public string DoWork(Communication communication)

Type classType = GetType(communication); //通過自定義的GetType(Communicate o)方法加載類

if (classType != null) //下面将利用反射原理建立類對象

object reflectedObject;

if (communication.ConstructedParameters != null)

reflectedObject = Activator.CreateInstance(classType, communication.ConstructedParameters);

else

reflectedObject = Activator.CreateInstance(classType);

MethodInfo methodInfo = classType.GetMethod(communication.Method); //擷取方法資訊

if (methodInfo != null)

object data = methodInfo.Invoke(reflectedObject, communication.Parameters); //調用方法

if (data != null)

return Formate(data, methodInfo.ReturnType); //将結果轉化為JSON

return null;

//因為結果供于Ajax頁面使用,是以将結果轉化為Json形式

//其實當項目已經啟動AJAX,在預設情況下結果會自動轉化為JSON,但因為不能事先預知傳回的類型,是以把傳回類型定為String

//此處手動将結果轉換成JSON字元串

public string Formate(object data,Type type)

using (Stream stream = new MemoryStream())

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(type);

jsonSerializer.WriteObject(stream, data);

byte[] byteData = new byte[stream.Length];

stream.Seek(0,0);

stream.Read(byteData, 0, (int)stream.Length);

stream.Close();

return Encoding.UTF8.GetString(byteData);

//加載程式集 

private Assembly GetAssembly(Communication communication)

if (!assemblies.ContainsKey(communication.Assembly))

Assembly myAssembly = Assembly.Load(communication.Assembly);

assemblies.Add(communication.Assembly, myAssembly);

return (Assembly)assemblies[communication.Assembly];

//加載類

private Type GetType(Communication communication)

if (!types.ContainsKey(communication.Class))

Assembly assembly=GetAssembly(communication);

types.Add(communication.Class, assembly.GetType(communication.Class));

return (Type)types[communication.Class];

  伺服器端會自動為你配置.config檔案:

<system.serviceModel>

  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

  <behaviors>

    <endpointBehaviors>

    <behavior name="ServiceAspNetAjaxBehavior">

    <enableWebScript /> //注意啟動enableWebScript

  </behavior>

  </endpointBehaviors>

  <serviceBehaviors>

    <behavior name="ServiceBehavior">

      <serviceMetadata httpGetEnabled="true" /> //注意此處啟動了httpGetEnabled

      <serviceDebug includeExceptionDetailInFaults="false" />

    </behavior>

  </serviceBehaviors>

</behaviors>

  <services>

  <service name="Service" behaviorConfiguration="ServiceBehavior">

    <endpoint address="" behaviorConfiguration="ServiceAspNetAjaxBehavior"

binding="webHttpBinding " contract="Service" /> //注意綁定的是webHttpBinding

    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

  </service>

  </services>

  </system.serviceModel>

</configuration>

  好吧,現在萬事俱備的時候,讓我們開發一個測試頁面:

<body>

<form id="form1" runat="server">

<script type="text/javascript">

window.onload = function () {

myNamespace.Service.set_path("http://localhost:8080/Service.svc/");

var communication = { "Assembly": "MyAssembly", "Class": "MyAssembly.UserManager",

        "ConstructedParameters": null, "Method": "GetList", "Parameters": null };

//把Communication參數轉化為Json形式

myNamespace.Service.DoWork(communication, OnSucceed, OnFail, null);

function OnSucceed(result) {

if (result != null)

alert(result);

function OnFail(result) {

</script>

</form>

</body>

  測試成功:

一起談.NET技術,使用WCF實作SOA面向服務程式設計——使用AJAX+WCF服務頁面開發

  恭喜你終于學會如何使用Ajax+WCF進行頁面資料顯示了。

  你應該初步了解到如何使用管道Pipeline進行用戶端與伺服器端的通訊,自此之後,每逢你進行簡單的頁面開發時都可使用此方式。好處在于頁面無

需了解資料是從何處擷取的,因為資料存取和頁面可以處于不同的線程池,是以這樣做可以把伺服器壓力降到最低。同時你可以使用異步的服務,來進一步提高資料

<a href="http://blog.csdn.net/Leslies2/archive/2011/01/24/6161126.aspx" target="_blank"></a>