WCF For Client Script
0 |
話說上回介紹了ASP.NET AJAX Client Templates,資料的來源需為Javascript物件陣列的形式,為了簡化起見,我是以Javascript [ { ... }, { ... } ]的方式Hard-Coding產生物件陣列。而在實務上,我們多半會另外撰寫一個Web Page、Web Service或WCF作為資料來源。
在微軟構築的藍圖中,WCF已內建Client Script支援功能,整合的緊密度讓人驚豔,算是建構AJAX後端的王道。更進一步,若資料來源更直接地映對到資料庫DataTable時,則ADO.NET Data Service還能提供更密切的整合,甚至還有前端的MicrosoftAjaxAdoNet.js提供一缸子的Javascript Function協助,寫起Code來更加得心應手。關於ADO.NET Data Service的部分留到之後再談,今天我們先將焦點集中在WCF上。
我們延續先前的範例,目標是要產生一個有Id, Name, Score, RecTime的人員資料陣列,但這回我們要用WCF來實作。
首先,用VS2008在ASP.NET專案中新增一個WCF Service,命名為PeopleSource.svc,VS2008會幫你產生PeopleSource.svc, App_Code\IPeopleSource.cs, App_Code\PeopleSource.cs。
接著,我們把它修改成我們要的樣子:
IPeopleSource.cs:
[ServiceContract(Namespace="Darkthread")]
public interface IPeopleSource
{
[OperationContract]
List<Person> GetPeople(bool hideScore);
}
[DataContract]
public class Person
{
[DataMember]
public string Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public double Score { get; set; }
[DataMember]
public DateTime RecTime { get; set; }
}
PeopleSource.cs: (記得要using System.ServiceModel.Activation)
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class PeopleSource : IPeopleSource
{
public List<Person> GetPeople(bool hideScore)
{
List<Person> people = new List<Person>();
people.Add(new Person { Id="A01", Name="Jeffrey",
Score=(hideScore) ? -1 : 32767, RecTime = DateTime.Now });
people.Add(new Person { Id="A02", Name="Fox Mulder",
Score=(hideScore)?-1:6242.25,
RecTime = DateTime.ParseExact("2008-11-05 12:00:50",
"yyyy-MM-dd HH:mm:ss", null) });
people.Add(new Person { Id="A03", Name="Dana Scully",
Score=(hideScore)?-1:8391.66, RecTime= new DateTime(2008, 6, 15) });
return people;
}
}
另外,web.config裡要做一些設定,好開啟內建WCF支援Client Script的功能,MSDN上有詳細的介紹,這裡只列出修改後的樣子:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="default"></binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webScriptEnablingBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="PeopleSourceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service behaviorConfiguration="PeopleSourceBehavior" name="PeopleSource">
<endpoint address="" binding="webHttpBinding"
contract="IPeopleSource"
bindingConfiguration="default"
behaviorConfiguration="webScriptEnablingBehavior">
</endpoint>
</service>
</services>
</system.serviceModel>
[Updated 2008-12-02] 以上的調整動作,在VS2008裡改建立AJAX-enabled WCF Service就可省略,請多利用。
接著,我們修改先前的ASPX,在ScriptManager中加入
<Services>
<asp:ServiceReference Path="~/PeopleSource.svc" />
</Services>
神奇的事發生了,打入Darkthread(在IPeopleSource.cs裡宣告的ServiceContract Namespace),VS2008自動提示可用的Interface、Method名稱、呼叫參數,酷斃了!
我們將上回的ASPX內容稍作修改,主要是加入ServiceReference及呼叫Darkthread.IPeopleSource.GetPeople。WCF自動產生的Javascript端函數,第二參數onSuccess要宣告一個Function接收WCF傳回的結果。函數只有一個呼叫參數data,即為WCF端所return的物件。由於GetPeople宣告的傳回物件是List<Person>,在Javascript端,會透過JSON自動轉成有物件陣列,而物件有哪些屬性,則以先前在IPeopleSource.cs裡Person有宣告[DataMemeber]的屬性為準,也就是Id, Name, Score, RecTime。
如此一來,data跟上回Hard-Coding建出的物件陣列完全相同,我們直接dv.set_data(data)即可完成Client Side Binding,輕鬆愉快。
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/js/jquery-1.2.6.js" />
<asp:ScriptReference Path="~/js/MicrosoftAjaxTemplates.debug.js" />
</Scripts>
<Services>
<asp:ServiceReference Path="~/PeopleSource.svc" />
</Services>
</asp:ScriptManager>
<script type="text/javascript">
$(function() {
var dv = $create(Sys.UI.DataView, {}, {}, {}, $get("tbTemplate"));
Darkthread.IPeopleSource.GetPeople(false, function(data) {
dv.set_data(data);
$("#tbTemplate").show();
});
});
</script>
<table border="1" cellspacing="0" cellpadding="0" style="font-size: 9pt; width: 300px;">
<thead>
<tr><th>Id</th><th>Name</th><th>Score</th><th>Record Time</th></tr>
</thead>
<tbody id="tbTemplate" style="display:none; padding: 3px;">
<tr>
<td style="text-align: center;">{{Id}}</td>
<td>{{Name}}</td>
<td style="text-align: right;">{{Score.format("N2")}}</td>
<td style="text-align: center;">
{{RecTime.format("yyyy/MM/dd HH:mm:ss")}}
</td>
</tr>
</tbody>
</table>
執行網頁,我們得到與上回一模一樣的結果,不同的是,資料來源已改由WCF提供。
WCF函數傳回的List<T>可以當場轉成立即可用的Javascript Object Array,直接做為ASP.NET AJAX Client Templates的資料來源,非常簡便(尤其是VS2008還提供Javascript呼叫WCF時的Intellisense,讓人感動)。
講到這裡,有沒有聯想到什麼?
Yes! LINQ查詢的結果不就可以轉成List<T>? 大家知道可以怎麼玩了吧!
Comments
Be the first to post a comment