上一篇博文具體的介紹了怎麼在 JavaScript 中調用 WCF 服務,
但是其中具體的一些細節卻並沒有多做解釋,
所以在這一篇博文中將會對這些細節做一些比較詳細的解釋,
同時會示範一個和上一篇博文中的 Demo 不同的例子,
這個 Demo 是採用將介面公開給 JavaScript ,
然後再讓一個類實現這個介面,
從而這個類就會實現介面中的公開給 JavaScript 的方法,
這樣這個類中的這個方法也就間接的公開給了 JavaScript 。
講了這麼多的把一個類中的方法公開給 JavaScript ,
以保證 JavaScript 可以訪問 WCF 服務中的方法,
那麼如何將一個方法公開給 JavaScript 呢?
首先,您必須將要公開給 JavaScript 的方法所在的類或者介面,
應用 ServiceContractAttribute ,
然後,您必須將要公開給 JavaScript 的方法
應用 OperationContractAttribute,
其實,除了上面這些以外,要保證使 JavaScript 可以訪問 WCF 服務,
還必須在 web.config 中進行一些必要的配置,
當然您可以在建立一個 “啟用了 AJAX 的WCF 服務”WCF 服務
來自動完成 web.config 中的配置,雖然可以這樣做,
但是我們還是看一下其到底在 web.config 中做了什麼樣的配置,
當我使用 “啟用了 AJAX 的 WCF 服務”來
建立一個 WCF 服務 WCFDemo22Use.svc 時,
會在 web.config 中添加如下的一些設定(請注意注釋和標記部分),
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<!--啟用 WebScript 來保證可以在用戶端使用指令碼 JavaScript 來進行訪問-->
<behavior name="深入淺出_ASP.NET_AJAX.WCFDemo22UseAspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="深入淺出_ASP.NET_AJAX.WCFDemo22Use">
<!--注意這裡的 contract 屬性是一個介面的名稱,而不是一個類名
這是因為這個介面中標記了 ServiceContranctAttribute
並且在介面的方法中標記了 OperationContractAttribute
所以在這裡使用的契約是介面名 IWCFSample 而不是 類名 WCFDemo22Use
而在上一篇博文的 Demo 中是直接使用類來添加 ServiceContractAttribute
所以上一篇博文對應得在 web.config 中的
contract="深入淺出_ASP.NET_AJAX.WCFDemo21Use"-->
<endpoint address=""
behaviorConfiguration="深入淺出_ASP.NET_AJAX.WCFDemo22UseAspNetAjaxBehavior"
binding="webHttpBinding" contract="深入淺出_ASP.NET_AJAX.IWCFSample" />
</service>
</services>
</system.serviceModel>
通過上面建立的 WCFDemo22Use.svc WCF服務,
我完成了下面的 Demo,
因為是為了明白其中的一些內容,所以代碼部分相當簡單,
.svc.cs
using System;
using System.ServiceModel.Activation;
namespace 深入淺出_ASP.NET_AJAX
{
[System.ServiceModel.ServiceContract(Namespace = "BaoBeiMe",
Name = "WCFDemo22Use")]
public interface IWCFSample
{
[System.ServiceModel.OperationContract]
string GetDate();
}
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class WCFDemo22Use : IWCFSample
{
//實現 IWCFSample 介面中的方法
//由於介面已經標記了 [System.ServiceModel.ServiceContract]
//並且在介面中的方法又標記了 [System.ServiceModel.OperationContract]
//而這個類 WCFDemo22Use 又實現了這個介面
//所以在這個類中實現介面中的方法的話
//可以不需要再標記上述的 Attribute 了
//因為在介面中這個方法已經對 JavaScript 公開了
public string GetDate()
{
return DateTime.Now.ToString();
}
}
}
.aspx
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="Demo__22.aspx.cs"
Inherits="深入淺出_ASP.NET_AJAX.Demo__22" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/WCFDemo22Use.svc" />
</Services>
</asp:ScriptManager>
<script language="javascript" type="text/javascript">
function btnOne_onclick() {
var wcfProxy = new BaoBeiMe.WCFDemo22Use();
wcfProxy.GetDate(OnSucceededCallback, OnFailedCallback);
}
function OnSucceededCallback(result) {
alert(result);
}
function OnFailedCallback(error) {
alert(error.get_message());
}
</script>
<div>
<input id="btnOne" type="button" value="調用 WCF 服務"
onclick="return btnOne_onclick()" />
</div>
</form>
</body>
</html>
再看一下
然後就是要稍微解析一下上面 .svc 中的代碼了,
由於我的 ServiceContractAttribute 屬性是應用在介面 IWCFSample 上,
所以,在用戶端,我 BaoBeiMe.WCFDemo22Use
是在此處
定義的 Namespace 和 Name,
上面的 Demo 是使用一個介面裡實現 ServiceContractAttribute ,
而如果是在一個類之上直接使用 ServiceContractAttribute ,
那麼如果不定義 Namespace 和 Name ,
在用戶端則是直接使用類名來初始化一個 JavaScript Proxy 代理類,
比如上一篇博文的 Demo ,如果不設定 Namespace 和 Name 的話,
則在用戶端可以直接寫
但是這一個 Demo 卻必須要設定 Namespace 和 Name,
因為要在這個 .svc 中唯一的定義要在用戶端組建代理程式類的命名空間和名稱,
如果不設定 Namespace 和 Name 的話,
那麼程式將無法得知當前是哪一個命名空間下方法公開給了 JavaScript。
以上很多地方都是需要注意的,
如果您的應用程式執行時會失敗的話,那麼應該就是下面三處有問題
第一,web.config 中的 contract 是否設定正確
第二,ServiceContractAttribute 是否應用正確
第三,OperationContractAttribute 是否應用正確
2010—2—03