开发平台:
1、Visual Studio 2008 SP1
2、.NET Framework 3.5 SP1
3、ASP.NET AJAX
4、IIS 7 或者 VS Integrated Web Server [WCF 和 SVS文件的配置]
5、Windows Vista
介绍:
WCF为微软的应用程序开发平台提供了大量的新增的功能。特别是在各个应用程序之间的交互。在这篇文章中,我们将看到能够在客户端的Javacript直接使用WCF服务。这个是ASP.NET AJAX提供的非常酷的功能。在这篇文章中,我们不会涵盖WCF内部的原理,我们仅仅关注如何在JavaScript中直接使用wcf服务。因此,没有asp.net或者.net运行时如何管理这些功能的幕后的东西。
为了演示这些观点和功能,我将创建一个带有两个工程的解决方案的例子。因此,为了不浪费时间,创建一个空解决方案然后保存。现在,在这个解决方案中添加一个类库工程。改名为ServiceLibrary。然后,向这个解决方案中再添加一个Web Application工程,改名为WEBUI 。我们将看到两种途径来添加让Javascript使用的WCF服务。
1、 使用Ajax-Enable WCF Service 项目模板
2、 将使用的服务接口定义在一个类库项目中
使用Ajax-Enable WCF Service 项目模板
这里,我们将看见一个非常直截了当的方式来实现在JavaScript中使用WCF服务。右击添加好的Web Application工程,选择添加一个新项。选择AJAX-Enabled WCF Service 项目模板,将其命名为“HelloWorldService.svc” ,点击OK。和预期一样向导添加一个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”的方法,然后为这个方法添加一个[OperationContract] 属性。从 Visual Studio工具箱上拖拽一个Script Manager控件,在ScriptManager 的标签内,添加一个<Services>来引用wcf服务.一个例子给出如下:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/HelloWorldService.svc" />
</Services>
</asp:ScriptManager>
现在,添加一个button和一个textbox到页面上,在button的点击事件中,使用JavaScript 函数来调用WCF服务.下面给出了全部的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_sucess 和on_error
分别是正常和错误的回调函数。
使用的类库项目来定义WCF服务接口
因此,我们看看如何使用通过一个项目来使用AJAX-enabled WCF 服务。现在,我们将看见一个更传统的WCF服务的实现,我们也将会看见如何公开这个WCF服务给ASP.NET AJAX。 当我们创建的默认类库项目,它是不会被添加WCF必要的的服务模型和运行时序列化的支持,因此,我们不得不添加必要的服务引用。回到前面,右击类库项目。选择添加引用。然后选择下面这些引用:
System.Runtime.Serialization
System.ServiceModel
在这个阶段, 我将使用一个TODO Management 的例子来说明这个观点。 添加一个服务的基础数据库,创建一个TODO 表,它有ID,
Description
, 和Status
字段。 现在,从项目模板中添加一个LINQ to SQL的类。 从数据库中拖拽TODO表到LINQ to SQL设计类中。 然后,点击属性框中的设计界面,将serialization模式改成Unidirectional.现在 我们设计产生出了准备为wcf使用的LINQ to SQL 类。如果你想要使用客户自定义的类型,你就必须为你的自定义的类型设置[DataContract] 属性,你必须为每个你想曝露给wcf的类的属性添加[DataMember]属性。
现在,我们添加一个如下的服务接口:
代码
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代码中访问wcf服务的名称。现在,我们将要去实现这个服务接口。代码给出如下所示。请注意,我们使用了
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
属性类;为了公开这个服务给ASP.NET AJAX ,这样做是必须的。代码
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 程序,现在是时候公开服务给一个能使用WCF的ASP.NET AJAX 程序的客户端。为此,我们将添加一个 AJAX-enabled 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中使用WCF服务
现在,像先前我们使用的HelloWorldService一样使用该服务,为了清楚起见,我们给出例子的代码。也给出了ScriptManager标签代码。请注意,我们已经添加的一个clientServiceHelper.js文件,我们把所有的客户端到服务端交互的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 客户端orm来实现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-enabled WCF Service 项目模版.然后,我们学习了如何使用定义基于wcf服务的服务接口。我们也学习到了如何配置wcf服务的web.config 。最后,我们学习了在一个ScriptManager中添加服务引用。在文章结束之前,一点必须说明,我们能通过C#代码添加服务引用。下面是一个例子的代码:
ScriptManager manager = ScriptManager.GetCurrent(Page);
ServiceReference reference = new ServiceReference("ToDoService.svc");
manager.Services.Add(reference);