使用 ASP.NET AJAX 在 JavaScript 中使用 WCF 服务的入门指南






4.61/5 (69投票s)
演示了如何在 JavaScript 中使用 WCF。
目录
开发平台
- Visual Studio 2008 SP1
- .NET Framework 3.5 SP1
- ASP.NET AJAX
- IIS 7 或 VS 集成 Web 服务器 [已配置 WCF 和 SVS 文件]
- Windows Vista
引言
WCF (Windows Communication Foundation) 为 Microsoft 应用程序开发平台增加了许多新功能,尤其是在应用程序如何相互通信方面。在本文中,我们将介绍如何直接从客户端 JavaScript 代码使用 WCF。这是 ASP.NET AJAX 提供的一个非常酷的功能。在本文中,我们不会介绍 WCF 内部的各种理论,而是只关注如何直接从 JavaScript 使用服务。因此,不会涉及 ASP.NET 或 .NET 运行时如何管理此功能的幕后信息。
为了演示这些想法和事实,我们将创建一个包含两个项目的演示解决方案。因此,废话不多说,创建一个空白解决方案并保存。现在,向解决方案添加一个类库项目。将类库命名为 _ServiceLibrary_。然后,向解决方案添加一个 Web 应用程序项目,并命名为 _WEBUI_。我们将看到两种方法来添加一个可从 JavaScript 使用的 WCF 服务。
- 使用 Ajax-Enable WCF 服务项模板
- 使用类库中定义的 خدمة 接口
使用 AJAX 启用的 WCF 服务项模板
在这里,我们将看到一种非常直接的方法来在 JavaScript 中使用 WCF 服务。右键单击 Web 应用程序项目,然后选择“添加新项”。选择 _AJAX-Enabled WCF Service Item Template_,并将其命名为 “_HelloWorldService.svc_”,然后单击“确定”。向导将如预期一样向解决方案添加一个 _HelloWorldService.svc_ 文件。该文件还将有一个代码隐藏文件。如果使用 XML 文件编辑器打开 _HelloWorldService.svc_,您将看到类似如下的标记
<%@ ServiceHost Language="C#" Debug="true"
Service="WebUI.HelloWorldService" CodeBehind="HelloWorldService.svc.cs" %>
如果打开代码隐藏文件,您将看到类似如下的代码
namespace WebUI
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class HelloWorldService
{
[OperationContract]
public void DoWork()
{
return;
}
}
}
Visual Studio 2008 会自动为您在 _web.config_ 文件中添加必要的配置,因此无需在 _web.config_ 中进行任何配置。现在,继续添加一个返回字符串“HelloWorld”的 `HelloWorld()` 方法,并为该方法添加 `[OperationContract]` 属性。我们将在本文后面解释这些属性的含义。现在,向 Web 应用程序项目添加一个页面,并将其命名为“_HelloWorldTest.aspx_”。从 Visual Studio 工具箱中拖放一个 Script Manager 控件。在 `ScriptManager` 标记内,添加对该服务的服务引用。示例如下
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/HelloWorldService.svc" />
</Services>
</asp:ScriptManager>
现在,向页面添加一个按钮和一个文本框,并在按钮单击事件中,使用 JavaScript 函数调用服务。当您编写服务调用函数时,Visual Studio 2008 的 HTML 编辑器将提供智能感知功能来编写必要的函数调用。完整的 HTML 代码如下
<form id="form1" runat="server">
<div>
<script language="javascript" type="text/javascript">
function GetValueFromServer() {
HelloWorldService.HelloWorld(onSuccess, onFailure);
}
function onSuccess(result) {
document.getElementById('txtValueContainer').value = result;
}
function onFailure(result) {
window.alert(result);
}
</script>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/HelloWorldService.svc" />
</Services>
</asp:ScriptManager>
<input id="btnServiceCaller" type="button" value="Get Value"
onclick="GetValueFromServer()"; />
<input id="txtValueContainer" type="text" value="" />
</div>
</form>
请注意,在调用服务时,我们传递了两个方法:一个用于回调,另一个用于错误回调。如果我们向函数传递任何参数,参数将首先传递,然后是回调。因此,如果我们有一个名为 `getvalue` 的函数,该函数接受两个字符串参数,我们将像这样调用函数:_[NameSpaceName].[ServiceName].getvalue(“value one”,”value two”,on_success,on_error);_,其中 `on_success` 和 `on_error` 分别是成功回调和错误回调。
使用类库中定义的 خدمة 接口
因此,我们已经了解了如何使用项模板来使用 AJAX 启用的 WCF 服务。现在,我们将看到一种更传统的 WCF 服务实现,并且还将学习如何公开此服务以供 ASP.NET AJAX 使用。当我们创建类库项目时,默认情况下,它没有添加服务模型和运行 WCF 所需的运行时序列化支持。因此,我们必须添加必要的服务引用。继续右键单击类库项目,选择“添加引用”,然后选择这些引用
System.Runtime.Serialization
System.ServiceModel
在这一阶段,我们将使用一个 TODO 管理示例来演示整个思路。添加一个基于服务的数据库,然后创建一个包含 `ID`、`Description` 和 `Status` 字段的 _TODO_ 表。现在,从项模板中添加一个 LINQ to SQL 类文件。将 _TODO_ 表从数据库拖放到 LINQ to SQL 类文件设计器中。现在,单击设计器表面,然后在属性窗口中,将序列化模式更改为“单向”。现在,我们设计器生成的 LINQ to SQL 类已准备好供 WCF 使用。如果您想使用自定义用户定义类型,必须将 `[DataContract]` 类属性设置为您的类,并且必须将 `[DataMember]` 属性添加到您想暴露给 WCF 的类的每个属性。
现在,我们将添加一个类似这样的服务接口
namespace ServiceLibrary
{
[ServiceContract(Namespace = "ServiceLibrary")]
interface IToDoService
{
[OperationContract]
ToDo GetToDo(long ID);
[OperationContract]
ToDo AddToDo(ToDo toDo);
[OperationContract]
bool DeleteToDo(ToDo todo);
[OperationContract]
ToDo UpdateToDo(ToDo todo);
[OperationContract]
List<ToDo> GetAllToDo();
}
}
请注意,我们在 `ServiceContract` 接口属性中提到了一个命名空间。这一点非常重要。我们将在 JavaScript 代码中使用此名称作为服务名称来访问服务。现在,我们将为该服务接口添加实现;代码如下。请注意,在代码中,我使用了 `[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]` 类属性;这是将服务公开为启用 ASP.NET AJAX 的 WCF 服务的一个强制要求。
namespace ServiceLibrary
{
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class ToDoService : IToDoService
{
#region IToDoService Members
public ToDo GetToDo(long ID)
{
DataClasses1DataContext context = new DataClasses1DataContext();
var toDos = from p in context.ToDos
where p.ID == ID
select p;
List<ToDo> listTodos = toDos.ToList();
if (listTodos != null && listTodos.Count > 0)
{
return listTodos[0];
}
else
{
return null;
}
}
#endregion
}
}
配置 Web 应用程序以使用 TODO 服务
既然我们已经定义了运行 TODO 应用程序所需的所有内容,现在是时候将服务公开为客户端的 ASP.NET AJAX 启用的 WCF 服务了。为此,我们将添加一个 AJAX 启用的 WCF 服务 _ .svc_ 文件。然后,我们将删除代码隐藏文件。或者,我们可以添加一个 XML 文件或文本文件,然后将其重命名为 _ToDoService.svc_。使用 XML 编辑器打开它,并添加如下所示的指令
<%@ ServiceHost Language="C#" Debug="true" Service="ServiceLibrary.ToDoService" %>
现在,我们将把必要的配置放在 _web.config_ 中以运行此服务。代码如下
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="AspNetAjaxBehavior">
<enableWebScript />
</behavior>
<behavior name="WebUI.HelloWorldServiceAspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="ServiceLibrary.ToDoService">
<endpoint behaviorConfiguration="AspNetAjaxBehavior" binding="webHttpBinding"
contract="ServiceLibrary.IToDoService" />
</service>
<service name="WebUI.HelloWorldService">
<endpoint address="" behaviorConfiguration="WebUI.HelloWorldServiceAspNetAjaxBehavior"
binding="webHttpBinding" contract="WebUI.HelloWorldService" />
</service>
</services>
</system.serviceModel>
现在,右键单击文件并选择“在浏览器中查看”,以查看服务是否正常运行。在进入下一阶段之前,有几点需要说明。您必须添加 `serviceHostingEnvironment` 并设置 `aspNetCompatibilityEnabled="true"
`,才能在 ASP.NET 中使用 WCF 服务及其功能,如 HTTP Context、Session 等。
在 JavaScript 中使用服务
现在,像我们之前使用的 HelloWorldService 一样使用服务。下面我提供了一个示例代码以使事情更清楚。还显示了 `ScriptManager` 标记。请注意,我们添加了一个 _clientServiceHelper.js_ 文件。我们将所有客户端到 WCF 的通信 JavaScript 函数都放在该文件中。
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/Script/ClientServiceHeler.js" />
</Scripts>
<Services>
<asp:ServiceReference Path="~/ToDoService.svc" />
</Services>
</asp:ScriptManager>
我们使用了 ASP.NET AJAX 客户端对象模型来编写 JavaScript 客户端代码,这是 _clientServiceHelper.js_ 的一部分。
Type.registerNamespace("ServiceClients");
ServiceClients.ToDoClient = function() {
}
ServiceClients.ToDoClient.prototype = {
AddToDo: function(todo, callback, errorCallBack) {
ServiceLibrary.IToDoService.AddToDo(todo, callback, errorCallBack);
},
DeleteToDo: function(todo, callback, errorCallBack) {
ServiceLibrary.IToDoService.DeleteToDo(todo, callback, errorCallBack);
},
UpdateToDo: function(todo, callback, errorCallBack) {
ServiceLibrary.IToDoService.UpdateToDo(todo, callback, errorCallBack);
},
GetAllToDo: function(callback, errorCallBack) {
ServiceLibrary.IToDoService.GetAllToDo(callback, errorCallBack);
},
dispose: function() {
}
}
ServiceClients.ToDoClient.registerClass('ServiceClients.ToDoClient', null, Sys.IDisposable)
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
摘要
在本文中,我们已经了解了如何使用 AJAX 启用的 WCF 服务项模板。然后,我们学习了如何使用基于服务接口的 WCF 服务。我们还学习了如何配置 _web.config_ 来使用服务。最后,我们学习了如何在 `ScriptManager` 中添加服务引用。在结束本文之前,有几点需要说明。我们也可以在 C# 代码中添加服务引用。下面是一个简单的代码示例:
ScriptManager manager = ScriptManager.GetCurrent(Page);
ServiceReference reference = new ServiceReference("ToDoService.svc");
manager.Services.Add(reference);
如果初学者遇到问题或不理解文章的任何部分,请给我留言。您可以在 这里 学习 WCF 的基础知识。如果您在 IIS 中配置 WCF 时遇到任何困难,请参阅 此处 的文章。
参考文献
- http://msdn.microsoft.com/en-us/library/aa480190.aspx [WCF - 基础]
- http://munna.shatkotha.com/Blog/post/2008/07/08/Install-WCF-Aspnet-in-IIS7.aspx [配置 WCF]
- http://msdn.microsoft.com/en-us/library/bb514961.aspx [将 WCF 公开给客户端脚本]
- http://msdn.microsoft.com/en-us/library/bb763177.aspx [在 ASP.NET 环境中配置 WCF]
- http://msdn.microsoft.com/en-us/library/bb398785.aspx [ASP.NET 中的 Web 服务]
- http://peterkellner.net/2008/09/14/wcf-web-service-json-vs2008/ [讨论相同概念的文章]