ASP.NET 3.5、AJAX 和 Web 服务






2.67/5 (5投票s)
本文介绍如何使用 AJAX 客户端脚本调用 Web Service 方法。
引言
本文介绍在 ASP.NET 3.5 AJAX 环境中使用 Web 服务,以及如何从客户端 JavaScript 调用 Web 服务方法。它还概述了新的 System.Web.Script
命名空间,并探讨了定义 Web 服务方法客户端调用的方法。
在 AJAX 中调用 Web Service 方法
为了改善 Web 用户体验,ASP.NET 的 AJAX 功能在其新版本中包含了从客户端 JavaScript 调用 Web 服务方法的新方法。AJAX 允许您在不提交或渲染整个页面的情况下,调用服务器端方法而无需回发。客户端脚本可以向 Web 方法发出请求,并将数据作为输入参数传递给方法;数据也可以从服务器发送回客户端浏览器。
为了使您的应用程序能够通过客户端脚本调用 ASP.NET Web 服务,服务器异步通信层会自动生成 JavaScript 代理类。为每个 Web 服务生成一个代理类,前提是在页面中的 <asp:ScriptManager>
控件下包含一个 <asp:ServiceReference>
元素。
<asp:ScriptManager runat="server" ID="scriptManagerId">
<Services>
<asp:ServiceReference Path="WebService.asmx" />
</Services>
</asp:ScriptManager>
此代理类在页面加载时下载到浏览器,并提供一个客户端对象,该对象代表 Web 服务公开的方法。要调用 Web 服务的方法,请调用生成的 JavaScript 代理类的相应方法。代理类进而与 Web 服务通信。请求通过浏览器的 XMLHTTP
对象异步发出。
<asp:ScriptReference>
元素用于注册将在网页中使用的 JavaScript 文件。只有在注册了 CallWebServiceMethod.js 文件后,才能在其上调用方法。
从脚本调用 Web 服务方法是异步的。要获取返回值或确定请求何时返回,您必须提供一个成功回调函数。当请求成功完成时,将调用回调函数,并且它包含 Web 方法调用的返回值(如果有)。您还可以提供一个失败回调函数来处理错误。此外,您可以传递用户上下文信息以供回调函数使用。
JSON – JavaScript Object Notation 是客户端-服务器请求之间数据转换使用的默认序列化格式。您可以禁用所有当前启用的协议,如 HTTP-GET、HTTP-POST,甚至早期 Web 服务形式中使用的 XML-SOAP 格式。Web.Config 文件中的以下设置将执行相同的操作。
<system.web>
<webServices>
<protocols>
<clear/>
</protocols>
</webServices>
</system.web>
下图详细展示了客户端和服务器端不同的层。对 Web 服务方法的请求会经过这些层。您可以看到如何调用一个可用代理对象上的方法,以及 Web 请求如何由客户端浏览器端的 XmlHttp
对象处理。在服务器端,您的请求像往常一样由 HTTP 处理程序处理,并发送进行 XML/JSON 序列化。
示例:在 AJAX 中使用 Web Service 方法
在 AJAX 中使用 Web Service 方法涉及两个步骤。第一步是创建和定义 Web 服务的方式略有不同。第二步是从页面使用客户端脚本调用服务方法。
步骤 1:创建 Web Service
在 System.Web.Scripts.Services
命名空间中,您可能会找到一个名为“ScriptSrvice
”的属性类,需要将其应用于 Web 服务类,以便客户端脚本可以调用 Web 服务方法。这将使代理生成脚本能够生成与 Web 服务类对应的代理对象。
同样,在相同的命名空间中,您可能会找到另一个名为“ScriptMethod
”的属性类,在将其应用于 Web 方法后,您可以指定用于调用方法的 HTTP 动词和响应格式。此属性有三个参数,如下所述:
UseHttpGet
:将其设置为true
将使用 HTTP GET 命令调用方法。默认值为false
。ResponseFormat
:指定响应是序列化为 JSON 还是 XML。默认值为 JSON。XmlSerializeString
:指定是否将所有返回类型(包括字符串类型)序列化为 XML。当响应序列化为 JSON 时,将忽略XmlSerializeString
属性的值。
好的…现在,使用 Visual Studio 2008 中的 ASP.NET Web 服务模板创建一个新的网站,并按如下方式修改 Web 服务类:
using System.Web.Script.Services;
namespace AjaxWebService
{
[WebService(Namespace = "https://:49232/AjaxWebService/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class Service : System.Web.Services.WebService
{
string myXmlData = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<Book>
<Title>Programming ASP.NET 3.5, AJAX and Web Services</Title>
</Book>";
// This method uses JSON response formatting
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
[WebMethod]
public string getNextBackupDate(int months)
{
return DateTime.Now.AddMonths(months).ToShortDateString();
} // This method uses XML response formatting
[ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
[WebMethod]
public string Greetings(string name)
public XmlDocument GetBookTitle()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(myXmlData);
return xmlDoc;
}
// This method uses HTTP-GET protocol to call it
[ScriptMethod(UseHttpGet = true)]
[WebMethod]
public string HelloWorld()
{
return "Hello, world";
}
}
}
注意:默认情况下,使用 ScriptService
启用的 Web 服务不会在浏览器中进行测试。您需要按如下方式修改 Web.Config 文件中的设置才能测试上述 Web 服务。
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
步骤 2:使用客户端脚本调用 Web Service 方法
ASP.NET Web 服务方法可以从客户端脚本异步调用,而无需回发且无需刷新整个页面。只有数据会在服务器和客户端浏览器之间传输。
目前,.NET framework 3.5 支持同一域(同一网站)中的 Web 服务和客户端网页。您不能使用 VS2008 Beta 2 调用位于 Internet 或任何其他系统上的 Web 服务方法。
现在,向现有 Web 服务项目添加一个新的“启用 AJAX 的网页”,并按如下标记中的指定,向网页添加控件:
编写 JavaScript 函数来调用 Web 服务方法和回调方法。通过使用代理类,并按顺序传递参数列表、成功回调函数的名称、失败回调函数的名称以及用户上下文,来调用 Web 服务方法。
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>AJAX Web Form</title>
<script type="text/javascript">
function CallNextDate()
{
AjaxWebService.Service.getNextBackupDate(1, OnSucceeded);
}
function CallHelloWorld()
{
AjaxWebService.Service.HelloWorld(OnSucceeded);
}
function CallBookTitle()
{
AjaxWebService.Service.GetBookTitle(OnSuccess, OnFail,
"XmlDocument");
}
// This is the callback function that processes
// the Web Service return value in JSON format.
function OnSucceeded(result)
{
var myresult = document.getElementById("Text1");
myresult.value = result;
}
// This is the callback function that processes
// the Web Service return value in XML format.
function OnSuccess(result)
{
var myresult = document.getElementById("Text1");
myresult.value = "Title: " + result.documentElement.text;
}
// This is the callback function that processes
// the Web Service return value in XML format.
function OnFail(error)
{
var myresult = document.getElementById("Text1");
myresult.value = "Service Error: " + error.get_message();
}
</script>
<style type="text/css">
#Text1
{
width: 375px;
}
#Button2
{
width: 140px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/Service.asmx"/>
</Services>
</asp:ScriptManager>
<br />
Result: <input id="Text1" type="text" /><br />
<br />
<input id="Button1" type="button"
value="Get Server Time" onclick="CallNextDate()" />
<input id="Button2" type="button"
value="Say Hello World" onclick="CallHelloWorld()" />
<input id="Button3" type="button"
value="Get Book Title" onclick="CallBookTitle()" />
<br />
<br />
<br />
</div>
</form>
</body>
</html>
在上面的标记中,请注意 ScriptManager
控件的 ServiceReference
元素中的 path
属性如何指向 Web 服务类。这使得 Web 服务方法可以从 default.aspx 页面的脚本中调用。内联函数 CallNextDate
、CallHelloWorld
和 CallBookTitle
用于调用三个 Web 服务方法。OnSuccess
和 OnFail
方法是回调方法,当 Web 服务方法执行完成后就会执行。
您的网页布局大致如下所示:
为了使客户端网页能够正常工作,您需要在 Web.Config 文件中添加以下设置:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions"
publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Extensions.Design"
publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
这将指示 ASP.NET 引擎加载当前版本的 System.Web.Extensions.dll 和其他 DLL,以利用 ASP.NET 3.5 中内置的 AJAX 支持。
结论
ASP.NET 3.5 及其内置的 AJAX 客户端-服务器框架增强了使用客户端脚本调用 Web 服务方法的功能。当您使用 Visual Studio 2008 时,大多数设置和 JavaScript 代码文件都会自动加载。在早期版本的 AJAX、ATLAS 中调用 Web 服务方法会遇到一些麻烦,使得开发和调试有些困难。现在,借助 ASP.NET 3.5,它已成为更简单、更熟悉的 VS2008 IDE 的固有组成部分。