65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.61/5 (69投票s)

2009年2月10日

CPOL

7分钟阅读

viewsIcon

242895

downloadIcon

4212

演示了如何在 JavaScript 中使用 WCF。

目录

开发平台

  1. Visual Studio 2008 SP1
  2. .NET Framework 3.5 SP1
  3. ASP.NET AJAX
  4. IIS 7 或 VS 集成 Web 服务器 [已配置 WCF 和 SVS 文件]
  5. Windows Vista

ClientAjaxTodoApp.jpg

引言

WCF (Windows Communication Foundation) 为 Microsoft 应用程序开发平台增加了许多新功能,尤其是在应用程序如何相互通信方面。在本文中,我们将介绍如何直接从客户端 JavaScript 代码使用 WCF。这是 ASP.NET AJAX 提供的一个非常酷的功能。在本文中,我们不会介绍 WCF 内部的各种理论,而是只关注如何直接从 JavaScript 使用服务。因此,不会涉及 ASP.NET 或 .NET 运行时如何管理此功能的幕后信息。

为了演示这些想法和事实,我们将创建一个包含两个项目的演示解决方案。因此,废话不多说,创建一个空白解决方案并保存。现在,向解决方案添加一个类库项目。将类库命名为 _ServiceLibrary_。然后,向解决方案添加一个 Web 应用程序项目,并命名为 _WEBUI_。我们将看到两种方法来添加一个可从 JavaScript 使用的 WCF 服务。

  1. 使用 Ajax-Enable WCF 服务项模板
  2. 使用类库中定义的 خدمة 接口

使用 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" %>

ChooseItemTemplate.jpg

如果打开代码隐藏文件,您将看到类似如下的代码

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

ProjectOfTodo.png

在这一阶段,我们将使用一个 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 时遇到任何困难,请参阅 此处 的文章。

参考文献

© . All rights reserved.