ASP.NET2.0页面框架的几处变化

作者:http://blog.joycode.com/liuhuimiao/

  1. 新增的页面事件
    在ASP.NET 2.0中,一个ASP.NET页面的生命周期主要为(红色字体表示ASP.NET 2.0新增加的阶段页面事件):客户端请求页面—》预初始化(OnPreInit)—》初始化(OnInit)—》完成初始化(OnInitComplete)—》载入ViewState(LoadViewState)—》处理回送数据(IPostBackDataHandler)—》Page_OnPreLoad—》Page_OnLoad—》回发更改通知(RaisePostDataChangedEvent)—》处理回发事件(RaisePostBackEvent)—》Page_OnLoadComplete—》预呈现(OnPreRender)—》完成预呈现(OnPreRenderComplete)—》保存ControlState(SaveControlState)—》保存ViewState(SaveViewState)—》呈现(Render)—》Page_UnLoad。

    • OnPreInit:在初始化页面OnInit事件前触发。在这个阶段里,可以进行定义站点主题(Theme)或加载站点个性化所需要的数据信息等操作。
    • OnInitComplete:完成初始化页面OnInit事件后触发。
    • OnPreLoad:在加载页面OnLoad事件前触发。
    • OnLoadComplete:完成页面加载OnLoad事件后触发。
    • OnPreRenderComplete:在完成预呈现OnPreRender事件后触发。这是完成页面呈现的最后一道关卡,在此之后,页面将无法再进行任何呈现上的改动。
    • SaveControlState:保存控件状态ControlState。ControlState是ASP.NET2.0控件新增的一个属性,类似ViewState作用,但它们区别在于ControlState用于保存更加重要的控件状态信息,以保证在禁用ViewState的情况下还可以对控件状态进行读写操作。
  2. 增加对页面Header的控制:
    System.Web.UI.Page类新增加了Header属性,用于对HTML页面头区域里数据的操作。通过对Header属性的跟踪,可以发现,Header属性保存着一个实现IPageHeader接口的对象(该对象有LinkedStyleSheets、Metadata、StyleSheet和Title四个属性),实际上正是通过这个对象实现对HTML页面头区域里数据的操作的。例如:
    <script runat=server>
    void Page_Load(object sender, System.EventArgs e)
    {
    this.Header.Metadata.Add(author, brooks);
    }
    </script>

    其运行结果为:
    <html>
    <head> <title>Untitled Page</title>
    <meta name=”author” content=”brooks” />
    </head>
  3. 定义表单中的默认按钮:
    在ASP.NET1.0中,我就为了设置表单中的默认按钮而一筹莫展。幸好ASP.NET2.0把这个功能补上了,现在可以非常方便的设置表单中的默认按钮了。
    <%@ page language=C# %>
    <script runat=”server”>
    void Button1_Click(object sender, System.EventArgs e)
    {
    this.LB_Message.Text = You clicked button1;
    }
    </script>
    <html>
    <head runat=”server”>
    <title>Untitled Page</title>
    </head>
    <body>
    <form runat=”server” defaultbutton=”Button1″>
    <asp:textbox id=”Textbox1″ runat=”server”></asp:textbox>
    <asp:button id=”Button1″ runat=”server” text=”Button” onclick=”Button1_Click” />
    <asp:label id=”LB_Message” runat=”server”></asp:label>
    </form>
    </body>
    </html>
  4. 设置焦点
    现在假设为TextBox1控件设置焦点,在ASP.NET 2.0中可以这样实现:
    this.Textbox1.Focus(); this.SetFocus(this.Textbox1); 即可为TextBox1控件设置焦点。
    如果打算也为表单设置个默认焦点控件,让光标默认停留在TextBox1上:
    <form runat=”server” defaultfocus=”TextBox1″>
  5. 跨页面数据发送
    如果你需要多个页面发送数据到同一个表单程序进行处理,或者数据在多个页面之间传输处理的话,你就可以使用ASP.NET 2.0这个新特性。例如,我打算把Default.aspx页里TextBox1里的文本数据发送到Default2.aspx页面进行处理:
    Default.aspx页:
    <%@ Page Language=C# %>
    <script runat=”server”>
    void Button2_Click(object sender, EventArgs e)
    {
    Label1.Text
    = Hi, + TextBox1.Text + . This is Default.aspx;
    }
    </script>

    <html xmlns=”http://www.w3.org/1999/xhtml” >
    <head runat=”server”>
    <title>Untitled Page</title>
    </head>
    <body>
    <form id=”form1″ runat=”server”>
    <asp:TextBox ID=”TextBox1″ Runat=”server”></asp:TextBox>
    <asp:Button ID=”Button1″ Runat=”server” Text=”PostToAnotherPage” PostBackUrl=”~/Default2.aspx” />
    <asp:Button ID=”Button2″ Runat=”server” Text=”PostToSelf” OnClick=”Button2_Click” />
    <br />
    <asp:Label ID=”Label1″ Runat=”server” Text=”Label”></asp:Label>
    </form>
    </body>
    </html>
    Default2.aspx页:
    <%@ Page Language=C# %>
    <script runat=”server”>
    void Page_Load(object sender, System.EventArgs e)
    {
    TextBox textBox1
    = (TextBox)PreviousPage.FindControl(TextBox1);
    this.Label1.Text = Hi, + textBox1.Text + . This is Default2.aspx!;
    }
    </script>
    <html xmlns=”http://www.w3.org/1999/xhtml” >
    <head runat=”server”>
    <title>Untitled Page</title>
    </head>
    <body>
    <form id=”form1″ runat=”server”>
    <asp:label id=”Label1″ runat=”server”></asp:label>
    </form>
    </body>
    </html>

《Wicket开发指南一书》在JavaEye提供PDF版本下载

经过一月的时间,在一些朋友的热心帮助下,修正了一些问题,现在发布正式的版本!
266页
希望大家喜欢Wicket这个框架!

如果大家喜欢这本书,麻烦下载后回复一下!
让我有写下去的信心和激情!

下面是简单的介绍

Wicket前生后世篇
Wicket是什么 简单点说,它就是一个基于Java的Web开发框架,与Struts,WebWork,Tapestry相类似。其特点在于对Html和代码进行了有效的分离(有利于程序员和美工的合作),基于规则的配置(减少了XML等配置文件的使用),学习曲线较低(开发方式与C/S相似),更加易于调试(错误类型比较少容易,而且容易定位)。如果你不对微软并不反感,可以把它看作Java平台上的ASP.NET。
Wicket现在是Sourceforge上一个非常活跃的项目,开发源码基于Apache协议(也是最宽松,对商业最友好的的源码协议),项目位于http://wicket.sourceforge.net,另外它还有一个独立的域名网站http://www.wicketframework.org/。最新的消息则是,Wicket已经成为Apache孵化器中一个项目,可以通过http://incubator.apache.org/projects/wicket.html来访问。但SourceForge上的网站仍然可以访问。
Wicket出现时,著名的J2EE网站TSS(即http://www.TheServerSide.com,以后简称TSS),对该项目也进行了讨论,有一段旷日持久的论战(地址:http://www.theserverside.com/news/thread.tss thread_id=28162:),论战主力当然就是Wicket的主要作者Jonathan Locke和Tapestry的作者Howard Lewis Ship ,争论的内容十分广泛,从URL的格式到系统结构,从扩展性到界面开发,如果有时间的话,我尽量将其中部分内容翻译过来,还是很精彩的。(TSS上很多的讨论都非常精彩,如果英文好的话,建议经常上去看看,国外的牛人就是多啊。有时候我也觉得很奇怪,这些人都不用睡觉的吗,看他们的帖子,完全覆盖了24小时,感觉他们的老板真是宽容啊)。
Wicket的作者中有几个是原Sun公司Swing小组的开发人员(现在可能大部分已经不是了),因此Wicket的框架中带有浓厚的C/S色彩。而他们的开发计划中,还包括了Swing,Flash平台的支持,也就是说使用Wicket不仅可以可以输出Html,而且可以支持Swing和Flash,不过和朋友经过讨论后,觉得这个计划看起来有一点不切实际,毕竟Html,Swing,Flash之间的差别还是很大,恐怕想要无缝移植,还是有点难度的。单是一个JavaScript,恐怕就够头痛了。
Wicket带有强烈C/S结构的UI色彩,这一点有助于美工和程序人员的分工,与Delphi的开发方式非常类似(Delphi使用.frm文件保存UI控件的定义,而用.pas文件存储代码,从而对控件进行操作)。Wicket则是使用Html描述UI,并将具有特殊标记的Html元素定义为UI控件,在java文件中则直接使用代码操作这些UI控件,控制其输出及行为,样式等。这一点和Tapestry,以及.NET平台上的ASP.NET极为相似,也怪不得与Tapestry的作者争论了这么久,毕竟两者的用户群有很多的重复。其实从结构上看来,无论是Tapestry,ASP.Net,Wicket估计都借鉴了Applet平台上的WebObjects,还有Delphi。(不要忘了,Delphi的创建者Anders Hejlsberg就是.net框架的架构师,所以C#和Asp.net怎么看都带着Delphi的影子。
Wicket目前最新的版本是1.2.2版,已经支持了AJAX,但感觉这个框架的发展时间毕竟还是短了一点,尽管设计思想很不错,但还是有许多问题存在的,包括控件的数量,BUG较多等,希望2006年它可以尽快的成熟起来。
关于重新发明轮子的争论
谈到Wicket,恐怕第一个感觉就是在Java的Web开发中又多了一个轮子,这一点国内外的程序员好象都是一样。
有一个国外的Blog专门写了一篇关于轮子的文章,说明了重复发明轮子的必要性。我个人对于这种轮子是持一种欢迎的态度,因为没有人会去写一段功能完全一样的东东,总是要修正了原有轮子的不足,这样就不能简单当作一种重复。
即使是功能重复,就不需要轮子了吗 JSP能完成Struts到所有功能,而Tapestry能做到的,Struts也全部可以做到,但Struts,Tapestry就不需要了吗 Struts的MVC结构比JSP更加优秀,在很大程度上减轻了开发人员开发量,而Tapestry基于组件的开发方式,则是开创了一种新的Web开发方式,对于多语言的支持也有了新的方式。以往开发多语言页面时,往往使用properties保存字符串资源,但是页面通常都没有什么变化。而Tapestry可以通过不同的Html为不同的国家指定不同的页面。
Wicket吸收了Tapestry的一部分内容,但我最喜欢的就是,它是基于规则的,而并非XML配置的方式,这不仅有利于程序员学习,对系统的维护及开发规范都很有效,毕竟XML的编写并不见得就比写一段程序来得更容易。(这里插一句题外话,我觉得XML文件用来表示数据和资源,而不是行为,更不是业务,所以对于XML我只用来存放多语言资源或者用来做数据交换。象Spring这种大量使用XML方式,我并不欣赏,Spring也意识到了这一点,在2.0版本中努力的简化Xml的配置,但是并不尽如人意)。如果使用简单的规则来配置或者管理一个系统,用户就会很容易的查找到自己需要的内容。而通过配置文件,不管这样的一个配置文件的结构如何好,也需要在其中查找自己需要的内容,开发效率肯定要低一些。
因此对于这种有创新性的轮子,多几个,或许Java世界可以跑得更快一些。
去年就听说不少Web框架的开发人员要联合起来开一个Web框架,在Yahoo上还有一个讨论组,上去看了一下。但是这个事件对我的第一感觉就是晕,第二感觉就是特别的晕,虽然目前Java世界的Web框架一通混战,但这样一个联盟,所给出的东西很可能是第二个EJB。

上周技术关注:关于AJAX框架性能的比较

  • [.NET开发, 性能] 如何最大限度提高.NET的性能 (续) >>
    现在开发的很多网络系统性能开销主要是在数据的读取,传输上,更快的读取速度,更少的网络宽带占用是我们追求的目标。我就从这方面来谈谈如何提高.net的性能。
  • [LINQ] (译作)LINQ会为我们带来什么? >>
    从编程语言的演变来讲,LINQ代表的更多的是经典的面向对象语言(C#)和现代动态语言(Ruby)以及函数式语言(Lisp)的一种融合。它非常有趣而且可能会使C#在技术上暂时领先Java。无论如何,它最终能否帮助我们开发出更高质量(更强大,更可靠以及更可维护的)的应用——这些大概是所有公司在招聘.NET程序员时的最起码要求了——最终还是要取决于:我们的C#和VB程序员是否喜欢这些概念:Lambda表达式,表达式树和宣告式编程。
  • [.NET开发] asp.net的一个bug的发现和解决 >>
    gridview中的按钮类型用如果用image,触发rowcommand事件时会被执行两次,据说只出现在IE6,IE5、firefox等没有问题,我的IE7也存在同样问题,似乎和IIS版本也有关系,期待微软的补丁。
  • [开发工具, SQL_Server] 恢复误删数据(SQL Server 2000)--Log Explorer >>
    今天不小心把客户那边的数据库中删了一千多条数据,而且之前又没有备份,真的是很郁闷,后来在网上找到一工具,用起来挺方便,让我躲过一劫。
  • [Anthem, ajax, 性能] Anthem.NET试用手记之性能优化篇 >>
    使用WebResourceCompression后,客户端加载的js脚本减少了差不多5倍,从22KB减少到仅有5KB左右。这样就是说,为你的项目加上Ajax的效果,客户端只需多加载5KB的数据量,相当于多加显示了一幅gif小图片而已!而且脚本只会在第一次浏览页面时进行加载,之后就会进行一定时间缓存。当然,asp.net ajax也有这个功能,但压缩之后体积也比Anthem.NET大十倍以上,这样Anthem.NET第一次启动页面的速度无疑比原来加快了许多!综合上面分析及优化,能采用Anthem.NET实现所需要Ajax效果的项目使用Anthem.NET绝对是明智之选
  • [ajax] 我的一些看法:关于AJAX框架的比较 >>
    其实事实往往就是这样:现在用于比较的都是非常优秀的框架,这样的框架不太会做一些无用的事情。额外的代码,额外的数据传输应该都是有其目的的,因此单独比一个非常小,几乎不可能单独出现的Scenario往往还不够。我们还需要结合一些别的比较,例如功能的比较,或者在一个庞大,完整的Scenario下,不过这个比较就非常困难了。另外,比较太小的Scenario的结论往往也会有失偏颇,例如ASP.NET AJAX在任何“小功能”的比较时都会传输“大量”的脚本,但是这真的是劣势吗?在性能上请求一次JS时传输相差十几K真的会相差无几,何况除了第一次下载之外之后就会被缓存了。而且,优化PLT(Page Load Time)的一个Best Practice就是“尽量将所有的JS都存放在一个文件内一起下载”,这可以有效地提高性能和避免出现JS错误。因为重新发起一个Request的代价比下载代码的消耗要大不少,而且如果一个文件太小,甚至小于TCP/IP的一个Package,那么更加可谓得不偿失了。
  • [ajax, Anthem, 性能] 客户端调用服务器端方法——ASP.NET AJAX(Atlas)、Anthem.NET和Ajax.NET Professional实现之小小比较 >>
    前几天曾经发过一篇《ASP.NET AJAX(Atlas)和Anthem.NET——管中窥豹般小小比较》,Jeffrey Zhao说用ASP.NET AJAX中的UpdatePanel似乎不大好。我想了想确实如此,有些高射炮打蚊子的感觉。还有朋友希望我也能在比较中关照一下Ajax.NET Professional——同样是个ASP.NET平台上非常优秀的Ajax框架。种种要求下,形成此文。本文将比较在ASP.NET AJAX(Atlas)、Anthem.NET和Ajax.NET Professional这三个知名ASP.NET上Ajax框架中实现客户端调用服务器端方法的实现。客户端调用服务器端方法是每一个Ajax框架都必须考虑的问题,非常具有代表性。在程序编写过程中,我也将抛弃掉某些框架中提供的“智能的”服务器端控件(例如ASP.NET AJAX的UpdatePanel),而完全用手工JavaScript和C#实现,力求创造出较为“公平”的比较环境。
  • [开发工具, 安全, .NET开发] 微软推出Anti-Cross Site Scripting Library V1.5 >>
    根据 ACE Team 博客,你应该升级到这个版本的五大理由是:1。更多的Encoding方法,除了HtmlEncode和UrlEncode方法外,这个版本还提供了HtmlAttributeEncode,JavaScriptEncode,VisualBasicScriptEncode,XmlEncode,XmlAttributeEncode 5个方法!2。对Partially Trusted Caller Attribute (PTCA)的支持3。大为改进的文档,例程和实用教程4。End User License Agreement (EULA)更为清晰和灵活5。升级路径极其容易,因为这个版本里仍然支持旧的命名空间
  • [WPF, Vista] 将进酒,杯莫停 >>
    正是在这种大势之下,微软才会推出WPF对整个软件生态链催熟。WPF的出现解决了三个问题:1) 更快速的开发更丰富的用户体验2) 消除用户界面差异3) 软件开发团队的协作问题
  • [计算机图书, Amazon] 亚马逊网上商店2006年读者最喜欢的计算机图书介绍 >>
    亚马逊网上商店的大名相信所有人都听过,随着2006年岁末的来临,亚马逊给出了今年一年来读者最喜欢的10本计算机图书的排行榜。说是“读者最喜欢的(Top 10 Customers’ Favorites)”,其实也应该就是销售榜吧。榜上有名的10本中,我们对一些已经耳熟能详,且国内已经发售了中文版,也自然还有一些是我们不太熟悉的。
  • [Lucene] 深入 Lucene 索引机制 >>
    Lucene 是一个基于 Java 的全文检索工具包,你可以利用它来为你的应用程序加入索引和检索功能。Lucene 目前是著名的 Apache Jakarta 家族中的一个开源项目,下面我们即将学习 Lucene 的索引机制以及它的索引文件的结构。在这篇文章中,我们首先演示如何使用 Lucene 来索引文档,接着讨论如何提高索引的性能。最后我们来分析 Lucene 的索引文件结构。需要记住的是,Lucene 不是一个完整的应用程序,而是一个信息检索包,它方便你为你的应用程序添加索引和搜索功能。
  • [系统架构, eBay] eBay 的应用服务器规模 >>
    在 2004 年的时候,eBay 的应用服务器采用了 IBM WebSphere,部署在 WinNT 上,硬件是 Intel 双 CPU 奔腾服务器。服务器数量是 2400 台。在《eBay 的数据量》中我们知道,eBay 的是集中式处理 Log 的,每天会有 2T 的 Log 数据产生,现在只会更多。这些应用服务器分成不同的组,通过一个统一的 DAL(database access layer) 逻辑层访问 135 个数据库节点。
  • [数据库技术, Oracle] 关于世界上的超大数据库 >>
    如果不区分操作系统环境,Yahoo! 力拔数据仓库一项的头筹,单个数据库数据大小接近 100T 。采用的是 Oracle 数据库,部署在 Unix 上, 存储是 EMC 的设备。这是 2005年的数据,雅虎现在每日接近 40 亿 PV,这个数据仓库现在应该远超 100T 了吧。 电信巨头 AT&T 的数据仓库屈居亚军。Amazon 的两个数据仓库也不小,数据量多达 24773 GB,是用 Oracle RAC 实现的,部署在 Linux 操作系统上。
  • [论坛] 国内论坛系统的风云变幻 >>
    现在Discuz!、Phpwind、动网在国内论坛市场可谓是三足鼎立,同时相互之间的竞争也促进了论坛系统的发展,例如AJAX功能、RSS订阅、博客系统、同其他CMS系统的整合、跨平台的支持等等。而论坛系统从早期个人或民间团队的开发也转型到了成立公司进行运营管理和专业团队的系统开发,这样论坛系统的发展提升将更加有保障,而我希望在未来论坛能够突破现有模式,朝着社会化、web2.0的方向发展,同时也希望其他web产品也借鉴以上几个论坛的模式进行开源发布。
  • [搜索技术] 一篇搜索引擎的论文 >>
    新闻搜索引擎是从指定的Web页面中按照超连接进行解析、搜索,并把搜索到的每条新闻进行索引后加入数据库。然后通过Web服务器接受客户端请求后从索引数据库中搜索出所匹配的新闻。本人在介绍搜索引擎的章节中除了详细的阐述技术核心外还结合了新闻搜索引擎的实现代码来说明,图文并茂、易于理解。
  • [长尾, 数学, 二八法则] 长尾理论的数学分析:真的彻底颠覆了二八法则? >>
    其实Chris Anderson也承认:“真正的80/20法则只是承认帕累托分布的有效性,承认某些东西卖得远比其他东西要好,这在长尾市场和传统市场中都是成立的。”所以,长尾理论彻底颠覆了二八法则是没有根据的。长尾理论不是颠覆性的概念,更多地是指导我们在丰饶经济的条件下,寻找合适的长尾市场,开拓新的销售渠道。所以Chris Anderson也重点谈到“即使有二八法则的统治,在丰饶经济环境下,我们也没有理由不去经营其它的80%产品”。或许,这就是对长尾理论最深刻的注解。
  • [长尾, 二八法则, 数学] Zipf, Power-law, Pareto – a ranking tutorial >>
    Many man made and naturally occurring phenomena, including city sizes, incomes, word frequencies, and earthquake magnitudes, are distributed according to a power-law distribution. A power-law implies that small occurrences are extremely common, whereas large instances are extremely rare. This regularity or ‘law’ is sometimes also referred to as Zipf and sometimes Pareto. To add to the confusion, the laws alternately refer to ranked and unranked distributions. Here we show that all three terms, Zipf, power-law, and Pareto, can refer to the same thing, and how to easily move from the ranked to the unranked distributions and relate their exponents.
  • [ajax, Anthem, .NET开发] ASP.NET AJAX(Atlas)和Anthem.NET——管中窥豹般小小比较 >>
    本文将分别用ASP.NET AJAX和Anthem.NET实现一个最最最最简单的Ajax应用,即:页面中一个Button一个Label,点击Button将在服务器端设置Label中的Text,当然,这一切都是以Ajax异步回送的方式进行的。并比较这两种实现方式的编写代码、生成客户端脚本大小、执行效率等。
  • [Gadget, Vista] Sidebar Gadget开发教程(4) >>
    今天继续讲Sidebar Gadget的开发。此篇将是本教程的最后一篇,因为了解了Gadget的大体情况后,接下来就需要大家自己进行练习了。只有勤于练习,而不是安心看教程,你才会积累丰富的开发经验。而且有些细节其实只需要点一下即可,不需要再详述。
  • [Gadget, Vista] Sidebar Gadget开发教程(3) >>
    就像计算机语言都会有一个入口函数一样,Sidebar Gadget在启动时也会有一个主入口,而这个主入口文件呢就是Gadget.xml。但该文件你可以存放在多个区域,即Gadget的根目录,或者Gadget的地区语言(如zh-cn, en-us等)目录。按照我的理解,Gadget应该先会找最适合地区语言目录下的Gadget.xml,其次再找根目录中gadget.xml,而一个典型的Gadget.xml文件结构如下所示
  • [网站设计] 每周一站:软件下载网站的设计(softpedia.com) >>
    总结一下,为什么网站的界面设计可以带来信赖感了?大致的优点在于:1) 大分辨率,布局简单,使用1024分辨率查看时,铺满整个浏览器。大规模的感觉。(国内使用的多还在700,770,778之类的宽度) 而只有两列,重点版面突出。 2) 疏松排列,巧妙留白,成就了流畅的视觉体验。跟那些恨不得把所有特点都摆出来挤在一起的小家子作风相反,这种宽松大度,显得气宇不凡~ 3) 背景色轻盈,避免强烈的对比。这么做的优点优雅的突出文字部分。干净而精致,一向都是很高的境界~4) 使用漂亮的视觉元素进行分区,让页面整体结构清晰,减少浏览负荷。 5) 少使用动态视觉元素
  • [Javascript, 用户体验] Web2.0 Forms 和“可降解的”Javascript >>
    那么,既要支持javascript被关闭的情况,又要有Ajax,会不会增加开发的难度呢?Jeremy Keith, DOM Scripting的作者,不这么认为,在他的书里也提到Progressive enhancement(渐进增强)的开发过程和Hijax的手段,简单地说,就是1) 首先以传统的或者说web1.0的方式设计和实现网页; 2) 在1的基础上,添加Javascript实现Ajax,优化用户互动
  • [人物, 乔布斯] 像乔布斯一样活着 >>
    “非技术出身、没有MBA文凭,甚至连大学都未毕业,除了选择创新,他还能做些什么”,《FastComany》将乔布斯的创新归为命运的选择。离开苹果后的近10年间,乔布斯和苹果就开始了双线发展,接替他的两任CEO,迈克尔·斯宾德和吉尔·阿梅里奥同样为苹果带来了一些不同的东西,Newton掌中电脑、eWorld Service、还有极具前瞻性的世界最早的数码相机产品之一QuickTake 200,没有乔布斯的苹果同样具备相当的活力和创造力。而结果就像乔布斯评价那些有创意但不成功的产品时所说,“如果那些又新又酷的产品不能够为你带来可观利润,那不是创新,只是艺术”,相比苹果的原地徘徊,乔布斯领导的Pixar却是一日千里,短短几年间就在动画电影和3D技术上确立了自己的地位。
  • [软件, IT业界] 优秀的中国软件人才和黯淡的中国软件事业 >>
    不管谁是罪魁祸首, 10年黄金时间已经过去了, 沸腾的热血已经冷却了, 信心已经荒芜了. 中国优秀的软件人才, 除了少数道德品德有问题的去做流氓软件, 坑蒙拐骗了一些钱外, 更多的有良知的软件人则在惨淡中营生. 这种惨淡未必是生活和经济收入的上的惨淡, 相比其他行业的劳苦百姓, 软件人还算收入高的, 但我相信每个软件人的心中是失落的, 是凄凉的, 是惨淡的.
  • [SEO, sitemap] Sitemaps将使用统一标准 >>
    最近传来了一个好消息,Google、微软与Yahoo已经达成协议,将使用统一的Sitemaps标准(相应官方声明:Google、Yahoo!、Live Search),从某种意义上可以说,即原来使用范围仅局限Google网站管理员工具的sitemaps,也将被其他两家搜索引擎接受。目前三大搜索引擎联合建立(或赞助 )的标准化机构官方网站为www.Sitemaps.org。
  • [网站设计] web产品设计随笔 >>
    我认为成功的产品设计很关键的一点是你要给你的网站你的服务一些特别的东西,能抓住用户的东西,可能是一种颜色一种布局,也可能是一句话,或者是制定一种规则。让用户在使用上和在情感上都产生某种习惯和依赖感,让他们在使用你产品解决问题的同时,也是在享受一种LifeStyle,那么我认为就算是成功的产品设计。
  • [长尾, 图书] 长尾理论(亚马逊畅销书榜经管类第一名) >>
    本书是自《引爆点》(TheTippingPoint)以来最重要的商业著作。克里斯 安德森在书中告诉我们,商业和文化的未来不在热门产品,不在传统需求曲线的头部,而在于过去被视为“失败者”的那些产品——也就是需求曲线中那条无穷长的尾巴。 互联网以及与其相关的无穷选择正在改变我们的世界。谁能利用这一点,明天的市场就属于谁。《长尾理论》的真正精髓就是丰饶经济学,随着无限的选择空间揭示了消费者的需求真相。

CSDN技术网摘生成。更多技术动态,请访问我的技术网摘RSS

DotNet软件开发框架

DotNet软件开发框架


以我个人的能力,没有足够的时间和资源自行开发一套完整的平台。在已有的众多开源项目中选择若干优秀的项目进行整合。“站在巨人肩膀上”是牛顿有一句名言.,同样适合我们的IT行业。

我对平台的技术架构的构想,是采用开源的ORM框架做数据持久层, Asp.net没有合适的Web层框架,就采用Asp.net的Code-behind方式编写代码,数据持久层同Web表现层之间的连接采用IOC的容器。
1、 开源框架选择:
数据持久层Nhibernate和IbatisNet这两个都是非常优秀的数据持久层,Nhibernate是优秀的Hibernate的dotNet移植版本,在开源社区具有非常高的人气,IbatisNet是Data Mapper框架,也是JAVA版的Ibatis的移植版本,在dotnet的开源社区一样是非常受欢迎的一个工具。Nhibernate用于支持非常好的面向对象的设计的模型,IbatisNet用于支持应用程序的移植(已经存在数据库,处于生产状态),这两个框架对开发人员的要求。这样就具有更大的弹性。IOC容器Spring.Net和Castle,这是两个dotnet非常优秀的IOC容器。Spring.Net同样是Java的Spring 的移植版本,目前的版本是0.6,Castle则是dotnet下出现新的IOC容器,它的功能,成熟度方面比Spring.Net好得多,框架中准备采用Castle.最后的平台的技术架构就是Nhibernate/IbatisNet + Castle + ASP.NET
2、 架构整合:
Web层的Asp.net负责数据输入输出, 响应用户事件,及输入校验的工作,Web层上如何得到Nhibernate的Session和IbatisNet的SqlMapper 本架构中的DAO,Service以及 Nhibernate的Session和IbatisNet的SqlMapper都是通过Castle进行管理,Web层如何得到Castle IOC容器的实例呢,参照文章在asp.net页面上得到Castle容器的实例 。Asp.net页面通过Service处理业务逻辑,Service负责use case逻辑, domain相关的逻辑委托给domain model去实现. Service通过DAO完成对domain model的持久化工作. Service负责数据库事务和NHibernate Session/IbatisNet SqlMapper的管理。Domain model负责表示问题域的数据,DAO使用Nhibernate/IbatisNet持久化数据以及查询. 在实现DAO时, 我们使用了Castle的Nhibernate/IbatisNet DAO Support,极大地简化了代码, 很多方法都只用简单的一行完成。这样的架构优点很明显, 层次清晰, 各层的职责也明确, 便于分层设计与开发, 结合mock和Castle的IOC, unit test也是非常容易的. 而且后台(Service, domain model and DAO)的代码不依赖于Asp.net框架,同样的代码可以在Web App也可以在WinForm上面使用,只需更换UI层。
使用的框架工具的链接
另外这里有一篇精彩文章应用系统架构设计

AjaxPro.NET框架生成高效率的Tree(Asp.net2.0)(示例代码下载)

(一). 说明

用Tree显示菜单及物品列表(从服务端获取数据)比较方便,当前显示Tree 主要有两种方式:

1. 在Tree初始化时将数据全部一次性从服务端获取,获取完数据后页面展开或收缩时就不再需要获取数据,

这样,获取完数据使用时效率比较高, 但当树节点很多时, 在每次初始化时会有较大的延迟.

2. 初始化时只加载展开的节点, 当用户需要查看某个节点下的数据时, 再去取数据, 这样, 初始化时延迟会相

对减少, 但每次单击节点时要获取数据, 页面每次都要刷新, 所以也会产生延迟.

此事例用Ajax实现第二种方式, 每次只动态加载要展开的节点数据(闭合节点不展开时,则不获取其子节点的

数据), 另外加载节点时页面不会刷新.

(二). 运行示例图

(三). AjaxPro.NET简介

首先对AjaxPro.NET作一下介绍, AjaxPro.NET是一个优秀的Ajax框架, 在实际应用中只要添加其DLL

引用并进行简单的配置,即可以非常方便的在客户端直接调用服务端方法, 来获取Tree节点.

(四).使用AjaxPro.NET预配置

1. 添加 AjaxPro.dll 文件的引用(示例代码中已经包含,直接COPY过来使用即可).

2. 在Web.config文件中添加以下配置,

1<httpHandlers>
2<addverb=POST,GETpath=ajaxpro/*.ashxtype=AjaxPro.AjaxHandlerFactory,AjaxPro/>
3 </httpHandlers>
3. 在要使用AjaxPro.NET框架的页面 *.aspx.cs 的 Page_Load事件中加如下代码:
AjaxPro.Utility.RegisterTypeForAjax(typeof(_Default));
4. 经过以上三步骤后, 只要在后台服务端的方法前面增加属性[AjaxMethod]后:
1[AjaxMethod()]//or[AjaxPro.AjaxMethod]
2publicArrayListGetSearchItems(stringstrQuery)
3{
4//生成数据源
5ArrayListitems=newArrayList();
6items.Add(King);
7items.Add(Rose);
8returnitems;
9}
10
就可以在客户端直接使用服务端方法, 非常方便, 客户端调用后台代码如下:
varreturnValue=后台代码类名.GetSearchItems(参数);

(五). 代码

1. 页面 Tree.aspx 代码:

1<%@PageLanguage=C#AutoEventWireup=trueCodeFile=Tree.aspx.csInherits=_Default%>
2
3<!DOCTYPEhtmlPUBLIC-//W3C//DTDXHTML1.0Transitional//ENhttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd>
4
5<htmlxmlns=http://www.w3.org/1999/xhtml>
6<headrunat=server>
7<title>AjaxEfficientTree</title>
8<linktype=text/csshref=css/tree.cssrel=stylesheet>
9</head>
10<body>
11<formid=form1runat=server>
12<div>
13<asp:PanelID=Panel1runat=serverHeight=424pxWidth=251px>
14<divid=CategoryTreeclass=TreeMenu></div>
15</asp:Panel>
16<scriptlanguage=jscript>
17vartree=document.getElementById(CategoryTree);
18varroot=document.createElement(li);
19root.id=li_0;
20tree.appendChild(root);
21ExpandSubCategory(0);
22functionExpandSubCategory(categoryID)
23{
24varliFather=document.getElementById(li_+categoryID);
25if(liFather.getElementsByTagName(li).length>0)
26{
27ChangeStatus(categoryID);
28return;
29}
30liFather.className=Opened;
31SwitchNode(categoryID,true);
32
33//仅获取当前节点的子Nodes
34_Default.GetSubCategory(categoryID,GetSubCategory_callback);
35}
36functionSwitchNode(CategoryID,show)
37{
38varli_father=document.getElementById(li_+CategoryID);
39if(show)
40{
41varul=document.createElement(ul);
42ul.id=ul_note_+CategoryID;
43
44varnote=document.createElement(li);
45note.className=Child;
46
47varimg=document.createElement(img);
48img.className=s;
49img.src=css/s.gif;
50
51vara=document.createElement(a);
52a.href=javascript:void(0);;
53a.innerHTML=Pleasewaiting;
54
55note.appendChild(img);
56note.appendChild(a);
57ul.appendChild(note);
58li_father.appendChild(ul);
59}
60else
61{
62varul=document.getElementById(ul_note_+CategoryID);
63if(ul)
64{
65li_father.removeChild(ul);
66}
67}
68}
69functionGetSubCategory_callback(response)
70{
71vardt=response.value.Tables[0];
72if(dt.Rows.length>0)
73{
74variCategoryID=dt.Rows[0].FatherID;
75}
76varli_father=document.getElementById(li_+iCategoryID);
77varul=document.createElement(ul);
78for(vari=0;i<dt.Rows.length;i++)
79{
80if(dt.Rows[i].IsChild==1)
81{
82varli=document.createElement(li);
83li.className=Child;
84li.id=li_+dt.Rows[i].CategoryID;
85varimg=document.createElement(img);
86img.id=dt.Rows[i].CategoryID;
87img.className=s;
88img.src=css/s.gif;
89vara=document.createElement(a);
90a.href=javascript:OpenDocument(‘+dt.Rows[i].CategoryID+‘);;
91a.innerHTML=dt.Rows[i].CategoryName;
92}
93else
94{
95varli=document.createElement(li);
96li.className=Closed;
97li.id=li_+dt.Rows[i].CategoryID;
98varimg=document.createElement(img);
99img.id=dt.Rows[i].CategoryID;
100img.className=s;
101img.src=css/s.gif;
102img.onclick=function(){ExpandSubCategory(this.id);};
103img.alt=Expand/collapse;
104vara=document.createElement(a);
105a.href=javascript:ExpandSubCategory(‘+dt.Rows[i].CategoryID+‘);;
106a.innerHTML=dt.Rows[i].CategoryName;
107}
108li.appendChild(img);
109li.appendChild(a);
110ul.appendChild(li);
111}
112li_father.appendChild(ul);
113SwitchNode(iCategoryID,false);
114}
115
116//单击叶节点时,异步从服务端获取单个节点的数据.
117functionOpenDocument(CategoryID)
118{
119_Default.GetNameByCategoryID(CategoryID,GetNameByCategoryID_callback);
120}
121
122functionGetNameByCategoryID_callback(response)
123{
124alert(response.value);
125}
126
127functionChangeStatus(CategoryID)
128{
129varli_father=document.getElementById(li_+CategoryID);
130if(li_father.className==Closed)
131{
132li_father.className=Opened;
133}
134else
135{
136li_father.className=Closed;
137}
138}
139</script>
140</div>
141</form>
142</body>
143</html>

2. 页面后台文件 Tree.aspx.cs 代码:

1usingSystem;
2usingSystem.Data;
3usingSystem.Configuration;
4usingSystem.Web;
5usingSystem.Web.Security;
6usingSystem.Web.UI;
7usingSystem.Web.UI.WebControls;
8usingSystem.Web.UI.WebControls.WebParts;
9usingSystem.Web.UI.HtmlControls;
10
11publicpartialclass_Default:System.Web.UI.Page
12{
13//此对象用于存放所有的节点数
14publicstaticDataSetdsAllNodes=newDataSet();
15
16protectedvoidPage_Load(objectsender,EventArgse)
17{
18AjaxPro.Utility.RegisterTypeForAjax(typeof(_Default));
19CreateNodes();
20}
21
22privateDataTableCreateStructure()
23{
24DataTabledt=newDataTable();
25dt.Columns.Add(newDataColumn(CategoryID,typeof(int)));
26dt.Columns.Add(newDataColumn(CategoryName,typeof(string)));
27dt.Columns.Add(newDataColumn(FatherID,typeof(string)));
28dt.Columns.Add(newDataColumn(IsChild,typeof(bool)));
29returndt;
30}
31publicvoidCreateNodes()
32{
33DataTabledt=this.CreateStructure();
34
35DataRowdrNew=dt.NewRow();
36drNew[CategoryID]=1;
37drNew[CategoryName]=物品类别;
38drNew[FatherID]=0;
39dt.Rows.Add(drNew);
40
41drNew=dt.NewRow();
42drNew[CategoryID]=2;
43drNew[CategoryName]=水果;
44drNew[FatherID]=1;
45dt.Rows.Add(drNew);
46
47drNew=dt.NewRow();
48drNew[CategoryID]=3;
49drNew[CategoryName]=工具;
50drNew[FatherID]=1;
51dt.Rows.Add(drNew);
52
53drNew=dt.NewRow();
54drNew[CategoryID]=4;
55drNew[CategoryName]=萍果;
56drNew[FatherID]=2;
57dt.Rows.Add(drNew);
58
59drNew=dt.NewRow();
60drNew[CategoryID]=5;
61drNew[CategoryName]=香蕉;
62drNew[FatherID]=2;
63dt.Rows.Add(drNew);
64
65drNew=dt.NewRow();
66drNew[CategoryID]=6;
67drNew[CategoryName]=桔子;
68drNew[FatherID]=2;
69dt.Rows.Add(drNew);
70
71drNew=dt.NewRow();
72drNew[CategoryID]=7;
73drNew[CategoryName]=萝卜;
74drNew[FatherID]=2;
75dt.Rows.Add(drNew);
76
77drNew=dt.NewRow();
78drNew[CategoryID]=8;
79drNew[CategoryName]=钢笔;
80drNew[FatherID]=3;
81dt.Rows.Add(drNew);
82
83drNew=dt.NewRow();
84drNew[CategoryID]=9;
85drNew[CategoryName]=铅笔;
86drNew[FatherID]=3;
87dt.Rows.Add(drNew);
88
89drNew=dt.NewRow();
90drNew[CategoryID]=10;
91drNew[CategoryName]=尺子;
92drNew[FatherID]=3;
93dt.Rows.Add(drNew);
94
95drNew<span s

关于语言及框架的思考

这个行业就是这样,经常会出新的东西,表示比以前进步了,很多人还没体会好现在这个语言、框架所带给我们的真正意义,就忙着学习下一个新的东西了,当然抱着玩乐的心态,尝试新的事物也没什么。

之前我有3年的ASP的经验,之后切换到VB.NET再到C#,之后因为接点私活用过VB、JAVA,后来读研,做过asp.net的兼职,主要的经历都放在.net上,也就是我切换到C#之后认识的博客园,博客园给了我成长的机会,我自己比较明显的是在博客园有这么几个阶段:

潜水期:有时间就上来看看大家的文章,但是没有在博客园开博,这个时段持续了近1年时间。

冒泡期:有好几次很想说点什么,但是由于是申请机制,也没开成博,嫌烦了,但是终于累积的小宇宙爆发了,还是开了,之后偶尔写写

参与期:这一时段也很长,主要是看首页的文章,发表一下自己的评论,比如向博主要点源码什么的(这种行为现在收敛了),自己一般是不写东西的。

融入期:每天看首页的每篇文章,一天,查看好几遍,刚开始是只看自己喜欢的文章,后来兴趣变得广泛了,首页的文章都看,技术的非技术的,由于首页文章更新很频,跟得很累,这一时段也断续持续了一年多吧

之后,由于内容太多了,后来有一段时间变成只看技术了,这时博客园也会冒出一些讲ruby,python的,偶尔也看下,讲架构设计的比较少。

现在我的情况是,如果是技术的基本不看,除了特别新颖的,点进去看一个大概,了解一下走了,对于一些非技术的话题,则选择性的看一部分质量较高的。

自己有时间也会有时间将自己的一些想说到话放到自已的博客里,之前一段时间,拼命的追求文章的数量,现在逐渐的希望能够追求质量了。

走题了,回到话题上来。

从05年接触.net到08年一直在做一些.net相关的项目和思考,之后接触了open source,一群搞ror,py,agile的人,原来这个圈子还可以这么玩,于是迷上了线下的技术聚会,由于平时看得多,什么都知道一点,我也算是圈里的人了。

先前我主要有asp,asp.net的经验,听人说ror好很久了,也就尝试起来,结果用的过程中还是很吃了苦头,后来发现,原来学习每样技术就和讨老婆一样,要看对没对上眼,看缘份的,现在觉得,ror对我而言还是挺累的,robbin fan也说rails每4个月有一次大的变动,真是够让人受的。所以我和它算是没什么缘分了,之后我又发现周围的人在说django好,我也羡慕了,心里想着,一点得找个机会狠狠的用它一把。终于有时间有精力来做点啥了,买了书,动手操家伙,发现它也不符合我的习惯。这时我发现不是py,ruby语言,框架的问题,而是之前几年的编程习惯给我的技术方法和这些语言,框架没有建立认同感和归属感。

我的一个同学说的好,在你二十五六的时候,你的人格已经基本定型的时候,你应该去国外留个学什么的,给你的人生注入一剂XXX,让你对整个世界能有一个不一样的思考的方式。

我想技术也是如此吧

在发现 ror,django都不适合我后,我又迷茫了,搞了这么多年的技术,就没一个顺心的,于是我去看了看.net下的subsonic3,又一个大变活人,好家伙下次用又得学了,我也问了一些朋友,做web开发,还是用PHP,但是我对强大的IDE以及静态语言的强类型,有非常的依赖,或许这就是我的style.

说的这么多,我也没想好用什么,具体项目具体分析,见招拆招,该用什么就用什么,但是平时还是喜欢用.net来做点事,尽量的多尝试在.net下的各种技术,对于一些重复性没有创新的,而其它语言有优势的,再选择尝试用其它语言。

很多人说微软不够开放,把人都套住了,是这样,我承认,但就这样吧,在用微软的技术的时候没感觉便捷,在用其它技术的时候才知道,妈的还不如微软呢。

另外,要用一下apple的产品,它真的用技术在改变人的生活,在做真正的创新。

最后,我想说的是一切的你的技术偏爱,是由f(x)函数作用的,你的背景,接触的人事物,在不断的修正你的f,使你对某一事件的看法和其它个体产生不同,也就是所谓的观点,最后产生的一系列的行为的集合我们称之为style.

如果今天这篇文章简单点,你只要记住style=f(x)这个函数就行了

各种javascript网站

        javascript函数大全      

        javascript函数速查

        JavaScript 对象与数组参考大全      

        JavaScript 的网站

        怎样取页面元素      

        最常用的10个javascript自定义函数

        正则表达式1

        常用正则表达式
  
        常用正则表达式      

        用正则表达式和javascript对表单进行全面验证       

        html字符集

        细说HTML元素的ID和Name属性的区别      

        span 或 div属性Display and Visibility      

        js 参考手册      

        js的三种编码

      
 escape() 方法:
采用ISO Latin字符集对指定的字符串进行编码。所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。比如,空格符对应的编码是% 20。不会被此方法编码的字符: @ * / +

encodeURI() 方法:
把URI字符串采用UTF-8编码格式转化成escape格式的字符串。不会被此方法编码的字符:! @ # $& * ( ) = : / ;   + ‘

encodeURIComponent() 方法:

把URI 字符串采用UTF-8编码格式转化成escape格式的字符串。与encodeURI()相比,这个方法将对更多的字符进行编码,比如 / 等字符。所以如果字符串里面包含了URI的几个部分的话,不能用这个方法来进行编码,否则 / 字符被编码之后URL将显示错误。不会被此方法编码的字符:! *  ( ) ‘

因此,对于中文字符串来说,如果不希望把字符串编码格式转化成UTF-8格式的(比如原页面和目标页面的charset是一致的时候),只需要使用escape。如果你的页面是GB2312或者其他的编码,而接受参数的页面是UTF-8编码的,就要采用encodeURI或者 encodeURIComponent。

另外,encodeURI/encodeURIComponent是在javascript1.5之后引进的,escape则在javascript1.0版本就有。

        JS的IE和Firefox兼容性汇编       

        CSS2.0样式表属性大全
       
        css速查手册      

        iframe的使用

使用Iframe可以在一人表格内调用一个外部文件,是非常有用的。本网站在很多页面上都使用了iframe效果。

现在我们学一下Iframe标记的使用。

Iframe标记的使用格式是:

<Iframe src=”URL” width=”x” height=”x” scrolling=”[OPTION]” frameborder=”x” name=”main”></iframe>
src:文件的路径,既可是HTML文件,也可以是文本、ASP等;
width、height:”内部框架”区域的宽与高;
scrolling:当SRC的指定的HTML文件在指定的区域不显不完时,滚动选项,如果设置为NO,则不出现滚动条;如为Auto:则自动出现滚动条;如为Yes,则显示;
FrameBorder:区域边框的宽度,为了让“内部框架“与邻近的内容相融合,常设置为0。
name:框架的名字,用来进行识别。

比如:

<Iframe src=”http://campo.3322.net” width=”250″ height=”200″ scrolling=”Auto” frameborder=”0″ name=”main”></iframe>

当你想用父框架控制内部框架时,可以使用: target=”框架的名字”来控制。

        css样式教程

        CSS单元的位置和层次-div标签

        HTML 语言教程:目录

        innerHtml用法

        跨浏览器的设置innerHTML方法

VS2005ASP.NET本地化学习笔记&感受

还记得在VS2003中,本地化特别是全局本地化文件,并没有预想当中的方便。
VS2003默认的本地化策略是页面级资源文件,但由于这种文件在 VS2003中资源管理器中的布局是跟着aspx文件的,使得维护很不方便,如果你要改一个资源,首先必须知道资源所应用到的文件,再来就是资源的名称,很多情况下,我们往往会因为资源太多,而漏掉几个需要维护的资源。出于这个原因,程序员们开始考虑使用全局资源文件(Global Resources File),但由于当时在VS2003中没有专用的设计器,且调用资源必须使用ResourceManager,使得一些初学者望而却步,无形中提高了技术门槛。

这次的VS2005则完全改变了这种局面,这在VS2005的资源管理器中最容易体现——加入了 App_GlobalResources(全局资源)和App_LocalResources(本地资源)。正因为有了这两个文件夹,你的所有页面的资源不再是跟着页面走了,任何一个页面的资源都会直接被加到App_LocalResources目录下,这样就使页面级资源文件管理变得相对简单。

值得一提的是,这次还在Tools菜单中加入了Generate Local Resource项,注意该项仅在设计视图(Design View)下可见。通过该项,你可以把一个页面中的所有控件的资源自动生成,资源会放在当前页面对应的本地资源文件中,命名是你的控件名称+’.’+属性名称,例如:有一个Label的ID为Label1,则生成的资源有Label1.Text, Label1.ToolTip,资源的值就是你生成时的Text的值和ToolTip的值,如果没有则为空。生成完成后,你会发现控件已自动与资源绑定,这可以体现在两个方面,第一,在属性编辑器(Properties)中,控件的Text和ToolTip没有了值,取而带之的是多了一个浅红色的图标,表示资源已绑定;第二就是在aspx的编码界面中,控件的标记属性中多了一个meta:resourcekey=“[资源名]”。另外,VS2005的资源编辑器也比原来VS2003的方便,不再是通用的xml编辑窗口了,有了许多资源编辑器本应该有的功能,如添加图片、添加文本文件、添加声音文件等,看来以后网上的第三方资源编辑器要没市场了。

再来看全局资源。全局资源文件不会自动被添加,但是我们可以自己建,也不会自动被绑定(否则岂不成了VS2005 AI版)。当你加完资源后,回到代码编辑界面,你会发现Resources的智能感知会把资源文件名显示出来让你选择,实在是方便,例如有个资源文件叫Res1,其中有一个String资源叫Text1,你就可以用Resources.Res1.Text1来获得它的值。看到这样的功能,再看看原来自己搭的 VS2003资源维护框架,不免觉得有些郁闷。这样做的好处很容易想到,一方面资源找起来方便,另一方面资源名不容易打错。或许你会觉得有些好笑,资源名怎么会打错,对于几十个资源来说,这或许是可笑的错误,但当资源增加到数百个甚至上千个,这种事情很容易发生。

不过,这次使用后,也发现了一些不足的地方,但是个人觉得从技术角度实现的确比较麻烦。比如,如果在使用过自动生成资源后,控件改名了,如果再次自动生成资源,VS2005会重建一个资源,而不是把原来的资源删掉,这样可能造成无用资源的堆积,特别是在多次的后期维护之后,当然可能是我要求高了点,大家不要见怪。

总的来说,我对这次的VS2005的本地化功能还是很认可的,甚至有些感慨,开发工具能做到如此方便易用,真可谓是以用户为导向,或者说以应用为导向,在这方面,中国的程序员应该好好向微软的同仁们学习。

由于时间仓促,还没有来得及看基于数据库的资源支持情况,过两天再说吧。

asp.netajax使用updatepanel进行更新后的提示

想实现这样一个简单的功能,却折腾了半天。原因是第一次使用asp.net Ajax,本来是不想使用的MS的。却想看看他的框架如何。

使用Response.write (js) 会出错。找了一些文档来看,原来要使用ScriptManager的静态方法 RegisterStartupScript 来实现调用。不知为什么实例类型没有提供这种方法。害得我花了很多的时间。

ScriptManager.RegisterStartupScript(this.UpdatePanel1, this.GetType(), “updateScript”, “alert(‘保存成功’)”, true);

看来以后有空要好好研究一下了。

Asp.net中服务端控件事件是如何触发的

Asp.net 中在客户端触发服务端事件分为两种情况:

一. WebControls中的Button 和HtmlControls中的Type为submit的HtmlInputButton

这两种按钮最终到客户端的表现形式为: < input name=”Submit1″ id=”Submit1″ type=”submit” value=”Submit”>,这是Form表单的提交按钮,点击以后会作为参数发送到服务端,参数是这样的: 控件的name属性=控件的value值,对应上面的例子就是:Submit1= Submit。 服务端会根据接收到的控件的name属性的这个key来得知是这个按钮被点击了,从而在服务端触发这个按钮的点击事件。

二. HtmlControls 中的 Type为button的HtmlInputButton 和其它所有的控件事件,比如LinkButton点击,TextBox的Change事件等等:

这些事件在客户端产生后会经过一个统一的机制发送到服务端。

1. 首先asp.net页框架会使用两个Hidden域来存放表示是哪个控件触发的事件,以及事件的参数:

< !—表示触发事件的控件,一般是这个控件的name –>

< input type=”hidden” name=”__EVENTTARGET” value=”” />

< !—表示触发事件的参数,一般是当某个控件有两个以上的事件时,用来区别是哪个事件 –>

< input type=”hidden” name=”__EVENTARGUMENT” value=”” />

2. 服务端会生成一个jscript的方法来处理所有这些事件的发送,这段代码是:

      < script language=”javascript”>

  < !–

  function __doPostBack(eventTarget, eventArgument) {

  var theform = document.WebForm2;

  theform.__EVENTTARGET.value = eventTarget;

  theform.__EVENTARGUMENT.value = eventArgument;

  theform.submit();

  }

  // –>

  < /script>

3. 每个会引发服务端事件的控件都会在响应的客户端事件中调用上面的代码: 

比如,HtmlControls 中的 Type为button的HtmlInputButton的点击事件

< !—客户端的点击事件调用__doPostBack,eventTarget 参数为’Button2’,表示是name为’Button2’控件触发的事件,eventArgument 为空,表示这个Type为button的HtmlInputButton只有一个客户端触发的服务端事件–>

< input language=”javascript” onclick=”__doPostBack(‘Button2’,”)” name=”Button2″ id=”Button2″ type=”button” value=”Button” />

又比如,TextBox控件的Change事件

< !—客户端的onchange事件调用__doPostBack,eventTarget 参数为’TextBox1’,表示是name为’TextBox1’控件触发的事件,而TextBox控件只有一个客户端触发的服务端事件TextChanged,故服务器就会去触发这个TextBox的TextChanged事件->

< input name=”TextBox1″ type=”text” id=”TextBox1″ onchange=”__doPostBack(‘TextBox1’,”)” language=”javascript” />

4. 客户端触发事件后调用__doPostBack方法,将表示触发的控件源的eventTarget 和事件参数eventArgument分别付给两个隐藏域__EVENTTARGET和__EVENTARGUMENT,然后提交Form,在服务端根据__EVENTTARGET和__EVENTARGUMENT来判断是哪个控件的什么事件触发了。