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

使用 AJAX 和 SOAP 保持解决方案“干净”

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (7投票s)

2007 年 7 月 5 日

CPOL

4分钟阅读

viewsIcon

42706

downloadIcon

135

如何从 JavaScript 对象序列化和 Web 服务中获益,即使您对此一无所知。

引言

本文假定读者正在使用 ASP.NET AJAX 框架并且对其有基本了解。

明白了?使用“AJAX 和 SOAP”保持解决方案“干净”?总之,本文最初的标题是“使用 ASP.NET AJAX 的超级简单的 JSON”,但我当时对“JSON”一词的使用有些自由(尽管我看到的其他人使用“AJAX”一词的自由程度也不低)。本文的实际标题应该类似于“如何在不担心序列化或 Web 服务的情况下利用返回 JavaScript 对象的 Web 服务”。或者,也许它应该叫“超级简单的序列化”,以便利用头韵。甚至也许是“在 ASP.NET AJAX 中从客户端脚本调用 Web 服务”(尽管我认为那个已经被占用了)。当前标题的真正原因将在文章结尾揭晓。无论如何,这是我发现的利用 AJAX 的最简单方法,而不必考虑 Web 服务层,也不必担心序列化或反序列化我已在使用中的对象。

以下示例使用 JavaScript 调用其“宿主”页面上的一个方法,该方法将返回一个 person 对象并在弹出框中显示该人的信息。为简洁起见,该示例包含在一个 ASPX 页面中。

使用代码

首先,代码隐藏文件

using System;
using System.Web.UI;
using System.Web.Services;

namespace AJAXExample
{
    public partial class _Default : Page
    {
        public class Person
        {
            // Person

            public Person(string name, DateTime birthDate, Person[] friends)
            {
                this.name = name;
                this.birthDate = birthDate;
                this.friends = friends;
            }

            // Name

            private string name;
            public string Name
            {
                get { return name; }
            }

            // BirthDate

            private DateTime birthDate;
            public DateTime BirthDate
            {
                get { return birthDate; }
            }

            // Age

            public int Age
            {
                get { return DateTime.Now.Year - BirthDate.Year; }
            }

            // Friends

            private Person[] friends;
            public Person[] Friends
            {
                get { return friends; }
            }
        }

        // Page_Load

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        // GetPerson

        [WebMethod]
        public static Person GetPerson()
        {
            Person friend1 = new Person("friend one", DateTime.Now, null);
            Person friend2 = new Person("friend two", DateTime.Now, null);
            return new Person("person name", DateTime.Parse("7/4/1980"), 
                new Person[] { friend1, friend2 });
        }
    }
}

代码隐藏文件的说明

您首先会注意到 `Person` 类的定义。当然,这个类可以放在任何地方,最佳实践是将其放在自己的文件中。无论如何,需要注意的是,所有属性都是只读的,其中一个属性是一个集合,甚至还有一个计算字段。字段不必是只读的,但该类已被设计成这样,以表明任何类都可以被序列化为 JavaScript 对象。

页面上唯一的方法是 `GetPerson()` 方法,它在被调用时返回一个 person 的新实例。您会注意到该方法是 static(静态)、public(公共)的,并带有 WebMethod 属性。仅此而已,就能使该方法可供页面上的 JavaScript 访问。调用此方法将返回一个代理对象,该对象与前一段中描述的 `Person` 类高度相似。由于该对象作为 JavaScript 对象返回给调用者,因此属性将不再是只读的,计算字段将不再有后台逻辑,对象上的所有方法也将不再存在,但所有数据将以相同的结构(层次结构)保持不变,甚至包括集合属性。

现在,ASPX 页面

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="Default.aspx.cs" 
    Inherits="AJAXExample._Default" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>AJAX Example</title>
        <script type="text/javascript">

        // GetPerson

        function GetPerson() 
        {
            PageMethods.GetPerson(OnGetPersonSucceeded);
        }

        // OnGetPersonSucceeded

        function OnGetPersonSucceeded(result, userContext, methodName) 
        {
            alert("name: " + result.Name 
            + "\r\nbirthdate: " + result.BirthDate 
            + "\r\nage: " + result.Age + "\r\nfriends: " 
            + result.Friends.length);
        }
        
        </script>
    </head>
    <body>
        <form id="form" runat="server">
            <asp:ScriptManager 
                ID="scriptManager" 
                runat="server" 
                EnablePageMethods="true">
            </asp:ScriptManager>
            <input type="button" onclick="GetPerson();" value="get person" />
        </form>
    </body>
</html>

ASPX 页面的说明

首先要注意的是,页面上有一个且只有一个 ScriptManager,并且其 EnablePageMethods 属性设置为 true。将此属性设置为 true 才能让页面上的 JavaScript “看到”我们在代码隐藏文件中创建的静态方法。然后,ScriptManager 会创建一个 PageMethods 对象,该对象允许访问代码隐藏方法。页面上唯一的元素是一个 HTML 按钮,它调用 JavaScript 函数 GetPerson()。JavaScript 函数 GetPerson() 实际上只是一个传递函数,它使用 PageMethods 对象调用代码隐藏中的 GetPerson() 方法。PageMethod.GetPerson 接受几个参数,包括成功和失败的回调函数。此实现每次都假定成功,因此仅将 OnGetPersonSucceeded 函数作为第一个参数传递。来自代码隐藏中 GetPerson 方法(静态 Web 服务方法)的 Person 类被作为 JavaScript 对象返回给 OnGetPersonSucceeded。此方法的第一个参数 (result) 实际上是序列化的 Person 对象,其属性已用代码隐藏对象中的数据填充。

Screenshot - simpleAJAXExample.jpg

摘要

就是这样。不需要丰富的 JSON、序列化或 Web 服务经验,只需要一个 ScriptManager 且其 EnablePageMethods 属性设置为 true,以及一个带有 WebMethod 属性的公共静态方法。这是最好的部分,也是本文标题的真正原因,现在测试更容易了。JavaScript 可能很难编写和调试,而测试则更难。上述方法允许将更多逻辑移到代码隐藏中,从而可以借助编译器,并且可以更容易地被 NUnit 等测试软件访问。我坚信将尽可能多的逻辑移出 UI,而这似乎是减少一些棘手的 JavaScript 代码并保持项目“干净”的好方法。

资源

© . All rights reserved.