Hello World
Spiga

有关注册DataItem的一些可能被忽视的事情

2007-04-18 15:05 by 老赵, 7003 visits

在UpdatePanel对页面进行部分刷新时注册一些Data Item是ASP.NET AJAX的特点之一。我们可以在服务器端为某个控件注册一个字符串甚至是一个对象,然后在客户端将将其取回。但是现在我希望向您展示一些您可能会忽视的事情。

让我们先从最基本的用法开始。在一个异步回送过程中,我们可以调用RegisterDataItem方法将一个字符串与一个UpdatePanel绑定起来:

ScriptManager.GetCurrent(this.Page).RegisterDataItem(this.UpdatePanel1, "DataItem");

在客户端,如果我们监听pageLoading,pageLoaded或者endRequest事件,我们就可以使用下面的代码,使用控件的ClientID将这个字符串取回:

Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(
    function(sender, e)
    {
        var dataItem = e.get_dataItems()["<%= this.UpdatePanel1.ClientID %>"]; // "DataItem"
        // more implementations...
    });

RegisterDataItem方法还有一个重载的版本会接受一个额外的参数,其作用是使用一个布尔值来表明我们注册的dataItem是不是已经被序列化为JSON。但是这里就出了一个问题——甚至在官方文档中的示例也是不正确的。

下面的代码选自官方文档中的示例:

protected void Page_Load(object sender, EventArgs e)
{
    if (ScriptManager1.IsInAsyncPostBack)
    {
        System.Web.Script.Serialization.JavaScriptSerializer json =
            new System.Web.Script.Serialization.JavaScriptSerializer();
        ScriptManager1.RegisterDataItem(Label1, DateTime.Now.ToString());
        ScriptManager1.RegisterDataItem(Label2, json.Serialize("more data"), true);
    }
}

这个示例的确能够正常工作,但是它事实上掩盖了一个问题。请注意,序列化之后的Data Item会被JavaScript内置的eval方法解释执行:

function Sys$WebForms$PageRequestManager$_onFormSubmitCompleted(sender, eventArgs)
{   
    //...

    for (i = 0; i < dataItemJsonNodes.length; i++) {
        var dataItemJsonNode = dataItemJsonNodes[i];
        this._dataItems[dataItemJsonNode.id] = eval(dataItemJsonNode.content);
    }

    //...
}

在官方文档的示例中,字符串“more data”会被序列化为“"more data"”(请注意多出的双引号),这样从eval方法中得到的结果就是“more data”,这正是我们注册的内容。这个再正常不多了,不是吗?猜猜看如果我们将一个序列化的对象注册到客户端时会发生什么事情呢?我为此写了一个示例:

//  the definition of Person class
public class Person
{
    public string Name;
}


// the code to register a Person object
Person person = new Person();
person.Name = "Jeffz";

JavaScriptSerializer serializer = new JavaScriptSerializer();
ScriptManager.GetCurrent(this.Page).RegisterDataItem(
    this.UpdatePanel1, serializer.Serialize(person), true);

当我们进行异步更新时就会抛出异常。似乎这是因为服务器端注册的表示Person对象的JSON字符串“{"Name":"Jeffz"}”无法被直接传递进入eval方法。具体的原因关乎语法方面的问题,可以在ECMAScript Specification中找到解释,因此我在这里就不多作解释了。那么,请注意我下面的代码:

ScriptManager.GetCurrent(this.Page).RegisterDataItem(
    this.UpdatePanel1, "(" + serializer.Serialize(person) + ")", true);

现在,我们的代码就能正常工作了,于是我们就可以在客户端将Person对象取出:

Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(
    function(sender, e)
    {
        var person = e.get_dataItems()["<%= this.UpdatePanel1.ClientID %>"];
        alert(person.Name); // "Jeffz"
    });

这样看来,这个问题也就可以使用这个方法来解决了。不过为什么ASP.NET AJAX会使用eval方法,而不是定义在Microsoft AJAX Library中的deserialize方法来反序列化一个对象呢?我们可以发现,在deserialize方法中,一个表达式被传递给eval方法之前会被自动加上括号:

Sys.Serialization.JavaScriptSerializer.deserialize = function (data)
{
    try
    {    
        var exp = data.replace(...);
        return eval('(' + exp + ')');
    }
    catch (e)
    {
         throw Error.argument('data', Sys.Res.cannotDeserializeInvalidJson);
    }
}

我猜想,会不会是因为编写部分刷新相关代码的开发人员并不完全了解Microsoft AJAX Library中的功能呢?不过可能性最大的原因则是这些代码没有被完整地Review和测试过。事实上这并不是ASP.NET AJAX最终版本中唯一的bug,其他的还包括那个著名的“跨域名frame的拒绝访问错误”和StringBuilder的Bug

嗯,我们问题也看够了,就把目光移向别处吧。尽管逻辑上一个Data Item应该是一个包含信息的对象,但是请注意我们是使用eval方法来“反序列化”一个JSON字符串的。这意味着我们事实上可以将任意的合法表达式发送到客户端,然后它就会被正确执行。请看下面的示例:

ScriptManager.GetCurrent(this.Page).RegisterDataItem(
    this.UpdatePanel1, "var __f = function(){alert('Hello World!');}; __f;", true);

Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(
    function(sender, e)
    {
        e.get_dataItems()["<%= this.UpdatePanel1.ClientID %>"]();
    });

我在上面代码中将一个函数注册为一个Data Item并且在客户端将其执行了。如果您深入了解UpdatePanel局部刷新的过程,您会注意到您在服务器端注册的JavaScript代码只有在页面更新结束后才会生效,也就是说,我们无法在pageLoading事件被触发时执行这些代码。我会在之后的文章中针对这样的设计以及如何使用work arounds来解决这个问题进行详细的探讨。这些work arounds就是基于Data Item注册的使用方式的,因为表示Data Item的“JSON字符串”在pageLoading触发之前就被解释执行。

 

English Version

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

35 条回复

  1. BoyLee
    *.*.*.*
    链接

    BoyLee 2007-04-18 16:16:00

    感谢,学习中

  2. llinzzi[未注册用户]
    *.*.*.*
    链接

    llinzzi[未注册用户] 2007-04-18 20:44:00

    我是老赵必读呀,呵呵,感谢老赵的文章
    我菜菜。。
    没理会出RegisterDataItem
    比System.Web.UI.ScriptManager.RegisterStartupScript有什么优势。
    前者能完成的,后者应该也都能完成吧
    优点在于方便嘛?机制上差不多嘛。
    我菜菜,随便问问,我再啃啃,(我知道我菜菜,别骂我哈,我会更伤心的。菜菜也有权利说话嘛,就是有点污染老赵底盘了。这是我看过就顶的优良习惯。)

  3. 老赵
    admin
    链接

    老赵 2007-04-18 21:08:00

    @llinzzi
    功能完全不一样啊,一个是注册数据项,例如一个对象啥的,一个是添加JavaScript函数之类的。至于区别许许多多……其实我没有看出任何相同的地方啊……

  4. llinzzi[未注册用户]
    *.*.*.*
    链接

    llinzzi[未注册用户] 2007-04-19 01:36:00

    同样的功能。
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Sopu.Business.WebForm1" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
    <title>无标题页</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
    <script type="text/javascript">
    Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(
    function(sender, e)
    {
    var dataItem = e.get_dataItems()["<%= this.UpdatePanel1.ClientID %>"];
    alert(dataItem.Name);
    });
    </script>

    <div>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>

    <asp:Button ID="test" runat="server" Text="test" OnClick="test_Click" />
    </ContentTemplate>
    </asp:UpdatePanel>
    </div>
    </form>
    </body>
    </html>



    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Web.Script.Serialization;

    namespace Sopu.Business
    {
    public partial class WebForm1 : System.Web.UI.Page
    {
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void test_Click(object sender, EventArgs e)
    {
    Person person = new Person();
    person.Name = "Jeffz";
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    ScriptManager.GetCurrent(this.Page).RegisterDataItem(this.UpdatePanel1, "(" + serializer.Serialize(person)+")", true);

    System.Web.UI.ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "test", "var p = (" + serializer.Serialize(person) + ");alert(p.Name)", true);

    }


    }

    public class Person
    {
    public string Name;
    }



    }


    都实现了同样的功能,前者是增加了个结束的hander,后面是结束直接输出了这个person,总赶紧差不多。。

  5. 老赵
    admin
    链接

    老赵 2007-04-19 02:38:00

    @llinzzi
    那么我只能说,用这种方式来比较的话,很多方法都差不多了。您用了两种截然不同的方法来得到了同样的效果而已(比如您的例子只是alert出了一端文本而已),怎么能够说这两种方法是相同或者差距很小呢?它的从概念到使用方式几乎没有一点相同的地方……
    而且您同样的效果也只是看上去的,其实有一点很明显,DataItem是服务器端注册的临时项,生命周期结束之后金没有了,而且从pageLoading阶段中就可以使用。而RegisterXXX方法只有从pageLoaded阶段起才能够使用。

    简单的说,一个是临时的“数据项”,一般一个对象。另一个是注册了一段脚本,比如在叶面上添加一些方法等等。如果像您现在把它们“硬掰”成“看上去”相同的效果,您觉得这么比较合适吗?:)

  6. llinzzi[未注册用户]
    *.*.*.*
    链接

    llinzzi[未注册用户] 2007-04-19 05:30:00

    谢谢老赵的解释。想起ajax.net了,这东西也能把.net的对象发送给js。
    没想到老赵这么晚还在线。
    继续关注。

  7. wqx[未注册用户]
    *.*.*.*
    链接

    wqx[未注册用户] 2007-04-20 22:32:00

    想请教下,能在VS2005默认ASPNET.MDF(则用户注册信息表)那里象我们平时的数据那样添加表吗?请问是可以这样做的吗

  8. 老赵
    admin
    链接

    老赵 2007-04-20 23:33:00

    @wqx
    只要有权限,就可以这么做。

  9. 工控网[未注册用户]
    *.*.*.*
    链接

    工控网[未注册用户] 2007-04-23 13:34:00

    长见识了!!谢谢

  10. Bing[未注册用户]
    *.*.*.*
    链接

    Bing[未注册用户] 2007-04-25 01:06:00

    老赵啊,我的桌面论坛“百工”的Alpha 版本开发完成,现在可以通过如下链接开始访问:http://lovanwubing.w26.cndns.com/ ,我们的域名明天才申请好。欢迎老赵赏脸来关顾一下,并提点意见啊!
    具体的关于“百工”的信息可以访问我的Blog

  11. 老赵
    admin
    链接

    老赵 2007-04-25 13:23:00

    @Bing
    :)

  12. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-04-25 21:19:00

    @Bing
    你的AJAX框架和MagicAjax什么关系? 看见一些MagicAjax的代码,感觉它不太好用所以重构了?

  13. 老赵
    admin
    链接

    老赵 2007-04-25 22:37:00

    @怪怪
    似乎是集大成者,完全放弃了Page模型的优势,可能性能高了但是开发难度急剧增高。感觉这样前途不大,还不如完全放弃Page模型,重新写一个Handler……

  14. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-04-26 01:49:00

    呵呵,我倒是对这个有点理解,控件的模型优点很多,不过Page模型像Bing那么用有点鸡肋,而控件又和Page是紧耦合的,如果不用Page直接RenderControl,等于又放弃了控件模型微软已经提供的功能。这个其实没有足够的工作量,很难重新从一个Handler开始的。最关键的是开始设计得好,不是指性能或架构的完美性,而是未来必须能够很容易的不停的重构,才能走远~

    我不太了解MagicAJAX,只匆匆扫过几眼,看Bing的客户端代码里好像含有不少MagicAJAX的成分,所以想了解一下他对MagicAJAX的看法,作为听来的经验 :)。

  15. Anders.X.Liu[未注册用户]
    *.*.*.*
    链接

    Anders.X.Liu[未注册用户] 2007-04-26 11:03:00

    ScriptManager.RegisterStartupScript在注册时
    有二步处理,
    (1)ClientScript.RegisterStartupScript()进行同步回传注册
    (2)如果是异步的话,使用ScriptRegistration.RegisterClientScriptBlockInternal()

    如果您熟悉asp.net 内核,您会发现ClientScript.RegisterStartupScript()注册的信息,是在何时被Render到客户端的的?它是在Page.EndFormRender()时调用的

    如果当前是异步的回传,Page.EndFormRender()是不会被调用的,(因为RenderPageCallBack替换了正常的流程)
    因此,在异步回传时ClientScript.RegisterStartupScript()是没有任何作用,
    您就是注册了,这部分也不会回发的!!!!!!!!

    异步回传时处理如下,
    在PageRenderCallBack()方法里,
    ProcessScriptRegistration()时,会将ScriptRegistration.RegisterClientScriptBlockInternal()
    注册的块呈现到客户端的


  16. Bing[未注册用户]
    *.*.*.*
    链接

    Bing[未注册用户] 2007-04-26 12:28:00

    @怪怪
    恩,客户端代码是参考的MagicAjax来的,所以有很多相似是很正常的。MagicAjax只是一个非常小型的框架,服务器端就一个UpdatePanel非常有用,任何东西拖到里面就可以实现无刷新了,但是还是要渲染所有的控件,同时没有办法将所有的页面整合到一个页面上,因而MagicAjax用在实现一些非常局部的无刷新是个不错的选择,但是功能太过于有限。

    这个论坛的开发依旧是使用Page模型,所有的表现层还是控件,只不过这些控件很多是自己写的,还有是继承自System.Web.UI.WebControls里面的控件,这些控件都是WediaAjax的一部分,WediaAjax掌控了所有的渲染,开发的时候我没有写一行Javascript代码,这些都用WediaAjax封装好了的。但是为了不改变传统的设计模式,同时将所有的Pages集成到一个Page里面,我采用的是动态加载组件的方式,结合我自己开发的WediaAjaxPanel实现无刷新,对资源的损耗将到最低,同时对于好的设计,扩充性和重构都不是问题,不存在可能存在构架重构带来的问题。

  17. 老赵
    admin
    链接

    老赵 2007-04-26 15:03:00

    @Anders.X.Liu
    了解过分细了之后好处并不大。:)

  18. andy[未注册用户]
    *.*.*.*
    链接

    andy[未注册用户] 2007-04-26 20:18:00

    赵老师,我想向您请教一个问题:
    我想用javascript 调用一个类数组.不知道怎么实现?比如.
    public class Employee
    {
    private string _name;
    private double _salary;
    }
    我现在在客户端调用一个webservice 上取得一个Employee[]数组,然后将其绑定到一个DropDownList上.不知道如何实现.希望您指点.谢谢.

  19. 老赵
    admin
    链接

    老赵 2007-04-26 23:50:00

    @andy
    您了解如何在客户段访问WebService吗?以及使用JavaScript修改Option元素。

  20. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-04-27 02:18:00

    @Bing
    呵呵,这次我听得比较明白了,不过感觉你和我理解的架构不是一种东西~ 比如,你这个确实不存在重构的问题,因为你把需求给集中或影射到一个小范围内了,这个在很多时候确实是解决问题的很好的一个办法,感觉你挺能想也敢于做的,等着看你更上一层楼了 :)

  21. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-04-27 03:09:00

    其实有点话没说出来,憋着也没意思,还是说了吧,反正咱俩也没什么办公室政治,我更愿意看见的是国内技术这块能真正出现一些高人呵呵。你说“同时对于好的设计,扩充性和重构都不是问题,不存在可能存在构架重构带来的问题”,这句话本身是有很大问题的。

    主要是:
    1.什么是设计,是在多大范围内的设计。
    2.什么是好的设计。
    2.扩充性和重构都不是问题,还有后面那句话,这不是一个小心谨慎的看法。

    拿你这个框架举个例子:
    1.你这个绝对算是一个设计了,但并非一个整体设计,而是从你自己定义的需求而进行的一个局部设计。当你把需求简化到一定地步的时候,由于局部就覆盖了需求,所以就会被认为是一个整体设计。但需求往往并不如你所想,如果简单的把AJAX或你提的桌面概念简单的理解为异步提交支持下的无刷新和流畅感,大多数工作其实围绕着这一个目的展开,那么未来一定会遇到瓶颈。比如拖拽、NoBot、验证,这些界面应用,比如权限、事务、工作流等模型上问题。

    2.那你可能会说了,我扩展这些完全不成问题,以前怎么写现在怎么写,该写的控件什么时候都得写,只是稍微改变一下方式,就可以完全无刷新了。这个问题看似这样,但其实这不是你的设计,这还是原来微软的设计,你的设计只是改变了其中一小部分行为模式而已。比如工作流,如果我应用你的框架,我照样可以用WWF,但其实WWF还是和ASP.NET结合,然后经过你的AJAX框架来改变渲染、提交和刷新的方式。这样的话很难说什么是好的设计,因为这是不由你决定的,只有ASP.NET本身是一个好的设计的前提下,然后你的设计足够好,并且再任何情景下都能良好结合,才能说是一个好的设计。

    3.我想即使是那些设计模式、极限编程的大师们,也不敢轻易说扩展和重构没问题。这里面内容很多,我的建议是你真正了解了这些之后,再来重新审视自己的作品。

    我上个帖子里说,等着你更上一层楼,其实就是不想说的太明显,你现在视野比较窄,在一个需求里做的比较出色了,就觉得可以涵盖住一切应用,实现你的桌面化的目标。当然国内真正的专家很少,你现在还上着学,就有这么高的水平是十分难得的,估计一大票人包括我在内都得吃醋,但我建议你换一个角度来考虑这个问题:假设带宽大10倍,响应快10倍,浏览器渲染得方式也稍微变变,最传统的同步提交看起来就和你现在做的博客/论坛效果一样,然后你再考虑一下你在使用桌面软件时能进行的所有操作,这能算桌面化吗?当你把在Windows里的全部操作或者比如文字性游戏(这还是为了减少复杂性)如冠军足球经理这类的东西的操作的实现也考虑进去,想想ASP.NET能够提供给你什么,然后你需要完成什么,再回过头看自己的框架是否足够。

    说实话写到这儿我都考虑一下是不是要发,因为我自己高度有限,我也不是你,所以我很难避免贬低别人作品的嫌疑,连自己都不确定我这个行为是否实质上在这么做。如今大家交流的时候都在避免这个。我一开始看见你的东西,说实话还是比较兴奋的,因为感觉国内现在水平真是提高了;不过最近我又感觉到如果我希望你进步,最好的方法还是泼泼冷水。但你知道我交流时最怕什么吗?热脸贴个冷屁股,被人误解 :(。

    比如如果我说,你说清楚以后,我并不感到新鲜,比如ScottGu的博客上很早就有类似的讲解和小例子(这是说明有人用的着),但至今没有系统化绝不是因为大家都蠢(这意味着对于真实的需求其实意义不大,比如PageFlakes的自定义页面、Reader这类应用现有的代码其实都可以很容易—大概1周到2周—提炼出比你这个还完整的动态加载、单页面框架),园子里几个水平不错的人如果有时间不用参考任何框架很短的时间就可以做出同样甚至更好的东西,你能接受吗?

    这就是老赵为什么说"前途不大",而我说你未来想走更远,就得能够不断重构的原因;因为如果你真是我所期盼的那种有恒心、有毅力的人,未来肯定会走得更远,碰见很多你现在根本没想到的问题和需求。

    怎么说呢,如果我最终没发这个帖子,我会感到良心不安,感觉我是在藏私~ 还是那句话,好意恶意自己判断吧,祝你成功啦 :)

  22. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-04-27 03:32:00

    由这里我就想到前一阵子你对Atlas的议论,其实我发自内心的说,别人跟风真的不是因为大家都蠢,我敢保证熟悉ASP.NET和Javascript的人大把抓,确实是人家对Atlas乃至ControlToolkit这样的东西有需求。老赵一天到晚围着UpdatePanel转,是因为我们需要的是Atlas这样的东西,所以在UpdatePanel或其它(比如MagicAJAX、你的框架)类似解决方式中只能选择UpdatePanel,基于需求奠定了选择。

    我所担心就是,如果你真的认定你的设计象你说的那样好,那么既然已然“百尺竿头”,就很难更进一步了,而在大家看来这仅仅解决了一小部分问题而已,还远远不够用,你希望这样吗? :)

  23. Bing[未注册用户]
    *.*.*.*
    链接

    Bing[未注册用户] 2007-04-27 10:32:00

    @怪怪 && @老赵
    我不是一个太喜欢和别人争吵的人,更不喜欢拿着“自鸣得意”的东西到处宣扬,事实上我这辈子的追求就是回家没事打打麻将,走上IT是无奈(这个是因为我专业本身是材料的缘故)也是巧合(我最开始看一本ASP书籍的时候感觉比看侦探小说还要有意思),至今我这这里面走的很Happy,很累,也一直很努力着。当然,作为一个年轻人,我希望能得到别人的认同,当然我的志向也绝不仅仅只是一个小小的“WediaAjax”。
    首先我不想再来和别人争吵什么,这个没有什么必要,永远也没有尘埃落定的时候,我想“走自己的路,让别人去说吧”。当然我能很清楚的认识到在市场上和产品上的眼光我远不及你们,这个是由于资源和时间有限的迫不得已。但是既然话已经说到您这点子上了,有些观点我给您阐明了,虽然很可能错误,但是我希望即使错也能错的潇洒,并能最终成长。虽然并不认识您和老赵,但是真的感觉很亲切,谢谢怪怪还有老赵。

    首先,我想说得是我对我所鼓催的WediaAjax的看法,WediaAjax是一个小型的框架,经过这次的改版,其JS代码已经缩到12K,服务器端再次精简,这是符合我个人目前开发的需要。Atlas很强大,对的,我非常赞同,但是目前为止并不适合做我现在的开发,在带宽、响应没有快十倍的情况下,我需要一种更为高效,更为简洁,更为快速的解决方法,我很清楚,当我有一台牛场一样大的服务器,手机在线播放视频跟看电视一样的时候,什么都不是问题,但是作为一个大学生,我希望我能看看我能企及的所谓的最高效率是个什么样子,这是对自己的负责。WediaAjax是基于ASP.NET 2.0的,当然得依靠ASP.NET2.0,并不是一种什么新的东西,而是我的一个实验性产品,仅仅是作为我的一种尝试,毕竟我的.NET学龄不到一年。WediaAjax的存在仅仅只是作为我思考问题和解决问题的一种方式而已,也只是我在不想改变传统的设计模式,不改变设计时涉及到验证、权限、事物、工作流而进行的一种尝试。我并不想拿它去超越ASP.NET Ajax,更不想和它比个高低,这没必要。以前我在我的Blog上写的东西,仅仅只是我内心有点急功近利的表现和宣传产品的一种尝试,我想尽快得到别人的认可,不想弄巧成拙了。浮躁只能带来糟糕的后果。WediaAjax我会在这个五一将其源码发布,是好是坏,让别人去评论好了,我并没什么要求。

    其次,对于桌面化的理解,我只想说说我的观点以及我所理解的微软对ASP.NET Ajax的战略目标。首先我理解的桌面化在现今就是一种无刷新,虽然Ajax能走得更远,但是我个人觉得这是Ajax的一种误区,尝试利用Ajax模仿Windows桌面和软件,我只能说Ajax并不擅长这个,如果开发类似的拖拉操作,我选择的肯定是Flex,而不是Ajax。同时现今的网站涉及的不仅仅是技术,还有艺术的成分,网页的效果,颜色的搭配,空间的摆放都是我在网页设计上的一种追求,如果全部换成和Windows操作界面一样的东西,是不是又会枯燥乏味不少呢?艺术往往能让我们流连忘返,回味深远。至于未来的桌面化,我个人觉得是会向着更艺术化,更人性化的方向发展,给人带来服务享受的同时,还带来一种艺术的美感。那么到那个时候,Ajax是否会继续存在,我并不看好,因而我现今做的是WediaAjax,而不是Atlas。至于微软如何看待ASP.NET Ajax,我个人认为这仅仅只是微软为了抓住现有客户的一种手段,同时加个非常美妙的词语“开源”,微软看好的是XAML,而不是Ajax。如果您愤怒了,请不消消气,个人愚见,如有雷同,纯属巧合。

    最后,我也没什么好说的了,聊聊吧,我有时也挺郁闷的。在我们这样一个时代,尤其是父辈没有留下值得炫耀的资产的时候,白手起家实在不是一件容易的事,而偏偏我又一直想回家讨个平凡的老婆,然后生个女儿,就这样一辈子稀里糊涂的过过去,而偏偏整个家族又对我寄予极大的厚望,有时感觉真的很累。虽然自我觉得在IT方面有点天赋,但也绝对是靠自己一分钟又一分钟拼命编码和苦思冥想换回来的。然而IT仅仅只是IT,一个时代诞生的产物,毕竟都会随风而逝,而内心真实的自我才是人类永远锲而不舍的追求,比起高竞争,快节奏的社会,我更喜欢过一种“宠辱偕忘,看门庭花开花落;去留无意,看门庭花开花落”的日子。算了,都是一堆屁话。。。一睁眼又要开始想工作,想考试的事了,真是庸人自扰。。。

    PS:对于先前的说别人“跟风”,我再一次表达歉意,但是我也希望再仔细认真思考一下,国内还需要进步,仅仅只是别人的东西,很难成为先驱,也很难看到未来,当然人个人能力有限,现在我也是无能为力。

  24. andy[未注册用户]
    *.*.*.*
    链接

    andy[未注册用户] 2007-04-27 11:17:00

    @Jeffrey Zhao
    我就是看过您的讲座的第一讲.就试着做这个小程序的.可您的讲座返回的只是一个Employee对象或是一个字符串.,我现在是要返回一个对象数组.然后从客户端将其分离绑定到DropDownList上.我不知道怎么做了.希望您给点代码提示.谢谢.

    我的email是:lgxcentury@sohu.com

    再次感谢!

  25. 老赵
    admin
    链接

    老赵 2007-04-28 00:55:00

    @andy
    使用WebService,返回一个Employee数组,然后填充select元素就可以了。

  26. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-04-28 01:48:00

    @Bing
    突然发现在老赵这里谈不太合适呵呵,不过这里已经是我最常来的地方了,就在这里随便扯两句吧。其实我们每一个人的问题,大家尤其是刚起步的人,无论他是强还是弱,都会遇见的。这样,嫌我烦的我对他也造不成什么伤害,如果别人能从你我的感慨里得到什么,那么也是一件好事。

    说实话,压力人人都有,这个你只有放轻松。世界上没有什么事情是大不了的。你的实力,现在还在上大学,出来一定能够出人头地,所以我说那么多,更多的希望你不要碰到天花板,其实这也是我想对老赵说的,也是我经常对自己的未来思考的。一年的.NET学习,到你今天这样,已经很不错了,我12岁左右就开始学编程,很早在DOS上能制作一些图形界面的东西,数据结构虽然不能完全理解也能照葫芦画瓢,但今天我不敢说我自己水平和你比怎么样,你对自己其实应该是自豪的。反过头想我自己,因为天分不足(最早是小孩子的小聪明)、自己不勤奋,导致十几年后不过是现在这种水平,我心里也不好受,那么我能怎么样?不干这行了? 不干这个我干什么去。看来你家庭背景不错,只是家里不是巨富,那么有一点,是我毕业几年来一直在思考的,我可以告诉你(因为我情况类似),如果实际上家里还有一点薄底,或者你的技能用在吃饭问题上三天打鱼两天晒网也能活下去,不至于为了生存奔波,你完全可以放开一些,尽情去干自己想干的事。成功不会来的十分容易,贵在坚持,哪怕所有的人都不看好,但这事只要需要别人做,而你还能贡献一份力量。我深信,当你对生产力和生产关系的改善付出的够多,你总有一天会获得回报。而且互联网象一个筛子,正在把那些阻碍改善的环节不停的扫掉。你现在对未来生活的种种幻想,说实话,我不太敢冒,人家说少年不识愁滋味,就是说的你我。从你出生开始,你就开始接受大量信息,其中一些是你愿意接受的,比如对于生活的某种理念,于是你认为我应该怎么怎么样,其实这未必是你想要的。这方面,不要想太多。

    回到具体的话题。

    我说那么长的话,不是又拿你的东西在和Atlas去比,需求不一样,结果不同。我的目的只有一个,提醒你不要过于急功近利,并且千万千万不要自视过高,我再过去老赵这里的一个回帖上探讨过这个问题。你可以看看李彦宏Baidu初期的博客,也可以看看ScottGu这样的技术大拿的博客,我觉得李彦宏确实是谨小慎微的,而很多技术大拿则是很平常的在说一些事,哪怕是推销自家的产品。而你的博客里我更多的看到的是自我肯定,自我肯定对自信心有用,但我个人认为仅限于自己和自己比。因为你做对的事,只是你今天的高度,而这个高度到底多高,我想自己最好不要多去思考,也不要去和别的东西去比。拿己之长,比人之短,并不代表着就弥补或避开了别人的缺陷。因为人家解决的问题可能和你解决的在方向和范围上就不一样。比如如果Atlas也主要是围着无刷新打转,那么你说的就是正确的,如果以Release版gzip后2xK而论,至少有1xK是无用代码。但Atlas,尤其是其客户端框架,其实根本不是以UpdatePanel方式实现无刷新为核心的,这块一共就几K代码,还在单独的JS里。

    然后说这个桌面化的问题。其实SilverLight还是需要javascript配合的,Apollo和Flex我不太懂,Flash我也了解不够,不过我感觉,Flash的表现层面上在现今的应用下,也是需要Javascript的配合才足够灵活,比如广泛使用的pixviewer.swf;而且实质上Flash的脚本也是ECMAScript吧。我看未来JavaScript一定是逐渐开始挑大粱的角色,因为通过语言控制显示元素这一部分完全可以剥离出来,而且剥离是唯一合理和有利于进一步发展的方式。从这个角度来看,就一定不会是RIA代替了AJAX,而是所有的RIA不得不倚重于各种强大的AJAX框架,而且不同的RIA和不同的AJAX框架之间可以灵活配对。至于JavaScript的天生弱点,难道JavaScript就没有再升级么? :) 你对微软的判断,说实话过于传统。微软不是一般的公司,不是Google,不是Oracle,这些看似在挑战微软的非传统公司或者其看似非传统的领导者,其实其作为反而是相当传统的。微软从最初最擅长的事,就是委身下嫁(而且微软总能找到一个机会让人不得不娶),然后生出杂交的后代,而这个后代往往就具有很强的生命力。另外XAML和AJAX,根本是不同的概念,这个我想你没仔细的思考过,就不探讨了。的确XAML是微软看好的,AJAX不过是块试验田,但这块试验田给与微软的是灵活的、可进可退的能力。从我有限的眼光来看,以微软的那点能耐(其实也没有任何公司有这个能耐),根本就改变不了Script成为主流的发展方向。你能想象技术都发展到了今天,开发者的选择不是过少而是太多的情况下,各大公司还不停的增加新的东西,各圈一块地么?真正的标准是怎么来的,靠的不是W3C,而是“不得不”。想想看,为什么大多数Flash实际上只是广告或简单的展示,因为Flash专家往往玩儿不转ActionScript,而就像你说的,程序员根本做不出艺术化的界面。现在全世界都MVC了,这是需求的选择,这是IT业界生产力发展方向的选择,所以RIA必然也只有走这条老路。M的表现形式可能是各种样子的XML,也可能是其它形式;V就是Flash、WPF/E、Apollo之流,C由JavaScript(也许将来还会有更多的Script也不一定)实现。完全完全的松耦合,语言可以不一致,MVC三者可以选用完全不同的产品来实现,还有比这更合理的方式么? 比如说:WPF/E内置一种Script,Apollo内置另一种,并且都只能有限的和文档(因为未来也未必是网页了)内的JavaScript结合,只是为了技术壁垒? 那么谁先跨出我说的这种形态的第一步,谁就是胜利者。不是说Apollo和SilverLight就不可以内置Script,但他们的主要任务只是维护View中的各种元素,并且最好足够简单的让美工或设计人员也能使用。现在社会讲究越来越细致的分工嘛,难道世界上能用程序语言表达复杂逻辑(哪怕仅仅是界面逻辑),同时又有艺术细胞的人那么多?上帝的归上帝,凯撒的归凯撒,正是你对未来网络应用的这种希望和判断,进一步坚定了我的看法。那么对于AJAX框架们来说,到底是控制Html元素,还是控制RIA内的元素,除了未来会更容易外,又有什么区别?所以AJAX框架一定不会消亡,而是会越来越强大,甚至带来语言的升级。

    这个说实话一大堆只是个人的想法,我也不会继续再做深入讨论,未来的发展会证明谁是对的。但是有一点想必你可以看得出来,我的论调,绝对是深入思考,而且我有信心说我的视角还是有一定广度和深度的,而不是说对某种技术、某家公司的热衷或简单判断它的行为到底是什么目的会带来什么后果,即使微软倒了,只要我所描述的这个前景成真了,我将来进行开发照样很容易不是?所以我不可能有什么愤怒 :),说一句,这么去臆测别人可不好,把你表达你的意图的对象进行一个想象加以判断,甚至都预测人家的情绪了 :P 。

    多的不说了,最近效率较低,回去干活了。

    最后是版权声明时间,拒绝一切靠文章、浏览量吃饭的网站及编辑借鉴我这篇文章的理念,你可以说相同的事,你自己想出来的我管不着,如果你受我启发,要么你的二次加工的深一些,要么如果只是简单的重新组织,请你给我、老赵或者博客园寄钱。

  27. Bing[未注册用户]
    *.*.*.*
    链接

    Bing[未注册用户] 2007-05-07 19:56:00

    站长好,本站链接地址已经从http://www.wubingstudy.com更改为http://www.bingblog.net,以前的那个域名在未来十天里将作废处理,请您将友情链接地址更换一下,Blog名称为:BingBlog。给您带来的不便表示抱歉。

    @老赵&@怪怪
    WediaAjax已经发布了。。。

  28. 老赵
    admin
    链接

    老赵 2007-05-08 04:58:00

    @Bing
    :)

  29. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-05-19 08:55:00

    @Jeffrey Zhao
    请教个问题,对于ASP.NET AJAX客户端JS库来说,是否单form是必须的?想用多form实现些功能,服务器端没什么难度,但是客户端JS看的太粗,心里没底。

  30. 老赵
    admin
    链接

    老赵 2007-05-19 21:38:00

    @怪怪
    如果不用一些技巧,应该算是必须的,form元素在一开始就被保留了起来。

  31. 怪怪[未注册用户]
    *.*.*.*
    链接

    怪怪[未注册用户] 2007-05-20 01:30:00

    只要需要变动的地方别太多,搞点偷鸡摸狗的事我在行 :P。谢了~

  32. idcnew[未注册用户]
    *.*.*.*
    链接

    idcnew[未注册用户] 2007-07-16 14:24:00

    北京新鑫互联 提供国内外空间,美国空间,台湾空间,香港高速空间QQ:603335822

    我们的服务空间站:http://www.idcnew.cn

  33. idcnew[未注册用户]
    *.*.*.*
    链接

    idcnew[未注册用户] 2007-07-16 14:25:00

    香港VPN代理,美国VPN代理,香港sock5,美国sock5代理租用 QQ:519266738

    迅捷代理 满城尽带 VPN香港专线 VPN美国专线

    http://www.hivpn.cn

    VPN租用价格: 50元/月 150元/季 600元/年

  34. 淡淡的[未注册用户]
    *.*.*.*
    链接

    淡淡的[未注册用户] 2007-08-21 04:48:00

    @怪怪
    看你帖子真的受益匪浅。如上一堂技术人生哲理课,受用无穷。

  35. nect[未注册用户]
    *.*.*.*
    链接

    nect[未注册用户] 2007-09-06 16:00:00

    Jeff:
    我这里有一个程序希望能再updatepanel里面弹出对话框,而且这个页面还使用了母版,比较复杂一点,麻烦你看看什么问题吧,我给你发到邮箱去了。

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我