﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Welcome to 陈俊峰's ---BeetleHeaded Man Blog !-随笔分类-ASP.NET</title><link>http://www.cppblog.com/Jeff-Chen/category/1413.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 24 May 2008 00:36:46 GMT</lastBuildDate><pubDate>Sat, 24 May 2008 00:36:46 GMT</pubDate><ttl>60</ttl><item><title>IIS、ASP.NET和SQLServer的安全性问题 </title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/12/6993.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Fri, 12 May 2006 03:28:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/12/6993.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6993.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/12/6993.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6993.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6993.html</trackback:ping><description><![CDATA[
		<img height="1" src="http://www.pcbookcn.com/images/ads_200.gif" width="1" align="left" />
		<span class="main">SQL Server、Internet 信息服务器和 ASP.NET 引擎都提供了坚实可靠的安全模型，它们可以很好地在一起协同工作。为了保证用户数据和应用程序的安全，Microsoft 还为每项服务的默认设置设置了相当低的值。大多数开发人员面临的挑战是如何使用 SQL Server、IIS 和 ASP.NET 在应用程序和数据之间设置适当的信任级别，而不会留下可被别人轻易攻入的安全漏洞。由于涉及三类服务（SQL Server、IIS 和 ASP.NET），所以需要采取三个关键的步骤来确保解决方案的安全。本部分讨论一种为 Web 应用程序设置足够权限和信任级别的更常用（且可靠）的方法。 <br /><br /><a name="1"><b>定义 DotNetKB 自定义 IIS 用户帐户</b></a><br /><br />保证 Web 应用程序安全性的最安全的方法是定义一个权限有限的自定义用户，然后对 IIS 进行配置，使之能够在执行您的 Web 应用程序时能作为自定义用户运行。这是相当容易实现的，可以确保访问您的 Web 应用程序的每个访问者都只具有您希望他们具有的权限。 <br /><br />第一步是生成一个新的 Windows 用户（本例中称为 DotNetKB），为其设置一个增强型密码，然后将其添加到 Windows 来宾组 (Guest Windows Group) 中。同时，确保选中 Password never expires（密码永不过期）和 User cannot change password（用户不能更改密码）复选框。这样将生成一个权限有限的用户，在 IIS 中运行您的 Web 应用程序时，您可以将其用作标识（参见图 7）。 <br /><br /><center><img src="http://www.pcbookcn.com/img_article/2005131113612734.gif" /><br /><br />图 7：生成的权限有限的用户</center><br /><br />然后，调用 Internet 信息服务器管理员并选择承载这些网页的 Web 应用程序。在本例中，您可以选择承载前文所生成的测试页的 Web 应用程序 (DotNetKB_WebSite)。在树视图中的 Web 应用程序上单击鼠标右键，然后从上下文相关菜单中选择 Properties...（属性...）。然后选择 Directory Security（目录安全性）并单击该对话框 Anonymous access and authentication control（匿名访问和验证控制）部分中的 Edit（编辑）按钮。最后，输入自定义用户名 (DotNetKB)，取消选择 Allow IIS to control password（允许 IIS 控制密码）复选框，并输入该自定义用户帐户的密码。完成所有这些工作之后，单击 OK（确定）按钮，将这些更改保存到 IIS 配置数据库中（参见图 8）。 <br /><br /><center><img src="http://www.pcbookcn.com/img_article/2005131113613580.gif" /><br /><br />图 8：Authentication Methods（验证方法）对话框</center><br /><br />此时，IIS 将在一个权限有限的自定义帐户下运行。任何访问者访问您应用程序的网页时，都将以这个自定义用户身份运行，且只具有该自定义用户的验证权限。 <br /><br /><a name="2"><b>授权 DotNetKB 用户帐户访问 SQL Server</b></a><br /><br />然后，您需要为该自定义用户授予访问数据库 (DotNetKB) 的相应权限。为此，您可以使用 Microsoft SQL Server 企业管理器或编写一个自定义脚本，以创建一个这样的用户并授予其访问特定对象的权限。本文介绍如何使用 SQL Server 企业管理器完成此操作。 <br /><br /><b>注意：</b>尽管 Visual Studio .NET 2003 具有与 SQL Server 兼容的许多强大的集成功能，但也不允许从 Visual Studio .NET 2003 中轻松管理用户和用户权限。在大型的组织和团队中，这些高级任务通常由数据库管理员完成。 <br /><br />因此，启动 SQL Server 企业管理器之后，您可以按照以下步骤将自定义用户 (DotNetKB) 添加数据库中（参见图 9）： <br /><br />·在左侧的树视图中，展开节点以显示 DotNetKB 数据库。在我的计算机上，树视图的结构如下：Console Root | SQL Server Group | (LOCAL) (Windows NT) | Databases | DotNetKB。<br />·然后，在数据库下的 Users（用户）节点上单击鼠标右键，并选择 New Database User...（新建数据库用户...）。显示 Database User Properties - New User（数据库用户属性 - 新建用户）对话框时，从 Login name（登录名）下拉框中选择 <new>（&lt;新建&gt;）。<br />·显示 SQL Server Login Properties - New Login（SQL Server 登录属性 - 新建登录）对话框时，选择 General（常规）选项卡，并在 Name（名称）输入框中输入 DotNetKB。确保选中 Windows Authentication（Windows 验证）单选按钮，并从 Domain（域）下拉框中选择自定义用户帐户所在的计算机的名称。然后从 Database（数据库）下拉框中选择 DotNetKB。<br />·现在，选择 Databases（数据库）选项卡，在对话框顶部的列表中找到 DotNetKB 数据库并选中它。然后，确保选中对话框底部列表中的 public（公共）角色。最后，单击对话框底部的 OK（确定）按钮，保存您的更改。 <br /><br /><center><img src="http://www.pcbookcn.com/img_article/2005131113613621.gif" /><br /><br />图 9：在数据库中添加自定义用户 </center><br /><br />然后，您需要为 DotNetKB 数据库中的所有存储过程和自定义函数添加执行权限。为此，您只需为 public（公共）角色授予权限。您可以将权限授予 DotNetKB 用户，这样将使以后的登录（当这些用户获得访问 DotNetKB 的权限时）更容易执行存储过程，而不需要为每个用户添加新的权限。 <br /><br />下面是为 DotNetKB 数据库中的存储过程和函数授予执行权限的步骤： <br /><br />·突出显示树视图中 DotNetKB 数据库下的 Users（用户）节点，以显示此数据库的用户列表。找到 DotNetKB 用户并在其上双击，打开 Database Users Properties（数据库用户属性）对话框。<br />·突出显示（选中）public（公共）角色时，单击 Properties...（属性...）按钮，打开 Database Role Properties（数据库角色属性）对话框。然后单击 Permissions...（权限...）按钮，显示数据库对象和权限设置列表。<br />·选中对话框顶部 Database role（数据库角色）下拉列表中的 public（公共）角色之后，找到为此数据库定义的所有存储过程和自定义函数（可能需要展开对话框才能看到全名），并确保选中各项旁边的 EXECUTE（执行）复选框。您可能会发现某些系统对象的其他一些复选框也被选中了，请不要更改这些选项。<br />·最后，设置所有的 EXECUTE（执行）权限后，单击 OK（确定）按钮，保存更改并关闭对话框。依次单击 OK（确定）按钮，直到所有对话框均被关闭。 <br /><br />至此，您已为 IIS 创建了自定义用户，并设置了该用户在 SQL Server 中的相应权限。现在，您需要在 ASP.NET Web 项目中进行一个配置更改，确保 ASP.NET 使用同一个用户帐户执行对 SQL Server 的所有调用。 <br /><br /><a name="3"><b>设置您的 ASP.NET 应用程序以模拟 DotNetKB 用户</b></a><br /><br />为 IIS 下运行的 ASP.NET Web 应用程序生成坚实可靠的配置的最后一个步骤是：配置 ASP.NET Web 应用程序，使之能够接受来自 IIS 的 Windows 用户标识并能用于访问其他操作系统资源。为此，您只需在 web.config 根文件中输入一行代码。 <br /><br />修改后的 web.config 文件如下所示： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>&lt;configuration&gt;
  &lt;system.web&gt;
    ... 其他要素 ...
    &lt;identity impersonate="true"/&gt; &lt;!-- 假设 IIS 用户标识 --&gt;
    ... 其他要素 ...
  &lt;/system.web&gt;
&lt;/configuration&gt;</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />请注意，您只需添加 <identity>元素并将模拟特性设置为 true（真）。不必输入用户帐户或密码，因为这些信息将由 IIS 提供。也就是说，即使其他人能够读取您的配置文件，他们也无法确定使用哪些标识凭据来执行您的 Web 应用程序。 <br /><br />至此，您已生成了自定义用户，并为其设置了访问 SQL Server 和 IIS 的相应权限。在下一篇《创建 ASP.NET 测试页》中，我们来创建一些测试页，确保它能够正常工作。从这里您可以看出一切正常。<img height="1" src="http://www.pcbookcn.com/down_info.asp?id=2390" width="1" border="0" /></identity></new></span>
		<br />
		<br />
<img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-12 11:28 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/12/6993.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用VBScript和JScript编写WEB应用程序（对比分析）</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/11/6924.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Thu, 11 May 2006 03:21:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/11/6924.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6924.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/11/6924.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6924.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6924.html</trackback:ping><description><![CDATA[使用VBScript和JScript编写WEB应用程序<br /><br />我心飞扬<br /><br />写这篇文章的动机是看到了大家对VBScript和Javascript的讨论以及另一片类似的文章，觉得有必要将大家的想法加以整理:-)，并将我在工作中产生的一些心得拿出来和大家分享，希望对大家有所帮助。当然，水平有限，错误在所难免。<br /><br /><br />Active Server Pages是Microsoft Windows DNA的重要组成部分，使用ASP我们可以很容易的构造功能强大的基于Web的应用。有很多脚本编写语言可供我们进行ASP创作，如：VBScript、JavaScript、Perl 和Rexx等，你可以从几种脚本编写语言中选择一个。本文中我们讨论微软公司所提供的两种脚本编写语言： <br />VBScript<br />JScript<br /><br />首先，我想讨论的是：<br /><br />一、什么时候使用VBScript 和JScript，以及两者之间的区别<br /><br />VBScript 是Visual Basic的子集，全称是Microsoft Visual Basic Scripting Edition。如果你曾经用过Visual Basic或者是Visual Basic for Applications (VBA)，你就会觉得非常熟悉。不过它们并不完全一样，因为VBScript是特意为在WEB中进行工作而设计的。<br /><br />JScript是ECMAScript的Microsoft版本，是一组包括JScript 和JavaScript脚本编写语言的标准定义。JScript从一组编程语言如C, C++, 以及Java等之中脱离出来的。如果你以前曾经用过C或者是Java，那么JScript的结构你会觉得非常熟悉。即便你不知道这些语言也没有关系，JScript的结构一点也不难，它像C和Java一样方便而没有它们那么复杂。<br /><br />微软公司在Internet Explorer和Internet Information Server (IIS)中为它们提供了ActiveX Scripting Language（ActiveX脚本编辑语言）引擎(比如vbscript.dll、jscript.dll)。<br /><br />那么，什么时候选择何种语言？<br />我们知道，进行ASP开发无外乎要编写下列两种脚本之一：<br /><br />1)服务器脚本：<br />在ASP页面中为IIS编写服务器脚本，无论使用那种语言都没有问题。并且微软公司的Visual InterDev对它们支持的都很好。<br /><br />2)客户端脚本：<br />如果你想在浏览器脚本中使用VBScript，那么浏览器必须是Internet Explorer的某个版本。因为其他浏览器可能不支持VBScript。如果要建立一个公共Web站点，你无法预知用户使用的是什么浏览器，那么VBScript只能用于Internet Explorer这个限制就成问题了。<br />几乎所有允许编写脚本的浏览器都支持JScript。因此，如果为一个公共Web站点编写应用程序，用JScript来编写客户端脚本是很自然的选择。<br /><br />影响你做决定的其他主要因素还有：<br /><br />1、错误控制<br />在VBScript中有On Error 错误陷阱来对错误情况进行控制，如：On Error Resume Next。如果你编写的是服务器脚本，错误控制非常重要，因为脚本的运行是无人照顾的。Jscript没有这种机制。<br /><br />2、格式化<br />VBScript有这样的功能，能够轻易地把数据，数字和货币数据格式化。JScript没有这样的功能。<br /><br />3、动态执行<br />JScript一个非常有力的特性是：它允许你在你的脚本内动态地建立和执行脚本(eval()函数、execScript()方法等)。简而言之，在你的脚本中能够编写脚本。当你用DHTML进行工作时，这个特性是非常有用的，因为这样你就能够动态的操作DHTML的文档模型了。VBScript无此功能。例如，在客户端的Javascript里你可以使用类似这样的句法：<br /><br />execScript("on error resume next:object.execWB 4, 1","VBScript");<br /><br />4、面向对象<br />JScript使用的是一种基于原型的对象结构，允许你在脚本中定义对象。你能够往对象的原型中加入方法和属性，扩展内置对象和定制对象。例如：<br /><br />//自定义对象myObject<br />function myObject(){<br />    //自定义属性<br />    this.properties1=value;  //此时赋值为该属性的默认值<br />    this.properties2;<br />    ...<br />    //自定义方法<br />    this.myMethod1=Method1;<br />    this.myMethod2=Method2;<br />}<br /><br />function Method1(arg){<br />    //block;<br />}<br /><br />function Method2(arg){<br />    //block;<br />}<br /><br />尤其有用的是该对象可通过SOM传回客户端，使得ASP编程方式更象以往的C/S结构。（我近期内可能会写一篇深入讨论SOM的文章，对该方法作详细讨论）<br /><br />5、事件控制<br />用VBScript在Internet Explorer中控制事件很方便，就像在Visual Basic中一样。在VBScript中也能够建立一个隐含的事件处理程序，这只需要用对象事件结构形式来定义一项功能就行了，比如说隐式调用Button1_onclick。不过在Internet Explorer中，JScript没有这项功能（但在其他的JScript主机上支持这项功能）。<br />在Internet Explorer 中使用JScript控制事件，会要求你链接到一个对象上，而这个对象又是与事件处理程序相连的。通常，只要在鉴别事件并且有处理程序功能的对象的标签栏中指明其属性即可。如下所示： <br /><br />&lt;SCRIPT ID=clientEventHandlersJS LANGUAGE=javascript&gt;<br />&lt;!--<br /><br />function button1_onclick() {<br />    alert("button1 Clicked")<br />}<br /><br />//--&gt;<br />&lt;/SCRIPT&gt;<br />&lt;INPUT type="button" value="Button" id=button1 name=button1 LANGUAGE=javascript onclick="return button1_onclick()"&gt;<br /><br />或者使用类似下面的语法:<br />&lt;SCRIPT ID=clientEventHandlersJS LANGUAGE=javascript&gt;<br />&lt;!--<br />function window_onload() {<br />    //Block;    <br />}<br />//--&gt;<br />&lt;/SCRIPT&gt;<br />&lt;SCRIPT LANGUAGE=javascript FOR=window EVENT=onload&gt;<br />&lt;!--<br />window_onload()<br />//--&gt;<br />&lt;/SCRIPT&gt;<br /><br />值得注意的是，上例中LANGUAGE属性设置为“Javascript”。Internet Explorer对于"JScript" 和"Javascript"这两个名字都认识，但许多其他浏览器却只认识"Javascript"，不认识"JScript" 。因此，为了保险起见，如果你不能确定该网页是用Internet Explorer来浏览，就最好用"Javascript"。<br />6、数据类型<br />VBScript和JScript的数据类型差别比较大，JScript有6种数据类型：数值型、字符串型、对象型、<br />布尔型、null和undefined。VBScript虽然只有一种数据类型Variant，但其子类型比较丰富。特别<br />是其对数值类型的精细划分使得在进行精确的数值运算时显得比较放心。且配合第2条中所讲到的<br />格式化功能使数据处理更加得心应手。有关这方面的文档请参阅微软的MSDN。<br /><br />7、运算符<br />在运算符方面VBScript和JScript也有一些差别：<br />例如，VBScript增加了用于字符串连接的算术运算符“&amp;”，用于对象比较的“is”运算符等。<br />然而JScript提供了比VBScript多得多的运算符，例如递加递减运算符“++、--”、一组位运算符<br />及typeof、delete等杂项运算符等。有关此方面的信息MSDN中非常详细，在此不必复述。<br /><br />8、字符串处理<br />VBScript和Javascript的字符串处理曾经也是网友们争论的焦点，它们对字符串的处理有着本质<br />的不同，我之所以将这部分单独提出来，也是想引发网友们作一些较为详细的讨论。<br />在VBScript中字符串只是一种简单的数据类型而已，并为之提供了非常丰富的字符串处理函数，<br />例如：<br />ASC,Chr,InStr,InStrRev,Join,LCase,UCase,Left,Right,Len,LTrim,RTrim,Trim,Mid,Replace,<br />Space,String,Split,StrComp,StrReverse<br />因此有很大一部分网友认为VBScript的字符串处理功能比JScript简捷、功能强大。<br /><br />不过我不这么认为。简捷是有可能的，但谈到强大，我觉得JScript功能更为强大。在JScript中，<br />字符串不仅是一种数据类型，更是一类特殊的对象。作为对象的方法，他不仅提供了上述<br />VBScript中字符串函数的几乎所有功能，而且配合正则表达式能够提供更为强劲的功能。<br /><br />一种典型的应用就是字符串的模糊搜索，看下面这个例子：<br />我想把一篇文章中的Chen0,Chen1,chenk,Chen99等可能的拼写方法替换成JoyASP:<br /><br />var txt = myTextFile.ReadAll();<br />var re = /chenk?\d?\d?/gi;<br />txt = txt.replace(re,"JoyASP");<br /><br />这种用法在不能精确地预知被处理的字符串时显得尤其有用。熟悉Unix,C,C++,Perl的网友可能<br />对正则表达式不会陌生，关于这方面的内容请查阅相关文章。<br /><br /><br />二、在同一个网页中同时使用两种语言<br /><br />在同一个网页中可以使用不同的脚本编写语言。这样做有以下几个可能的原因： <br />A、在一个程序中充分利用各种语言的优点。 <br />B、可能所面对的现有编码是用你不熟悉的语言来编写的。例如，DTC是用JScript编写的，而<br />你熟悉的语言却是VBScript。<br />大部分情况下，你可以在同一个网页中混合几种脚本语言并且它们相互之间能够配合得很好。<br />用一种语言编写的脚本可以调用用另外一种语言编写的程序并且能够共享全局变量。不过有时<br />候还是会出现一点小问题，现在就此说明一下。 <br /><br />1、当你从VBScript中调用一个JScript函数时，注意在调用过程中要有括号，即使这项函数不<br />要求设置参数也需如此。例如，一个调用应该像这样：<br /><br />returnValue = call_JScript_Function()<br /><br />如果你忘记了加括号，那么这个函数所返回的值就不是你所希望的值，而是一个包含了函数本<br />身的VBScript无法解释的对象。<br /><br />2、服务器脚本的执行顺序<br />被&lt;% %&gt;定界符括入的命令被称为主脚本命令，主脚本命令按顺序运行，从头到尾。当然，你可<br />以在一个服务器脚本中定义一个可调用的程序（函数或者是子程序）。这样的话，如果需要就<br />可以随时调用它们。 <br />所有的主脚本命令必须用同一种语言来编写，也就是在网页前面的&lt;%@ LANGUAGE=xxxxx%&gt;指示<br />中所指明的脚本语言。因此，在一个主脚本命令中你不能把几种脚本语言混合起来。 你也许会<br />说“等一等”。在理论上，把服务器脚本放到&lt;script&gt;单元中是绝对可能的。就像下例一样： <br /><br />&lt;%Response.Write("I Love joyASP!")%&gt;<br />&lt;SCRIPT language=VBScript RUNAT=Server&gt;<br />Response.Write("I Love 我心飞扬, too.")<br />&lt;/SCRIPT&gt; <br /><br />但是，这样你就会被IIS ASP处理程序的执行顺序控制。例如，如果你建立了服务器脚本并且在<br />IIS 4.0中运行它，你会发现执行顺序可能是这样的：<br /><br />1)非缺省语言的&lt;SCRIPT&gt;单元脚本<br />2)主脚本命令<br />3)缺省语言的&lt;SCRIPT&gt;单元脚本<br /><br />以上的顺序在很大程度上依赖于ActiveX脚本语言引擎的载入顺序，同时IIS中的ASP处理程序可<br />能在将来会有所改变。因此，我不不大赞成按这种方式书写代码，建议你是只把&lt;SCRIPT&gt;单元<br />用于函数或者子程序，或是把它仅仅用于其他与执行顺序无关的编码。<br /><br />3、客户端脚本块的顺序<br />当你在客户端把几种语言混合使用时，&lt;SCRIPT&gt;块在网页中出现的顺序非常重要，有时候会影<br />响到它们是否能正常工作。看看下面这个简单的例子，它是在一个VBScript脚本中调用一个用<br />JScript编写的函数：<br /><br />&lt;SCRIPT LANGUAGE="VBScript"&gt;<br />' 调用一个JScript function<br />her = "Lucy"<br />loveher = JSfuncLoveher(her)<br />document.write("绝密情报：" &amp; loveher)<br />&lt;/SCRIPT&gt;<br /><br />&lt;SCRIPT LANGUAGE="JavaScript"&gt;<br />function JSfuncLoveher(arg){<br />return "White、飞鸟和Moslem都想泡" + her + "MM :-)";<br />}<br />&lt;/SCRIPT&gt;<br /><br /><br />它不会起任何作用。说得更明白一点，document.write()会往网页中写入一个空的字符串。为<br />什么？很简单，在处理VBScript块时，下面的Java Script &lt;SCRIPT&gt;块还没有被读出来，没有<br />进行语法分析，因此网页不能使用它。当浏览器处理网页中的脚本块时，它是从上往下进行的。 <br /><br />在这个例子中，只需要调换一下脚本块的顺序就能够解决这个问题了。不过，事实上这类问题<br />并不那么常见，在大多数情况下，&lt;SCRIPT&gt;中包含的函数和子程序只有当整个网页被全部下载<br />下来并且所有的单元都可以使用之后才能够被调用。不过，你还是要记住，网页是按照一定的<br />顺序来处理的，不同语言的&lt;SCRIPT&gt;块是分别处理的。 <br />3、区分大小写以及命名习惯 <br />JScript是严格区别大小写的：在每个JScript的关键字，每个JScript命名空间的所有部分中，<br />你可以把大写和小写字母恰当的结合起来使用。这其中包括了你使用的对象模型中所有的关键<br />字。例如，当你使用ASP Response对象时，必须正确地使用大小写字母(如Response.Write)，<br />否则JScript会坚决不予承认。同样，如果你为DHTML onclick事件编写一个处理程序，如果用<br />在Visual Basic中经常发生的随便使用大小写的形式JScript可能就不会承认。<br /><br />VBScript是不区分大写和小写字母的。在某种程度上，这种不计较大小写的疏忽甚至在你用<br />VBScript对JScript编写的单元进行访问时都没什么问题。下面例子中给出了两个脚本。第一<br />个是用JScript编写的，其中还包括了一个全局变量（ctr）和一个函数（doubleMe）。第二个<br />脚本是用VBScript编写的，它是一个按钮处理程序，它能够调用JScript函数，并且报告全局<br />变量的值。 <br /><br />&lt;SCRIPT LANGUAGE=javascript&gt;<br />var ctr;<br />function doubleMe(aNumber){<br />    if(parseInt(ctr)){<br />        ctr = ctr + 1;<br />    }<br />    else{<br />        ctr = 1;<br />    }<br />return aNumber * 2;<br />}<br />&lt;/SCRIPT&gt;<br /><br />&lt;SCRIPT LANGUAGE="vbscript"&gt;<br />Function btn1_onclick()<br />    numberToDouble = 12<br />    msgbox "The doubled number = " &amp; DOUBLEME(numberToDouble)<br />    msgbox "You have doubled the number " &amp; CTR &amp; " times."<br />End function<br />&lt;/SCRIPT&gt;<br /><br />在VBScript脚本中，很明显，我在提到doubleMe 函数和ctr变量时，没有正确使用字母的大小<br />写，但是程序依然运行良好。 这是一个好消息。而坏消息就是，在下面这些情况下你一定要注<br />意字母的大小写：如果网页中的JavaScript脚本所包含的单元只能够通过字母的大写和小写来<br />区分，例如，一个叫做Timer()的函数和一个叫做timer的全局变量等等。很不幸，尽管这种编<br />码方式不怎么好，但是有时候在你的网页中还是可能会遇到原来就存在的编码。 <br /><br />在一个函数调用中把JScript单元的名字作为一个字符串参数来使用<br /><br />如果JScript包括的单元仅仅能够用字母的大小写来区分，那么VBScript就会把它们看成一样的<br />（也就是说，不区分大写和小写）。VBScript只能看看不管大小写的区别，它们是不是一样，<br />因此它识别出的只有一个JScript单元。换一句话说，如果VBScript首先找到的是叫做Timer()<br />的函数，那么它就无法找到叫做timer的全局变量了，反之也是一样。即便你在VBScript编码中<br />十分注意的把它们做了区别结果也是一样。因为VBScript在处理这些名字的时候认为它们只有一<br />种写法。不幸的是，这里没有其它的解决方法，除非在JScript的代码中不利用这些大小写之间<br />的微小差别来区分不同的函数名称。 <br /><br />除了在某些特殊的情况下，把单元名作为参数使用这种问题并不常见。特殊情况之一是在Visual <br />InterDev 6.0中的脚本对象模型中。下面我会把它作为一个例子来使用，你可以把它看作是相同<br />情况下的处理准则。 <br /><br />Visual InterDev 6.0的脚本对象模型都是用JScript来编写的。你也可以用VBScript来编写自己<br />的编码，它能够与用VBScript区分大小写方式编写的脚本对象模型一起使用。有时候，你不能够<br />直接调用某一方法，除非你把这个方法的名称传递到一个JScript函数中，而由函数来调用这个<br />方法。 <br /><br />一个典型的例子就是警告方法，你可以用它把一个方法绑定到一个特殊的事件上。在下面这个例<br />子中，一个按钮的onmouseover事件被绑定到changecaption()事件处理程序上。 <br /><br />&lt;SCRIPT LANGUAGE="VBScript"&gt;<br />Function setAdviseMethods()<br />    Btn1.advise("onmouseover", "changecaption()")<br />End Function<br />&lt;/SCRIPT&gt; <br /><br />因为你把这些名字作为字符串传送到一个JScript函数中，所以你必须使用正确的大小写表示。<br />JScript会自动用它的区分大小写的规则来检查这些名字，如果大小写不正确，就会找不到它们。<br /><br />4、从VBScript 往JScript中传送数组<br />有时候一个VBScript程序会传送一个数组作为它的一个参数，或者作为它的返回值。你可以从JScript<br />中调用这个程序，不过必须把VBScript数组转换成为一个可用的JScript数组。你只要在JScript函数中<br />建立一个VBArray对象并且用toArray把它转换成为一个JScript数组就可以了。<br /><br />注意：JScript不支持多维数组，如果原来的VBScript数组是多维的，经过toArray的转换后它会成为一<br />个一维的JScript数组。 在下面的例子中有一个VBScript脚本，它建立了一个数组，还有一个JScript<br />脚本，它将说明如何才能获得并使用这个数组：<br /><br />&lt;SCRIPT LANGUAGE="VBSCRIPT"&gt;<br />Function makeArrayVB()<br />    ' 建立一个 VBScript 数组<br />    dim anArray(1,1)<br />    anArray(0,0) = "0,0"<br />    anArray(0,1) = "0,1"<br />    anArray(1,0) = "1,0"<br />    anArray(1,1) = "1,1"<br />    makeArrayVB = anArray<br />End Function<br /><br />&lt;SCRIPT LANGUAGE="JavaScript"&gt;<br />// 在 JScript 脚本中访问 VBScript 数组<br />function getVBArray(){<br />    var arrayObj;<br />    var jsArray;<br />    arrayObj = makeArrayVB();<br />    jsArray = VBArray(arrayObj).toArray();<br />    alert("VBScript array length = " + jsArray.length);<br />    <br />    // 显示数组的内容<br />    for(i=1;i&lt;=jsArray.length;i++){<br />       alert(jsArray[i-1]);<br />    }<br />}<br />&lt;/SCRIPT&gt;<br />不过，在目前的VBScript（4.0）中，反过来是无法做到的。也就是说你不能把一个 JavaScript 数组转换成<br />为VBScript数组。如果你非要在VBScript程序中使用JavaScript数组，你可以用下面的做法：<br />把JScript 数组转换成一种不同的结构，如转换成一个由分隔符限制的字符串等，这样VBScript 就能够使<br />用了。例如，你可以用 toString 函数把一个数组转换成一个用逗号分隔的，无限制的字符串。这样，在 <br />VBScript 中你就能够用 Split 函数把它分成不同的单元。很明显这种方法在很多时候并不管用，不过有时<br />又的确有效。<br /><br />以上罗里罗唆的写了一大堆，希望能对网友们有帮助，也希望就某些问题展开讨论。<br />最后，祝网友们 Happy Scripting!!<br /><img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6924.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-11 11:21 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/11/6924.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何把ASP编写成DLL</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6870.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Wed, 10 May 2006 06:12:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6870.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6870.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6870.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6870.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6870.html</trackback:ping><description><![CDATA[
		<strong>服务器端组件</strong>
		<br />
		<br />首先,服务器端的组件要有别于客户端的组件.客户端的组件是通过网络传输,依靠HTML来起作用.而且只能在IE上有用.但是服务器端的组件是运行在服务器端,它在服务器上执行各种操作.因此,所有的浏览器都能享用,它依靠的是服务器而不是浏览器. <br /><br />当IIS被请求执行一个ASP程序,它首先会在ASP文件中找到 ＜% %&gt;标签之间的代码,并且执行它(也可以是＜script runat=server&gt;＜/script&gt;之间的代码).如果这个ASP程序在先前被调用过,那么它就会用内存中的编译过的程序来向用户返回HTML代码,如果没有,那么它就重新编译.这里ASP就比CGI多一点速度优势,因为CGI是每一个请求都使用一个线程.这样就大大消耗了服务器的资源. <br /><br />想不想你写的程序自己就能在IIS运行!?!现在你就行了!使用VB5(当然现在是VB6了),你就能建立Dynamic Linked Libraries (DLL 文件),它能在IIS上直接运行(如果有asp文件来请求的话). <br /><br />系统和软件的要求 <br /><br />你需要一个32位的操作系统来运行ASP.当然你也得安装IIS或PWS.我们下面的程序是在Windows95+PWS+VB5的环境下开发的. <br /><br />我们开始吧 <br /><br />启动你的VB,选择ActiveX图标.这个图标可以在新建工程找到!VB会提供一个默认的工程名(project1)和类名(class1).我们会将这两个名字都改掉.在改名之前,请首先确认我们拥有Microsoft Active Server Pages Object Library,它在我们的程序非常有用.从菜单中选择"工程",然后在其中选择"引用",就会出现"引用"窗口从中选择Microsoft Active Server Pages Object Library. <br /><br />给工程和类命名 <br /><br />现在我们来根据自己的爱好来为project1和class1来命名吧!给它们命名也是很重要的,我们以后会用这个工程名和类名来创建这个组件的实例!后面详细介绍. <br /><br />如何改名,我就不想多说了! <br />我们的工程名改为Exmaple,类名为Helloword <br /><br />怎样使用工程和类 <br /><br />现在我们有了我们自己的工程(Example1)和类名(HelloWorld).以后我们就会在ASP代码中使用它们的名字来引用这个组件.在ASP中我们就这样引用,如下: <br /><br /><code>Set ObjReference = Server.CreateObject("ProjectName.ClassName") <br /></code><br />对于我们工程的引用就是: <br /><code>Set ObjReference = Server.CreateObject("Example1.HelloWorld") <br /></code>现在我们就能用ObjReference来调用我们在组件中所创建的函数,子程序.下面我们会来写一个SayHello的子程序, 我们执行它的代码如下: <br /><br /><code>＜% <br />Set ObjReference = Server.CreateObject("Example1.HelloWorld") <br />ObjReference.SayHello <br />%&gt; <br /><br /></code>为了在Helloword类中使用ASP的方法,你必须在此类中写一个OnStartPage <br />子函数.如下: <br /><br /><code>Public Sub OnStartPage(PassedScriptingContext As ScriptingContext) <br />Set MyScriptingContext = PassedScriptingContext <br />End Sub </code>现在,无论什么时候用户访问一个带有本组件的ASP文件,IIS就会把ScriptingContext传送给我们的对象请我们使用.这个ScriptingContext包括了全部的ASP方法和属性.实现上,这使得我们有能力访问所有ASP的对象.看下面的代码: <br /><br /><code>Public Sub OnStartPage(PassedScriptingContext As ScriptingContext) <br />Set MyScriptingContext = PassedScriptingContext <br />Set MyApplication = MyScriptingContext.Application <br />Set MyRequest = MyScriptingContext.Request <br />Set MyResponse = MyScriptingContext.Response <br />Set MyServer = MyScriptingContext.Server <br />Set MySession = MyScriptingContext.Session <br />End Sub <br /></code><br />以后我们就能用在VB中用MyApplication 来代替ASP中的Application,同理可以代替Request,Server.....,不过我们来是要在 OnStartPage之前来申明这些变量: <br /><br /><code>Private MyScriptingContext As ScriptingContext <br />Private MyApplication As Application <br />Private MyRequest As Request <br />Private MyResponse As Response <br />Private MyServer As Server <br />Private MySession As Session <br /><br /></code>使用ASP的对象 <br />我们的变量现在就能像标准的ASP对象来使用了!比如,我们经常在ASP中用Request.form()来收集提交表单的数据.现在我们在我们的VB中实现这个功能,代码如下: <br /><br />用ASP中实现: <br /><code>＜% <br />MyTempVariable = Request.Form("userName") <br />Response.Write ("you entered "&amp; MyTempVariable &amp; "as your user name") <br />%&gt; <br /><br /></code>在VB中实现: <br /><br /><code>MyTempVariable = MyRequest.Form("userName") <br />MyResponse.Write ("you entered "&amp; MyTempVariable &amp; "as your user name") <br /><br /></code>通过使用MyResponse来代替Response,我们能够使用所有Response的方法,当然,MyResponse这个名字可以随便来取,你甚至可以就取Response. <br /><img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6870.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-10 14:12 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6870.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP.NET热点问题解答14个（开发中经常遇到）</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6862.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Wed, 10 May 2006 03:37:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6862.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6862.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6862.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6862.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6862.html</trackback:ping><description><![CDATA[
		<p>1、ASP.NET能在那些系统中运行？ <br /><br />　　 目前，ASP.NET还只能奔跑在微软的Windows 2000、Windows XP和Windows 2003的系统中，并且需要微软Internet Information Server(IIS)的支持，微软原计划要让Windows NT4.0也支持ASP.NET，但可能微软是有些技术问题或市场考虑，还没有实现NT下的ASP.NET的支持。 <br /><br />　　 2、在一个ASPX文件中是否可以使用一种以上的语言？ <br /><br />　　 答案让你有点失望，虽然微软的提供了公共语言运行环境（CLR，Common Laguage Runtime）,实现了多种编程语言间的紧密集成，可以允许你从一个VB对象中导出C＃所需的对象来，但一个ASPX文件中只能用一种语言，正如你不能在VB.NET中使用C#的语法一样。 <br /><br />　　 3、ASPX文件的服务器端脚本支持那些语言？ <br /><br />　　 目前，ASPX文件只支持C＃、Visual Basic.NET、Jscript.NET和J#，但是你使用code—behind(代码分离)的方法创建一个独立代码文件，你就可以使用任何.NET编译器支持的语言来实现功能了。 <br /><br />　　 4、在Global.asax文件中能使用code—behind（代码分离）技术吗？ <br /><br />　　 当然可以了，例如： <br />　　 Global.asax： <br /><br />　　 和使用code—behind（代码分离）技术 <br />　　 Global.asax： <br /><br /><code>　　 MyApp.vb: <br />　　 Imports System.Web <br />　　 Imports System.Web.SessionState <br />　　 Public Class MyApp <br />　　 Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) <br />　　 Application("online_session") = 0 <br />　　 End Sub <br />　　 Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs) <br />　　 Application.Lock() <br />　　 Application("online_session") = CInt(Application("online_session")) + 1 <br />　　 Application.UnLock() <br />　　 End Sub <br />　　 Sub Session_End(ByVal sender As Object, ByVal e As EventArgs) <br />　　 Application.Lock() <br />　　 Application("online_session") = CInt(Application("online_session")) - 1 <br />　　 Application.UnLock() <br />　　 End Sub <br />　　 End Class <br /></code>　　 5、我能否看到ASPX文件在ASP.NET中生成的代码吗？ <br /><br />　　 可以看到的，当你的ASPX文件中包含命令或Web.config中声明了时，你就可以在系统目录下的Microsoft.NET\Framework\v1.0.nnnn\Temporary ASP.NET Files中找到ASPX文件在ASP.NET下生成的文件。 <br /><br />　　 6、在ASPX文件中如何注释呢？ <br /><br />　　 同ASP文件中的方法一样。 <br /><br /><br />　　 7、ASPX文件中是否可以存在一个以上服务器端 Form 标记？ <br /><br />　　 不可以 <br /><br />　　 8、我可以在Web窗体中使用自定义数据类型吗 <br /><br />　　 可以，你可以把包含自定义数据类型的DLL文件放在程序根目录下的BIN目录中，ASP.NET会在数据类型引用时，装载DLL文件的。 <br /><br />　　 9、我能在Global.asax文件中触发那些事件？ <br />　　 Application对象创建和结束时所触发的事件有 <br />　　  Application_Start <br />　　  Application_End <br />　　 Session对象创建和结束时所触发的事件有 <br />　　 • Session_Start <br />　　 • Session_End <br />　　 对程序有请求发生时触发的事件有 (按发生顺序排列) <br /><code>　　 • Application_BeginRequest <br />　　 • Application_AuthenticateRequest <br />　　 • Application_AuthorizeRequest <br />　　 • Application_ResolveRequestCache <br />　　 • Application_AcquireRequestState <br />　　 • Application_PreRequestHandlerExecute <br />　　 • Application_PostRequestHandlerExecute <br />　　 • Application_ReleaseRequestState <br />　　 • Application_UpdateRequestCache <br />　　 • Application_EndRequest <br /></code>　　 当有程序有错误发生时触发的事件有 <br />　　 • Application_Error <br />　　 • Application_Disposed <br />　　 10、Web控件是否支持样式表（CSS）呢？ <br /><br /><code>　　 Yes. All Web controls inherit a property named CssClass from the base class System.Web.UI.WebControls.WebControl. The following example defines a CSS class named Input and uses it to modify a TextBox control to display text in red 10-point Verdana type: <br /><br /></code>　　 支持，所有的Web控件都从基类System.Web.UI.WebControls.WebControl中继承了一个叫做CssClass的属性。 <br />　　 例如： <br /><br /><code>　　 ＜html&gt; <br />＜head&gt; <br />＜style&gt; <br />.Input { font: 10pt verdana; color: red; } <br />＜/style&gt; <br />＜/head&gt; <br />＜body&gt; <br />＜form runat="server"&gt; <br />＜asp:TextBox CssClass="Input" RunAt="server" /&gt; <br />＜/form&gt; <br />＜/body&gt; <br />＜/html&gt; <br /><br /></code>　　　 11、在ASPX文件中默认导入那些名称空间？ <br /><br />　　 ASPX默认导入的名称空间可以直接引用了，使用其它的名称空间就的自行导入了。 <br /><br />　　 默认名称空间 <br /><code>　　  System <br />　　  System.Collections <br />　　  System.Collections.Specialized <br />　　  System.Configuration <br />　　  System.Text <br />　　  System.Text.RegularExpressions <br />　　  System.Web <br />　　  System.Web.Caching <br />　　  System.Web.Security <br />　　  System.Web.SessionState <br />　　  System.Web.UI <br />　　  System.Web.UI.HtmlControls <br />　　  System.Web.UI.WebControls <br /></code>　　 12、我是否可以自己创建服务器控件呢？ <br /><br />　　 可以，创作您自己的 ASP.NET 服务器控件很容易。创建简单的自定义控件时，您所要做的只是定义从 System.Web.UI.Control 派生的类并重写它的 Render 方法。Render 方法采用 System.Web.UI.HtmlTextWriter 类型的参数。控件要发送到客户端的 HTML 作为字符串参数传递到 HtmlTextWriter 的 Write 方法。 <br />　　 例如： <br />服务器控件代码（简单显示字符串）：Simple.vb： <br /><code>Imports System <br />Imports System.Web <br />Imports System.Web.UI <br /><br />Namespace SimpleControlSamples <br /><br />Public Class SimpleVB : Inherits Control <br /><br />Protected Overrides Sub Render(Output As HtmlTextWriter) <br />Output.Write("＜H2&gt;欢迎使用控件开发！＜/H2&gt;") <br />End Sub <br />End Class <br />End Namespace <br />引用文件Simple.aspx： <br />＜%@ Register TagPrefix="SimpleControlSamples" Namespace="SimpleControlSamples" Assembly="SimpleControlSamplesVB" %&gt; <br /><br />＜html&gt; <br />＜body&gt; <br />＜form method="POST" action="Simple.aspx" runat=server&gt; <br />＜SimpleControlSamples:SimpleVB id="MyControl" runat=server/&gt; <br />＜/form&gt; <br />＜/body&gt; <br />＜/html&gt; <br /><br /></code>　　 13、如何在ASP.NET程序中发送邮件呢？ <br /><br />　　 在ASP.NET程序中发送邮件不再象ASP中那样需要组件的支持了，在.NET的框架基类的System.Web.Mail名称空间内包含的MailMessage和SmtpMail类可以实现这个功能。 <br />　　 例如： <br /><code>　　 Dim message As new Mail.MailMessage <br />　　 message.From = "web3@163.com" <br />　　 message.To = "web3@163.com" <br />　　 message.Subject = "测试" <br />　　 message.Body = "内容" <br />　　 Mail.SmtpMail.SmtpServer = "localhost" <br />　　 Mail.SmtpMail.Send(message) <br /><br /></code>　　 14、我将如何通过ADO.NET读取数据库中的图片并显示它呢？ <br /><br />　　 下面举一个从Microsoft SQL Server的PUB数据库读取图片并显示它的例子： <br />　　 下面举一个从Microsoft SQL Server的PUB数据库读取图片并显示它的例子： <br /><code>＜%@ Import Namespace="System.Data.SqlClient" %&gt; <br />＜%@ Import Namespace="System.Drawing" %&gt; <br />＜%@ Import Namespace="System.Drawing.Imaging" %&gt; <br />＜%@ Import Namespace="System.IO" %&gt; <br />＜script language="VB" runat="server"&gt; <br />Sub Page_load(Sender as Object, E as EventArgs) <br />dim stream as new MemoryStream <br />dim connection as SqlConnection <br />connection=new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=") <br />try <br />connection.Open() <br />dim command as SqlCommand <br />command = new SqlCommand ("select logo from pub_info where pub_id='0736'", connection) <br />dim image as byte() <br />image = command.ExecuteScalar () <br />stream.Write (image, 0, image.Length) <br />dim imgbitmap as bitmap <br />imgbitmap = new Bitmap (stream) <br />Response.ContentType = "image/gif" <br />imgbitmap.Save (Response.OutputStream, ImageFormat.Gif) <br />Finally <br />connection.Close() <br />stream.Clse() <br />End Try <br />End Sub <br />＜/script&gt; <br /></code></p>
<img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6862.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-10 11:37 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6862.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从ASP过渡到ASP.net遗留的二十大积习(我就犯了其中的一半错误)</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6861.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Wed, 10 May 2006 03:26:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6861.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6861.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6861.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6861.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6861.html</trackback:ping><description><![CDATA[
		<p style="TEXT-INDENT: 2em">在技术更新的进程中, 仍然有一些人死抱着已经过了气的东西不放. 也有一些人虽然进入到新的世界, 但仍摆脱不了陈旧的习惯. 我没有用”陋习”这个词, 因为我对这个词也非常反感. </p>
		<p style="TEXT-INDENT: 2em">新技术应该有新技术的做法, 进入ASP.NET的世界, 就应该把以往的习惯改正, 全新的进入新的世界. </p>
		<p style="TEXT-INDENT: 2em">以下列举的都是错误的做法, 请不要误以为是推荐的做法而进行推广: </p>
		<p style="TEXT-INDENT: 2em">1. 使用server side include给ASPX引入共同的页面构图. </p>
		<p style="TEXT-INDENT: 2em">在ASP.NET的机制下, 应使用ASCX(web user control)来实现. ASCX提供了更多可控制接口. 并且更重要的是, ASCX是一个类. 一个实实在在的类. 可以全面控制它. </p>
		<p style="TEXT-INDENT: 2em">2.不使用web.config </p>
		<p style="TEXT-INDENT: 2em">web.config提供了非常丰富的配置管理接口. 是一个应用程序最核心的部分. 但是很多人的web.config往往是空的. 或者就从来没有修改过. </p>
		<p style="TEXT-INDENT: 2em">3.使用Response.Write向前端输出消息 </p>
		<p style="TEXT-INDENT: 2em">ASP.NET平台下的Response和ASP的Response有很大的不同. 虽然表示同一含义, 但用法上已经大不相同. Response.Write的内容只会输出到页的最前端. 向前端输出消息的正确方法是使用PlaceHolder. </p>
		<p style="TEXT-INDENT: 2em">4.使用一系列session管理用户连接状态 </p>
		<p style="TEXT-INDENT: 2em">这种方法在ASP里被滥用. 在ASP.NET环境下, 正确的做法应该是设计一个类. 结构化地保存数据. 将对session或者cookie的访问封装起来. </p>
		<p style="TEXT-INDENT: 2em">5.使用session验证身份 </p>
		<p style="TEXT-INDENT: 2em">这几乎是通病. ASP.NET提供了一组用于用户身份验证的API. 类型是forms验证或者windows验证. 这一点quick start有一节讲解得很清楚. 可以绝大部分人还是依靠给session赋值来保持用户身份验证状态. </p>
		<p style="TEXT-INDENT: 2em">6.使用Response.Redirect重定向页 </p>
		<p style="TEXT-INDENT: 2em">这一点在必要的时候可以使用. 但不可滥用. 事实证明滥用重定向将导致逻辑上的严重混乱. 这是在以页为程序单元的时候的做法. 使用front controller模式将使用户的操作逻辑集中起来] </p>
		<p style="TEXT-INDENT: 2em">7.使用太多ASPX页 </p>
		<p style="TEXT-INDENT: 2em">ASP环境下的程序单元只有*.asp页, ASP.NET可不是这样, 还有后端的类库, ASCX等等. 应将业务逻辑分别集中在不同的单元, 而不应该一项操作使用一个ASPX. 更多时候ASPX将做为ASCX或者custom control的容器而管理页内逻辑. ASPX重用ASCX的同时, ASPX也做为统一的页构图重用. </p>
		<p style="TEXT-INDENT: 2em">8.在多个逻辑单元之间复制代码并修改相应逻辑 </p>
		<p style="TEXT-INDENT: 2em">重用. 重用. 重用. 处理此类问题的原则是不出现任何相同或相似的过程. 如果你用上面的方法, 一旦出现重大逻辑更改, 带来的结果将是灾难性的. </p>
		<p style="TEXT-INDENT: 2em">9.害怕使用DataSet. </p>
		<p style="TEXT-INDENT: 2em">很多人被DataSet吓坏了. 认为”肯定”影响性能. 但连最初的尝试都不敢. 他们总认为他们的产品一定重大, 设计上应该”慎重”. 他们往往使用ArrayList或者设计低级的类来保存集合数据. 进行艰难的数据倒入工作. </p>
		<p style="TEXT-INDENT: 2em">10.对“性能”过多注意. </p>
		<p style="TEXT-INDENT: 2em">对ASP.NET ViewState的机制特别不满. 或者总是挖空心思迫害人家. 反倒把自己弄得很累. 如果在对付ViewState的同时多注意少连几次数据库也许更文明些. </p>
		<p style="TEXT-INDENT: 2em">11.应用程序根目录很乱. </p>
		<p style="TEXT-INDENT: 2em">ASP.NET是开发项目. 不是网站. 应该把不同的资源分类放置. 例如把所有静态资源(样式表, 脚本, 图像)组织到一起. 甚至可以写一组API来管理他们. ASPX应该放在一起. ASCX应该放在一起. .*.cs呢? 应该把他们放到另外一个project里. </p>
		<p style="TEXT-INDENT: 2em">12.不厌其烦的写访问数据库的过程 </p>
		<p style="TEXT-INDENT: 2em">应该把这工作交给DataAccess Application Block. 你自己还要开关connection, 何苦呢. </p>
		<p style="TEXT-INDENT: 2em">13.自己写的东西最靠得住. </p>
		<p style="TEXT-INDENT: 2em">事实往往正好相反. 多注意使用人家写好的产品. 又不收你钱, 何苦那么爱面子呢. </p>
		<p style="TEXT-INDENT: 2em">14. 胡乱命名ASPX文件名 </p>
		<p style="TEXT-INDENT: 2em">这是最让人痛苦的了. ASPX文件名不仅需要容易识别. 还应该遵循一定规则. 因为behind每个ASPX都会有一个同名的类, 想象一下, 多难受. 另外大部分人不知道管理自己的项目的name space. 让人好像看到一本帐一样. </p>
		<p style="TEXT-INDENT: 2em">15.从来不作继承或派生 </p>
		<p style="TEXT-INDENT: 2em">一些具有相同行为的类, 应该从公共的基类派生出来. 实际意义上, 我们的ASPX应该有一个基类PageBase. 因为总有一些公共的特性需要抽象出来. </p>
		<p style="TEXT-INDENT: 2em">16.零property </p>
		<p style="TEXT-INDENT: 2em">他们的类(ASPX所对应)里只有private method. 不公开自己的任何秘密. 可以这一定是JAVA的遗老干的事. </p>
		<p style="TEXT-INDENT: 2em">17. 零ASCX </p>
		<p style="TEXT-INDENT: 2em">不用说, 他还没学会ASP.NET </p>
		<p style="TEXT-INDENT: 2em">18.使用DreamWeaver“画“ASPX </p>
		<p style="TEXT-INDENT: 2em">这批人是美工. 甚至有一些人在非常陶醉地讨论如何更好地“整合“ DreamWeaver和Visual Studio. </p>
		<p style="TEXT-INDENT: 2em">19.只熟悉System.Web.UI.WebControl和System.Data.SqlClient应该还有一些值得熟悉的类库. </p>
		<p style="TEXT-INDENT: 2em">20.零注释 </p>
		<p style="TEXT-INDENT: 2em">这些都是心里很明白的快手. 一任IDE生成的缺省注释横在那里不管. </p>
		<p style="TEXT-INDENT: 2em">21.零事件 </p>
		<p style="TEXT-INDENT: 2em">对“事件驱动“一无所知. 只知道在Page_Load()里写过程. 或者双击一个按钮写Xxx_Clock()过程. 在他们的程序里看不到event和delegate</p>
<img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-10 11:26 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP实现图片上传</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6859.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Wed, 10 May 2006 02:54:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6859.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6859.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6859.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6859.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6859.html</trackback:ping><description><![CDATA[
		<p>用ASP编写网站应用程序时间长了，难免会遇到各式各样的问题，其中关于如何上传文件到服 <br />务器恐怕是遇见最多的问题了，尤其是上传图片，比如你想要在自己的社区里面实现类似网易 <br /><a href="http://www.sogou.com/sogoupedia?query=虚拟社区" target="_blank">虚拟社区 </a>提供的“每日一星”的功能，就要提供给网友上传照片的功能。上传图片文件到服务 <br />器可以使用各种免费的文件上传组件，使用起来功能虽然很强大，但是由于很多情况下，我们 <br />只能使用免费的支持ＡＳＰ的空间或者租用别人的虚拟空间，对于第一种情况，我们根本就没 <br />有可能来使用文件上传组件；至于第二种情况，我们也要付出不少的“银子”才可以。除非你 <br />拥有自己的虚拟主机，你就可以随便的在服务器上面安装自己所需要的组件，这种情况对于大 <br />多数人来说是可望而不可及的。那我们就没有办法了吗？呵呵，答案是肯定的（当然是肯定的 <br />了，要不然我也没法写出这篇文章啊）。下面就让我们一起来使用纯ＡＳＰ代码来实现图片的 <br />上传以及保存到数据库的功能（顺便也实现显示数据库中的图片到网页上的功能）。 <br /><br /><br />　　 首先我们先来熟悉一下将要使用的对象方法。我们用来获取上一个页面传递过来的数据一 <br />般是使用Request对象。同样的，我们也可以使用Request对象来获取上传上来的文件数据，使 <br />用的方法是Request.BinaryRead()。而我们要从数据库中读出来图片的数据显示到网页上面要 <br />用到的方法是： <br />Request.BinaryWrite()。在我们得到了图片的数据，要保存到数据库中的时候，不可以直接 <br />使用Insert语句对数据库进行操作，而是要使用ADO的AppendChunk方法，同样的，读出数据库 <br />中的图片数据，要使用GetChunk方法。各个方法的具体语法如下： <br />*Request.BinaryRead语法： <br />variant=Request.BinaryRead(count) <br />参数 <br />variant <br />返回值保存着从客户端读取到数据。 <br />count <br />指明要从客户端读取的数据量大小，这个值小于或者等于使用方法Request.TotalBytes得到的 <br />数据量。 <br />*Request.BinaryWrite语法： <br />Request.BinaryWritedata <br />参数 <br />data <br />要写入到客户端浏览器中的数据包。 <br />*Request.TotalBytes语法： <br />variant=Request.TotalBytes <br />参数 <br />variant <br />返回从客户端读取到数据量的字节数。 <br />*AppendChunk语法 <br />将数据追加到大型文本、二进制数据Field或Parameter对象。 <br />object.AppendChunkData <br />参数 <br />objectField或Parameter对象 <br />Data变体型，包含追加到对象中的数据。 <br />说明 <br />使用Field或Parameter对象的AppendChunk方法可将长二进制或字符数 <br />　　 据填写到对象中。在系统内存有限的情况下，可以使用AppendChunk方法对长整型值进行 <br />部分而非全部的操作。 <br />*GetChunk语法 <br />返回大型文本或二进制数据Field对象的全部或部分内容。 <br />variable=field.GetChunk(Size) <br />返回值 <br />返回变体型。 <br />参数 <br />Size长整型表达式，等于所要检索的字节或字符数。 <br />说明 <br />　　 使用Field对象的GetChunk方法检索其部分或全部长二进制或字符数据。在系统内存有限 <br />的情况下，可使用GetChunk方法处理部分而非全部的长整型值。 <br />GetChunk调用返回的数据将赋给“变量”。如果Size大于剩余的数据，则 <br />GetChunk仅返回剩余的数据而无需用空白填充“变量”。如果字段为空，则 <br />GetChunk方法返回Null。 <br />　　 每个后续的GetChunk调用将检索从前一次GetChunk调用停止处开始的数据。但是，如果从 <br />一个字段检索数据然后在当前记录中设置或读取另一个字段的值，ADO将认为已从第一个字段 <br />中检索出数据。如果在第一个字段上再次调用GetChunk方法，ADO将把调用解释为新的GetChu <br />nk操作并从记录的起始处开始读取。如果其他Recordset对象不是首个Recordset对象的副本， <br />则访问其中的字段不会破坏GetChunk操作。 <br />如果Field对象的Attributes属性中的adFldLong位设置为True，则可以对该字段使用GetChun <br />k方法。 <br />如果在Field对象上使用Getchunk方法时没有当前记录，将产生错误3021（无当前记录）。 <br />　　 接下来，我们就要来设计我们的数据库了，作为测试我们的数据库结构如下（Access200 <br />0）： <br /><br /><br />字段名称　　　　类型　　　　描述 <br />　　 id　　　自动编号　　　主键值 <br />img OLE对象　　　用来保存图片数据　 <br /><br /><br />对于在MSSQLServer7中，对应的结构如下： <br />字段名称　　　　类型　　　　描述 <br />　　 id　　　　int(Identity)　 主键值 <br />img　　 image　　　 用来保存图片数据<br />现在开始正式编写我们的纯ＡＳＰ代码上传部分了，首先，我们有一个提供给用户的上传界面 <br />，可以让用户选择要上传的图片。代码如下 <br /><code>（upload.htm）： <br />＜html&gt; <br />＜body&gt; <br />＜center&gt; <br />＜form name="mainForm" enctype="multipart/form-data" action="process.asp" method=p <br />ost&gt; <br />　　 ＜inputtype=filename=mefile&gt;＜br&gt; <br />　　 ＜inputtype=submitname=okvalue="OK"&gt; <br />＜/form&gt; <br />＜/center&gt; <br />＜/body&gt; <br />＜/html&gt; <br /></code>注意enctype="multipart/form-data"，一定要在Form中有这个属性，否则，将无法得到上传 <br />上来的数据。接下来，我们要在process.asp中对从浏览器中获取的数据进行必要的处理，因 <br />为我们在process.asp中获取到的数据不仅仅包含了我们想要的上传上来的图片的数据，也包 <br />含了其他的无用的信息，我们需要剔除冗余数据，并将处理过的图片数据保存到数据库中，这 <br />里我们以access2000为例。具体代码如下（process.asp）： <br /><code>＜% <br />response.buffer=true <br />formsize=request.totalbytes <br />formdata=request.binaryread(formsize) <br />bncrlf=chrB(13)&amp;chrB(10) <br />divider=leftB(formdata,clng(instrb(formdata,bncrlf))-1) <br />datastart=instrb(formdata,bncrlf&amp;bncrlf)+4 <br />dataend=instrb(datastart+1,formdata,divider)-datastart <br />mydata=midb(formdata,datastart,dataend) <br />setconnGraph=server.CreateObject("ADODB.connection") <br />connGraph.ConnectionString="driver={MicrosoftAccessDriver(*.mdb)};DBQ="&amp;server.Ma <br />pPath("images.mdb")&amp;";uid=;PWD=;" <br />connGraph.Open <br />setrec=server.createobject("ADODB.recordset") <br />rec.Open"SELECT*FROM[images]whereidisnull",connGraph,1,3 <br />rec.addnew <br />rec("img").appendchunkmydata <br />rec.update <br />rec.close <br />setrec=nothing <br />setconnGraph=nothing <br />%&gt; <br /></code>好了，这下我们就把上传来的图片保存到了名为images.mdb的数据库中了，剩下的工作就是要 <br />将数据库中的图片数据显示到网页上面了。一般在ＨＴＭＬ中，显示图片都是使用＜IMG&gt;标签 <br />，也就是＜IMGSRC="图片路径"&gt;，但是我们的图片是保存到了数据库中，“图片路径”是什么 <br />呢？呵呵，其实这个SRC属性除了指定路径外，也可以这样使用哦： <br />＜IMGSRC="showimg.asp?id=xxx"&gt; <br />所以，我们所要做的就是在showimg.asp中从数据库中读出来符合条件的 <br />数据，并返回到SRC属性中就可以了，具体代码如下（showimg.asp）： <br /><code>＜% <br />setconnGraph=server.CreateObject("ADODB.connection") <br />connGraph.ConnectionString="driver={MicrosoftAccessDriver(*.mdb)};DBQ="&amp; <br />server.MapPath("images.mdb")&amp;";uid=;PWD=;" <br />connGraph.Open <br />setrec=server.createobject("ADODB.recordset") <br />strsql="selectimgfromimageswhereid="&amp;trim(request("id")) <br />rec.openstrsql,connGraph,1,1 <br />Response.ContentType="image/*" <br />Response.BinaryWriterec("img").getChunk(7500000) <br />rec.close <br />setrec=nothing <br />setconnGraph=nothing <br />%&gt; <br /></code>注意在输出到浏览器之前一定要指定Response.ContentType="image/*"， <br />以便正常显示图片。 <br />最后要注意的地方是，我的process.asp中作的处理没有考虑到第一页(upload.htm)中还有其 <br />他数据，比如＜INPUT type=tesxt name=userid&gt;等等，如果有这些项目，你的process.asp就 <br />要注意处理掉不必要的数据。 <br /></p>
<img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-10 10:54 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/10/6859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>强烈推荐：ASP.NET程序中常用的三十三种代码(下)</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6650.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Fri, 05 May 2006 10:23:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6650.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6650.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6650.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6650.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6650.html</trackback:ping><description><![CDATA[
		<strong>18.日期格式化<br /><br /></strong>　　【aspx页面内：＜%# DataBinder.Eval(Container.DataItem,"Company_Ureg_Date")%＞<br /><br />　　显示为： 2004-8-11 19:44:28<br /><br />　　我只想要：2004-8-11 】<br /><br /><code>＜%# DataBinder.Eval(Container.DataItem,"Company_Ureg_Date","{0:yyyy-M-d}")%＞</code><br />　　应该如何改？<br /><br />　　【格式化日期】<br /><br />　　取出来,一般是object((DateTime)objectFromDB).ToString("yyyy-MM-dd");<br /><br />　　【日期的验证表达式】<br /><br />　　A.以下正确的输入格式： [2004-2-29], [2004-02-29 10:29:39 pm], [2004/12/31] <br /><br /><code>^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[1-9])|(1[0-2]))\:([0-5][0-9])((\s)|(\:([0-5][0-9])\s))([AM|PM|am|pm]{2,2})))?$</code><br />　　B.以下正确的输入格式：[0001-12-31], [9999 09 30], [2002/03/03] <br /><br /><code>^\d{4}[\-\/\s]?((((0[13578])|(1[02]))[\-\/\s]?(([0-2][0-9])|(3[01])))|(((0[469])|(11))[\-\/\s]?(([0-2][0-9])|(30)))|(02[\-\/\s]?[0-2][0-9]))$ </code><br />　　【大小写转换】<br /><br /><code>HttpUtility.HtmlEncode(string);<br />HttpUtility.HtmlDecode(string)</code><br />　　<strong>19.如何设定全局变量<br /></strong><br />　　Global.asax中<br /><br />　　Application_Start()事件中<br /><br />　　添加Application[属性名] ＝ xxx;<br /><br />　　就是你的全局变量<br /><br />　　<strong>20.怎样作到HyperLinkColumn生成的连接后，点击连接，打开新窗口？</strong><br /><br />　　HyperLinkColumn有个属性Target,将器值设置成"_blank"即可.(Target="_blank")<br /><br />　　【ASPNETMENU】点击菜单项弹出新窗口<br /><br />　　在你的menuData.xml文件的菜单项中加入URLTarget="_blank"，如：<br /><br /><code>＜?xml version="1.0" encoding="GB2312"?＞<br />＜MenuData ImagesBaseURL="images/"＞ <br />＜MenuGroup＞<br />＜MenuItem Label="内参信息" URL="Infomation.aspx" ＞<br />＜MenuGroup ID="BBC"＞<br />＜MenuItem Label="公告信息" URL="Infomation.aspx" URLTarget="_blank" LeftIcon="file.gif"/＞<br />＜MenuItem Label="编制信息简报" URL="NewInfo.aspx" LeftIcon="file.gif" /＞<br />......</code><br />　　最好将你的aspnetmenu升级到1.2版<br /><br />　　<strong>21.读取DataGrid控件TextBox值<br /></strong><br /><code>foreach(DataGrid dgi in yourDataGrid.Items)<br />{<br />　TextBox tb = (TextBox)dgi.FindControl("yourTextBoxId");<br />　tb.Text....<br />}</code><br />　　<strong>23.在DataGrid中有3个模板列包含Textbox分别为 DG_ShuLiang (数量) DG_DanJian(单价) DG_JinE(金额)分别在5.6.7列，要求在录入数量及单价的时候自动算出金额即</strong>:数量*单价=金额还要求录入时限制为 数值型.我如何用客户端脚本实现这个功能?<br /><br />　　〖思归〗<br /><br /><code>＜asp:TemplateColumn HeaderText="数量"＞ <br />＜ItemTemplate＞<br />＜asp:TextBox id="ShuLiang" runat=’server’ Text=’＜%# DataBinder.Eval(Container.DataItem,"DG_ShuLiang")%＞’ <br />onkeyup="javascript:DoCal()"<br />/＞<br /><br />＜asp:RegularExpressionValidator id="revS" runat="server" ControlToValidate="ShuLiang" ErrorMessage="must be integer" ValidationExpression="^\d+$" /＞<br />＜/ItemTemplate＞<br />＜/asp:TemplateColumn＞<br /><br />＜asp:TemplateColumn HeaderText="单价"＞ <br />＜ItemTemplate＞<br />＜asp:TextBox id="DanJian" runat=’server’ Text=’＜%# DataBinder.Eval(Container.DataItem,"DG_DanJian")%＞’ <br />onkeyup="javascript:DoCal()"<br />/＞<br /><br />＜asp:RegularExpressionValidator id="revS2" runat="server" ControlToValidate="DanJian" ErrorMessage="must be numeric" ValidationExpression="^\d+(\.\d*)?$" /＞<br /><br />＜/ItemTemplate＞<br />＜/asp:TemplateColumn＞<br /><br />＜asp:TemplateColumn HeaderText="金额"＞ <br />＜ItemTemplate＞<br />＜asp:TextBox id="JinE" runat=’server’ Text=’＜%# DataBinder.Eval(Container.DataItem,"DG_JinE")%＞’ /＞<br />＜/ItemTemplate＞<br />＜/asp:TemplateColumn＞＜script language="javascript"＞<br />function DoCal()<br />{<br />　var e = event.srcElement;<br />　var row = e.parentNode.parentNode;<br />　var txts = row.all.tags("INPUT");<br />　if (!txts.length || txts.length ＜ 3)<br />　　return;<br /><br />　var q = txts[txts.length-3].value;<br />　var p = txts[txts.length-2].value;<br /><br />　if (isNaN(q) || isNaN(p))<br />　　return;<br /><br />　q = parseInt(q);<br />　p = parseFloat(p);<br /><br />　txts[txts.length-1].value = (q * p).toFixed(2);<br />}<br />＜/script＞<br /><strong><font face="Times New Roman">24.datagrid选定比较底下的行时，为什么总是刷新一下，然后就滚动到了最上面，刚才选定的行因屏幕的关系就看不到了。<br /><br /></font></strong><code>page_load <br />page.smartNavigation=true</code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>25.在Datagrid中修改数据，当点击编辑键时，数据出现在文本框中，怎么控制文本框的大小 ? <br /></strong><br /></font><code>private void DataGrid1_ItemDataBound(obj sender,DataGridItemEventArgs e)<br />{<br />　for(int i=0;i＜e.Item.Cells.Count-1;i++)<br />　　if(e.Item.ItemType==ListItemType.EditType)<br />　　{<br />　　　e.Item.Cells[i].Attributes.Add("Width", "80px")<br />　　} <br />}</code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>26.对话框<br /></strong><br /></font><code>private static string ScriptBegin = "＜script language=\"JavaScript\"＞";<br />private static string ScriptEnd = "＜/script＞";<br /><br />public static void ConfirmMessageBox(string PageTarget,string Content)<br />{<br />　string ConfirmContent="var retValue=window.confirm(’"+Content+"’);"+"if(retValue){window.location=’"+PageTarget+"’;}";<br /><br />　ConfirmContent=ScriptBegin + ConfirmContent + ScriptEnd;<br /><br />　Page ParameterPage = (Page)System.Web.HttpContext.Current.Handler;<br />　ParameterPage.RegisterStartupScript("confirm",ConfirmContent);<br />　//Response.Write(strScript);<br />}</code><br /><font face="Times New Roman">　　<strong>27. 将时间格式化：string aa=DateTime.Now.ToString("yyyy年MM月dd日");</strong><br /><br />　　1.1 取当前年月日时分秒 <br /><br /></font><code>currentTime=System.DateTime.Now;</code><br /><font face="Times New Roman">　　1.2 取当前年 <br /><br /></font><code>int 年= DateTime.Now.Year;</code><br /><font face="Times New Roman">　　1.3 取当前月 <br /><br /></font><code>int 月= DateTime.Now.Month; </code><br /><font face="Times New Roman">　　1.4 取当前日 <br /><br /></font><code>int 日= DateTime.Now.Day; </code><br /><font face="Times New Roman">　　1.5 取当前时 <br /><br /></font><code>int 时= DateTime.Now.Hour; </code><br /><font face="Times New Roman">　　1.6 取当前分 <br /><br /></font><code>int 分= DateTime.Now.Minute; </code><br /><font face="Times New Roman">　　1.7 取当前秒 <br /><br /></font><code>int 秒= DateTime.Now.Second; </code><br /><font face="Times New Roman">　　1.8 取当前毫秒 <br /><br /></font><code>int 毫秒= DateTime.Now.Millisecond; </code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>28．自定义分页代码：<br /></strong><br />　　先定义变量 ：<br /><br /></font><code>public static int pageCount; //总页面数 <br />public static int curPageIndex=1; //当前页面 </code><br /><font face="Times New Roman">　　下一页： <br /><br /></font><code>if(DataGrid1.CurrentPageIndex ＜ (DataGrid1.PageCount - 1)) <br />{ <br />　DataGrid1.CurrentPageIndex += 1; <br />　curPageIndex+=1; <br />} <br /><br />bind(); // DataGrid1数据绑定函数 </code><br /><font face="Times New Roman">　　上一页： <br /><br /></font><code>if(DataGrid1.CurrentPageIndex ＞0) <br />{ <br />　DataGrid1.CurrentPageIndex += 1; <br />　curPageIndex-=1; <br />} <br /><br />bind(); // DataGrid1数据绑定函数 </code><br /><font face="Times New Roman">　　直接页面跳转： <br /><br /></font><code>int a=int.Parse(JumpPage.Value.Trim());//JumpPage.Value.Trim()为跳转值 <br /><br />if(a＜DataGrid1.PageCount) <br />{ <br />　this.DataGrid1.CurrentPageIndex=a; <br />} <br /><br />bind(); <br /><font face="Times New Roman"><strong>29．DataGrid使用：</strong><br /><br />　　添加删除确认： <br /><br /></font><code>private void DataGrid1_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e) <br />{ <br />　foreach(DataGridItem di in this.DataGrid1.Items) <br />　{ <br />　　if(di.ItemType==ListItemType.Item||di.ItemType==ListItemType.AlternatingItem) <br />　　{ <br />　　　((LinkButton)di.Cells[8].Controls[0]).Attributes.Add("onclick","return confirm(’确认删除此项吗?’);"); <br />　　} <br />　} <br />} </code><br /><font face="Times New Roman">　　样式交替： <br /><br /></font><code>ListItemType itemType = e.Item.ItemType; <br /><br />if (itemType == ListItemType.Item ) <br />{ <br />　e.Item.Attributes["onmouseout"] = "javascript:this.style.backgroundColor=’#FFFFFF’;"; <br />　e.Item.Attributes["onmouseover"] = "javascript:this.style.backgroundColor=’#d9ece1’;cursor=’hand’;" ; <br />} <br />else if( itemType == ListItemType.AlternatingItem) <br />{ <br />　e.Item.Attributes["onmouseout"] = "javascript:this.style.backgroundColor=’#a0d7c4’;"; <br />　e.Item.Attributes["onmouseover"] = "javascript:this.style.backgroundColor=’#d9ece1’;cursor=’hand’;" ; <br />} </code><br /><font face="Times New Roman">　　添加一个编号列： <br /><br /></font><code>DataTable dt= c.ExecuteRtnTableForAccess(sqltxt); //执行sql返回的DataTable <br />DataColumn dc=dt.Columns.Add("number",System.Type.GetType("System.String")); <br /><br />for(int i=0;i＜dt.Rows.Count;i++) <br />{ <br />　dt.Rows[i]["number"]=(i+1).ToString(); <br />} <br /><br />DataGrid1.DataSource=dt; <br />DataGrid1.DataBind(); </code><br /><font face="Times New Roman">　　DataGrid1中添加一个CheckBox，页面中添加一个全选框 <br /><br /></font><code>private void CheckBox2_CheckedChanged(object sender, System.EventArgs e) <br />{ <br />　foreach(DataGridItem thisitem in DataGrid1.Items) <br />　{ <br />　　((CheckBox)thisitem.Cells[0].Controls[1]).Checked=CheckBox2.Checked; <br />　} <br />} </code><br /><font face="Times New Roman">　　将当前页面中DataGrid1显示的数据全部删除 <br /><br /></font><code>foreach(DataGridItem thisitem in DataGrid1.Items) <br />{ <br />　if(((CheckBox)thisitem.Cells[0].Controls[1]).Checked) <br />　{ <br />　　string strloginid= DataGrid1.DataKeys[thisitem.ItemIndex].ToString(); <br />　　Del (strloginid); //删除函数 <br />　} <br />} </code><br /><font face="Times New Roman">　　<strong>30．当文件在不同目录下，需要获取数据库连接字符串（如果连接字符串放在Web.config，然后在Global.asax中初始化）</strong><br /><br />　　在Application_Start中添加以下代码： <br /><br /></font><code>Application["ConnStr"]=this.Context.Request.PhysicalApplicationPath+ConfigurationSettings.<br />　　　AppSettings["ConnStr"].ToString();</code><br /><font face="Times New Roman">　　<strong>31． 变量.ToString()</strong><br /><br />　　字符型转换 转为字符串 <br /><br /></font><code>12345.ToString("n"); //生成 12,345.00 <br />12345.ToString("C"); //生成 ￥12,345.00 <br />12345.ToString("e"); //生成 1.234500e+004 <br />12345.ToString("f4"); //生成 12345.0000 <br />12345.ToString("x"); //生成 3039 (16进制) <br />12345.ToString("p"); //生成 1,234,500.00% </code><br /><font face="Times New Roman">　　<strong>32、变量.Substring(参数1,参数2);</strong><br /><br />　　截取字串的一部分，参数1为左起始位数，参数2为截取几位。 如：string s1 = str.Substring(0,2); <br /><br />　　</font><font face="Times New Roman"><strong>33．在自己的网站上登陆其他网站：(如果你的页面是通过嵌套方式的话，因为一个页面只能有一个FORM，这时可以导向另外一个页面再提交登陆信息) <br /></strong><br /></font><code>＜SCRIPT language="javascript"＞ <br />＜!-- <br />　function gook(pws) <br />　{ <br />　　frm.submit(); <br />　} <br />//--＞ <br /><br />＜/SCRIPT＞ ＜body leftMargin="0" topMargin="0" onload="javascript:gook()" marginwidth="0" marginheight="0"＞ <br />＜form name="frm" action=" http://220.194.55.68:6080/login.php?retid=7259 " method="post"＞ <br />＜tr＞ <br />＜td＞<br />＜input id="f_user" type="hidden" size="1" name="f_user" runat="server"＞<br />＜input id="f_domain" type="hidden" size="1" name="f_domain" runat="server"＞<br />＜input class="box" id="f_pass" type="hidden" size="1" name="pwshow" runat="server"＞ <br /><br />＜INPUT id="lng" type="hidden" maxLength="20" size="1" value="5" name="lng"＞<br />＜INPUT id="tem" type="hidden" size="1" value="2" name="tem"＞ <br /><br />＜/td＞ <br /><br />＜/tr＞ <br /><br />＜/form＞ </code><br /><font face="Times New Roman">　　文本框的名称必须是你要登陆的网页上的名称，如果源码不行可以用vsniffer 看看。 <br /><br />　　下面是获取用户输入的登陆信息的代码： <br /><br /></font><code>string name; <br />name=Request.QueryString["EmailName"]; <br /><br />try <br />{ <br />　int a=name.IndexOf("@",0,name.Length); <br />　f_user.Value=name.Substring(0,a); <br />　f_domain.Value=name.Substring(a+1,name.Length-(a+1)); <br />　f_pass.Value=Request.QueryString["Psw"]; <br />} <br /><br />catch <br />{ <br />　Script.Alert("错误的邮箱!"); <br />　Server.Transfer("index.aspx"); <br />}</code></code></code><img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6650.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-05 18:23 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6650.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>强烈推荐：ASP.NET程序中常用的三十三种代码(上)</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6649.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Fri, 05 May 2006 10:22:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6649.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6649.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6649.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6649.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6649.html</trackback:ping><description><![CDATA[ <strong>1. 打开新的窗口并传送参数：</strong><br /><br />　　传送参数：<br /><br /><code>response.write("＜script＞window.open(’*.aspx?id="+this.DropDownList1.SelectIndex+"&amp;id1="+...+"’)＜/script＞")</code><br />　　接收参数：<br /><br /><code>string a = Request.QueryString("id");<br />string b = Request.QueryString("id1");</code><br />　　<strong>2.为按钮添加对话框<br /></strong><br /><code>Button1.Attributes.Add("onclick","return confirm(’确认?’)");<br />button.attributes.add("onclick","if(confirm(’are you sure...?’)){return true;}else{return false;}")</code><br />　<strong>　3.删除表格选定记录<br /></strong><br /><code>int intEmpID = (int)MyDataGrid.DataKeys[e.Item.ItemIndex];<br />string deleteCmd = "DELETE from Employee where emp_id = " + intEmpID.ToString()</code><br />　　<strong>4.删除表格记录警告<br /></strong><br /><code>private void DataGrid_ItemCreated(Object sender,DataGridItemEventArgs e)<br />{<br />　switch(e.Item.ItemType)<br />　{<br />　　case ListItemType.Item :<br />　　case ListItemType.AlternatingItem :<br />　　case ListItemType.EditItem:<br />　　　TableCell myTableCell;<br />　　　myTableCell = e.Item.Cells[14];<br />　　　LinkButton myDeleteButton ;<br />　　　myDeleteButton = (LinkButton)myTableCell.Controls[0];<br />　　　myDeleteButton.Attributes.Add("onclick","return confirm(’您是否确定要删除这条信息’);");<br />　　　break;<br />　　default:<br />　　　break;<br />　}<br /><br />}</code><br />　　<strong>5.点击表格行链接另一页<br /></strong><br /><code>private void grdCustomer_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)<br />{<br />　//点击表格打开<br />　if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)<br />　　e.Item.Attributes.Add("onclick","window.open(’Default.aspx?id=" + e.Item.Cells[0].Text + "’);");<br />}</code><br />　　双击表格连接到另一页<br /><br />　　在itemDataBind事件中<br /><br /><code>if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)<br />{<br />　string OrderItemID =e.item.cells[1].Text;<br />　...<br />　e.item.Attributes.Add("ondblclick", "location.href=’../ShippedGrid.aspx?id=" + OrderItemID + "’");<br />}</code><br />　　双击表格打开新一页<br /><br /><code>if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)<br />{<br />　string OrderItemID =e.item.cells[1].Text;<br />　...<br />　e.item.Attributes.Add("ondblclick", "open(’../ShippedGrid.aspx?id=" + OrderItemID + "’)");<br />}<br /><strong><font face="Times New Roman">6.表格超连接列传递参数<br /><br /></font></strong><code>＜asp:HyperLinkColumn Target="_blank" headertext="ID号" DataTextField="id" NavigateUrl="aaa.aspx?id=’<br />　＜%# DataBinder.Eval(Container.DataItem, "数据字段1")%＞’ &amp; name=’＜%# DataBinder.Eval(Container.DataItem, "数据字段2")%＞’ /＞</code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>7.表格点击改变颜色<br /></strong><br /></font><code>if (e.Item.ItemType == ListItemType.Item ||e.Item.ItemType == ListItemType.AlternatingItem)<br />{<br />　e.Item.Attributes.Add("onclick","this.style.backgroundColor=’#99cc00’;<br />　　　 this.style.color=’buttontext’;this.style.cursor=’default’;");<br />} </code><br /><font face="Times New Roman">　　写在DataGrid的_ItemDataBound里<br /><br /></font><code>if (e.Item.ItemType == ListItemType.Item ||e.Item.ItemType == ListItemType.AlternatingItem)<br />{<br />e.Item.Attributes.Add("onmouseover","this.style.backgroundColor=’#99cc00’;<br />　　　this.style.color=’buttontext’;this.style.cursor=’default’;");<br />e.Item.Attributes.Add("onmouseout","this.style.backgroundColor=’’;this.style.color=’’;");<br />}</code><br /><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>8.关于日期格式<br /></strong><br />　　日期格式设定<br /><br /></font><code>DataFormatString="{0:yyyy-MM-dd}"</code><br /><font face="Times New Roman">　　我觉得应该在itembound事件中<br /><br /></font><code>e.items.cell["你的列"].text=DateTime.Parse(e.items.cell["你的列"].text.ToString("yyyy-MM-dd"))</code><br /><font face="Times New Roman">　</font><font face="Times New Roman"><strong>　9.获取错误信息并到指定页面<br /></strong><br />　　不要使用Response.Redirect,而应该使用Server.Transfer<br /><br />　　e.g<br /><br /></font><code>// in global.asax<br />protected void Application_Error(Object sender, EventArgs e) {<br />if (Server.GetLastError() is HttpUnhandledException)<br />Server.Transfer("MyErrorPage.aspx");<br /><br />//其余的非HttpUnhandledException异常交给ASP.NET自己处理就okay了 :)<br />}</code><br /><font face="Times New Roman">　　Redirect会导致post－back的产生从而丢失了错误信息，所以页面导向应该直接在服务器端执行，这样就可以在错误处理页面得到出错信息并进行相应的处理 <br /><br />　　</font><font face="Times New Roman"><strong>10.清空Cookie<br /></strong><br /></font><code>Cookie.Expires=[DateTime];<br />Response.Cookies("UserName").Expires = 0</code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>11.自定义异常处理<br /></strong><br /></font><code>//自定义异常处理类 <br />using System;<br />using System.Diagnostics;<br /><br />namespace MyAppException<br />{<br />　/// ＜summary＞<br />　/// 从系统异常类ApplicationException继承的应用程序异常处理类。<br />　/// 自动将异常内容记录到Windows NT/2000的应用程序日志<br />　/// ＜/summary＞<br />　public class AppException:System.ApplicationException<br />　{<br />　　public AppException()<br />　　{<br />　　　if (ApplicationConfiguration.EventLogEnabled)LogEvent("出现一个未知错误。");<br />　　}<br /><br />　public AppException(string message)<br />　{<br />　　LogEvent(message);<br />　}<br /><br />　public AppException(string message,Exception innerException)<br />　{<br />　　LogEvent(message);<br />　　if (innerException != null)<br />　　{<br />　　　LogEvent(innerException.Message);<br />　　}<br />　}<br /><br />　//日志记录类<br />　using System;<br />　using System.Configuration;<br />　using System.Diagnostics;<br />　using System.IO;<br />　using System.Text;<br />　using System.Threading;<br /><br />　namespace MyEventLog<br />　{<br />　　/// ＜summary＞<br />　　/// 事件日志记录类，提供事件日志记录支持 <br />　　/// ＜remarks＞<br />　　/// 定义了4个日志记录方法 (error, warning, info, trace) <br />　　/// ＜/remarks＞<br />　　/// ＜/summary＞<br />　　public class ApplicationLog<br />　　{<br />　　　/// ＜summary＞<br />　　　/// 将错误信息记录到Win2000/NT事件日志中<br />　　　/// ＜param name="message"＞需要记录的文本信息＜/param＞<br />　　　/// ＜/summary＞<br />　　　public static void WriteError(String message)<br />　　　{<br />　　　　WriteLog(TraceLevel.Error, message);<br />　　　}<br /><br />　　　/// ＜summary＞<br />　　　/// 将警告信息记录到Win2000/NT事件日志中<br />　　　/// ＜param name="message"＞需要记录的文本信息＜/param＞<br />　　　/// ＜/summary＞<br />　　　public static void WriteWarning(String message)<br />　　　{<br />　　　　WriteLog(TraceLevel.Warning, message);　　<br />　　　}<br /><br />　　　/// ＜summary＞<br />　　　/// 将提示信息记录到Win2000/NT事件日志中<br />　　　/// ＜param name="message"＞需要记录的文本信息＜/param＞<br />　　　/// ＜/summary＞<br />　　　public static void WriteInfo(String message)<br />　　　{<br />　　　　WriteLog(TraceLevel.Info, message);<br />　　　}<br />　　　/// ＜summary＞<br />　　　/// 将跟踪信息记录到Win2000/NT事件日志中<br />　　　/// ＜param name="message"＞需要记录的文本信息＜/param＞<br />　　　/// ＜/summary＞<br />　　　public static void WriteTrace(String message)<br />　　　{<br />　　　　WriteLog(TraceLevel.Verbose, message);<br />　　　}<br /><br />　　　/// ＜summary＞<br />　　　/// 格式化记录到事件日志的文本信息格式<br />　　　/// ＜param name="ex"＞需要格式化的异常对象＜/param＞<br />　　　/// ＜param name="catchInfo"＞异常信息标题字符串.＜/param＞<br />　　　/// ＜retvalue＞<br />　　　/// ＜para＞格式后的异常信息字符串，包括异常内容和跟踪堆栈.＜/para＞<br />　　　/// ＜/retvalue＞<br />　　　/// ＜/summary＞<br />　　　public static String FormatException(Exception ex, String catchInfo)<br />　　　{<br />　　　　StringBuilder strBuilder = new StringBuilder();<br />　　　　if (catchInfo != String.Empty)<br />　　　　{<br />　　　　　strBuilder.Append(catchInfo).Append("\r\n");<br />　　　　}<br />　　　　strBuilder.Append(ex.Message).Append("\r\n").Append(ex.StackTrace);<br />　　　　return strBuilder.ToString();<br />　　　}<br /><br />　　　/// ＜summary＞<br />　　　/// 实际事件日志写入方法<br />　　　/// ＜param name="level"＞要记录信息的级别（error,warning,info,trace).＜/param＞<br />　　　/// ＜param name="messageText"＞要记录的文本.＜/param＞<br />　　　/// ＜/summary＞<br />　　　private static void WriteLog(TraceLevel level, String messageText)<br />　　　{<br />　　　　try<br />　　　　{ <br />　　　　　EventLogEntryType LogEntryType;<br />　　　　　switch (level)<br />　　　　　{<br />　　　　　　case TraceLevel.Error:<br />　　　　　　　LogEntryType = EventLogEntryType.Error;<br />　　　　　　　break;<br />　　　　　　case TraceLevel.Warning:<br />　　　　　　　LogEntryType = EventLogEntryType.Warning;<br />　　　　　　　break;<br />　　　　　　case TraceLevel.Info:<br />　　　　　　　LogEntryType = EventLogEntryType.Information;<br />　　　　　　　break;<br />　　　　　　case TraceLevel.Verbose:<br />　　　　　　　LogEntryType = EventLogEntryType.SuccessAudit;<br />　　　　　　　break;<br />　　　　　　default:<br />　　　　　　　LogEntryType = EventLogEntryType.SuccessAudit;<br />　　　　　　　break;<br />　　　　　}<br /><br />　　　　　EventLog eventLog = new EventLog("Application", ApplicationConfiguration.EventLogMachineName, ApplicationConfiguration.EventLogSourceName );<br />　　　　　//写入事件日志<br />　　　　　eventLog.WriteEntry(messageText, LogEntryType);<br /><br />　　　　}<br />　　　catch {} //忽略任何异常<br />　　} <br />　} //class ApplicationLog<br />}<br /><font face="Times New Roman"> </font><font face="Times New Roman"><strong>12.Panel 横向滚动，纵向自动扩展<br /></strong><br /></font><code>＜asp:panel style="overflow-x:scroll;overflow-y:auto;"＞＜/asp:panel＞</code><br /><font face="Times New Roman">　　<strong>13.回车转换成Tab</strong><br /><br /></font><code>＜script language="javascript" for="document" event="onkeydown"＞<br />　if(event.keyCode==13 &amp;&amp; event.srcElement.type!=’button’ &amp;&amp; event.srcElement.type!=’submit’ &amp;&amp; 　　　　event.srcElement.type!=’reset’ &amp;&amp; event.srcElement.type!=’’&amp;&amp; event.srcElement.type!=’textarea’); <br />　　　event.keyCode=9;<br />＜/script＞<br /><br />onkeydown="if(event.keyCode==13) event.keyCode=9"<br /></code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>14.DataGrid超级连接列<br /></strong><br /></font><code>DataNavigateUrlField="字段名" DataNavigateUrlFormatString="http://xx/inc/delete.aspx?ID={0}"</code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>15.DataGrid行随鼠标变色<br /></strong><br /></font><code>private void DGzf_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)<br />{<br />　if (e.Item.ItemType!=ListItemType.Header)<br />　{<br />　　e.Item.Attributes.Add( "onmouseout","this.style.backgroundColor=\""+e.Item.Style["BACKGROUND-COLOR"]+"\"");<br />　　e.Item.Attributes.Add( "onmouseover","this.style.backgroundColor=\""+ "#EFF3F7"+"\"");<br />　}<br />}</code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>16.模板列<br /></strong><br /></font><code>＜ASP:TEMPLATECOLUMN visible="False" sortexpression="demo" headertext="ID"＞<br />＜ITEMTEMPLATE＞<br />＜ASP:LABEL text=’＜%# DataBinder.Eval(Container.DataItem, "ArticleID")%＞’ runat="server" width="80%" id="lblColumn" /＞<br />＜/ITEMTEMPLATE＞<br />＜/ASP:TEMPLATECOLUMN＞<br /><br />＜ASP:TEMPLATECOLUMN headertext="选中"＞<br />＜HEADERSTYLE wrap="False" horizontalalign="Center"＞＜/HEADERSTYLE＞<br />＜ITEMTEMPLATE＞<br />＜ASP:CHECKBOX id="chkExport" runat="server" /＞<br />＜/ITEMTEMPLATE＞<br />＜EDITITEMTEMPLATE＞<br />＜ASP:CHECKBOX id="chkExportON" runat="server" enabled="true" /＞<br />＜/EDITITEMTEMPLATE＞<br />＜/ASP:TEMPLATECOLUMN＞</code><br /><font face="Times New Roman">　　后台代码<br /><br /></font><code>protected void CheckAll_CheckedChanged(object sender, System.EventArgs e)<br />{<br />　//改变列的选定，实现全选或全不选。<br />　CheckBox chkExport ;<br />　if( CheckAll.Checked)<br />　{<br />　　foreach(DataGridItem oDataGridItem in MyDataGrid.Items)<br />　　{<br />　　　chkExport = (CheckBox)oDataGridItem.FindControl("chkExport");<br />　　　chkExport.Checked = true;<br />　　}<br />　}<br />　else<br />　{<br />　　foreach(DataGridItem oDataGridItem in MyDataGrid.Items)<br />　　{<br />　　　chkExport = (CheckBox)oDataGridItem.FindControl("chkExport");<br />　　　chkExport.Checked = false;<br />　　}<br />　}<br />}</code><br /><font face="Times New Roman">　　</font><font face="Times New Roman"><strong>17.数字格式化<br /></strong><br />　　【＜%#Container.DataItem("price")%＞的结果是500.0000，怎样格式化为500.00?】<br /><br /></font><code>＜%#Container.DataItem("price","{0:￥#,##0.00}")%＞<br /><br />int i=123456;<br />string s=i.ToString("###,###.00");</code></code></code><img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6649.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-05 18:22 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6649.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP.NET中弹出窗口技术</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6648.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Fri, 05 May 2006 10:20:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6648.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6648.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6648.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6648.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6648.html</trackback:ping><description><![CDATA[摘要：本文讨论如何以ASP.NET中的CodeBehind方式实现各种弹出窗口，实现与弹出窗口的交互。并探讨常用非标准IE浏览器对弹出的窗口的各种过滤行为及使用弹出窗口相应对策，以期给出使用弹出窗口的一个通用较优方案。 
<p>　　关键词：ASP.NET、CodeBehind、过滤、COM接口、JavaScript、绑定</p><p>　　作为Microsoft的最新建立动态Web网站的工具，ASP.NET相对于ASP和JSP在改变原始的Web编程方式方面有了长足的长进。它的代码与页面分离技术（CodeBehind）以及完善的Web服务器控件为程序员提供了一个更加符合传统编程的Web服务器端开发方式。但Web编程还是有着与传统编程不相同的特点，这些特点决定了ASP.NET编程中必须以一些特殊的技巧来完成程序要求，弹出窗口正是这类编程方式的代表。相当多的编程书籍对弹出窗口采取缄默或者一语带过，似乎看不过弹出窗口的巨大使用天地。本文将为你解开弹出窗口使用中的大多数问题。</p><p>　　为了提高网站的访问的并发度和吞吐量，与其它服务器脚本一样，ASP.NET同样使用了客户端脚本来减轻服务器的压力。ASP.NET到现在(1.1版)为止并不直接支持弹出窗口，必须通过JavaScript（或VBScript）来使用客户端弹出窗口。</p><p>　　一、 警告窗口与在CodeBehind中使用客户端脚本的方式</p><p>　　要在浏览器中弹出一个最简单的警告窗口，可以使用JavaScript语句：</p><p>window.alert( [sMessage]) </p><p>　　其中，sMessage是提示信息。可惜，这样的弹出窗口是只有一个“确定”按钮，只能起到提示作用。如果我们要在删除记录时候弹出一个询问的弹出窗口，此时你需要使用：</p><p>bConfirmed = window.confirm( [sMessage])</p><p>　　其中：bConfirmed是返回值，sMessage是提示信息。这个弹出窗口有两种选择：“确定”或“放弃”，其选择的返回值放在bConfirmed中，可供代码作出判断。</p><p>　　为了提高代码的可重用性与可读性，应当使JavaScript与Codehind相互溶合。通常有两种方式可以达到这样的效果。</p><p>　　（1） 使用Response.Write方法：</p><p>　　使用Response.Write方法早在ASP时代就已经被支持了。它可以把代码写到客户端，是一种相当方便且直观的方法。以下代码演示了如何使用Response.Write方法来显示一个警告信息。</p><p>Private Sub btAlert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btAlert.Click<br />　’演示Response.Write方法和alert窗口。<br />　Response.Write(" ")<br />End Sub </p><p>　　（2） 使用RegisterXXX方法</p><p>　　如果你观察Response.Write的生成HTML代码，你会发现Response.Write方法生成的代码是写到了HTML代码的最开始，即标签之前。此时，所有的 HTML对象都还没有生成，如果要想使用HTML内的对象，并与之交互，就会出现“找不到对象”的错误。因此，笔者推荐一个更加符合CodeBehind方式的方式----使用RegisterXXX方法。RegisterXXX包括：RegisterClientScriptBlock、RegisterStartupScript以及用于判断的IsStartupScriptRegistered函数。</p><p>　　RegisterStartupScript 的原型是：</p><p>Overridable Public Sub RegisterStartupScript( _<br />　ByVal key As String, _<br />　ByVal script As String _<br />) </p><p>　　其中：key表示这个脚本的唯一标识，script是代表脚本的字符串。</p><p>　　RegisterClientScriptBlock的原型与RegisterStartupScript相同，两个函数不同在于将其包含的脚本代码写入到HTML文件的不同位置。RegisterClientScriptBlock在 Page 对象的 元素的开始标记后立即发出客户端脚本，RegisterStartupScript则是在Page 对象的 元素的结束标记之前发出该脚本。如果你的脚本有与页面对象(doucument对象)进行交互的语句（这在我们后面的例子中看到），则推荐使用RegisterStartupScript，反之如果要想客户端脚本尽可能早的执行，则可以使用RegisterClientScriptBlock或Response.Write。</p><p>　　为了防止在页面中反复加入脚本，在注册脚本时ReisterStartupScript/RegisterClientScriptBlock使用了key作为注册的Key，然后在程序中可以使用IsClientScriptBlockRegistered作判断。</p><p>　　以下例子将使用RegisterClientScriptBlock来演示confirm的使用方法。</p><p>Private Sub btConfirm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btConfirm.Click</p><p>　’演示RegisterClientScriptBlock方法和confirm窗口</p><p>　If (Not IsClientScriptBlockRegistered("clientScript")) Then<br />　‘判断是否已经加入了该脚本，没有则加入。<br />　　Dim strScript As String <br />　　strScript = " "<br />　‘注册脚本 <br />　　RegisterClientScriptBlock("clientScript", strScript)<br />　‘如果选择”否”，则继续向下执行。<br />　End If</p><p>End Sub </p><p>　　二、 弹出指定页面</p><p>　　光有提示窗口还远远不能满足我们的要求，在程序中，我们常常需要弹出指定页面。此时可以使用JavaScript的window.open方法。配合前面的RegisterClientSciptBlock方法，我们就可以实现指定页面的弹出。</p><p>　　以下代码展示了如何弹出指定页面:</p><p>Private Sub btWinOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btWinOpen.Click</p><p>　’使用window.open与registerStartupScript简单演示。</p><p>　If (Not IsClientScriptBlockRegistered("OpenScript")) Then<br />　　’判断是否已经加入了该脚本，没有则加入。<br />　　Dim strScript As String = " "<br />　　RegisterStartupScript("OpenScript", strScript)<br />　End If<br />End Sub </p><p>　　程序使用Window.open方法来弹出新的页面，它只一个参数：新的弹出窗口的URL地址。事实在window.open方法有多个参数，但这是javascipt的简单内容，我们将不会在这儿详细分说。如果你有相关的问题，请查询MSDN。</p><p>　　这段程序在IE中直接使用一切正常。但如果你正在使用类如GoSurf、MyIE2、NetCapter之类的浏览器，那么，很不幸！ 你将看不到弹出窗口。这就是我们将要讨论的弹出窗口过滤问题。</p><p>　　三、 非标准IE浏览器对弹出窗口的过滤行为讨论</p><p>　　广告窗口的泛滥使得不少网民不堪铺天盖地的广告骚扰纷纷放弃标准IE浏览器而使用诸如GoSurf、MyIE2、NetCapter这样的使用IE内核支持多页面并能自动屏蔽广告的软件。据说在即将发布的IE6 sp2中微软也将加入封杀广告窗口功能。这对大多数网民当然是件好事，可对于程序员而言，我们使用弹出窗口的方式与一般广告并无本质的不同，这样的窗口也会被弹出窗口管理器不分青红皂白的封杀，其结果当然是我们不愿看到的。有没有一个标准的方式能让窗口正常的弹出呢？这就要求我们了解浏览器封杀广告的原理。通常的广告封杀器使用以下三种方式进行广告过滤：</p><p>　　（1）、基于窗口标题的封杀方式</p><p>　　这种封杀方式的原理是定时检查所有的IE窗口标题,然后于已经有的列表（由程序维护的一个数组列表）来比较,如果有相同的,我们就关闭这个窗口。显然，这种方式有着诸多缺陷，它封杀了所有的弹出的窗口，管得太死，在程序真正使用的很少。不过，依据它进行的变形方式倒使用得相当的普遍。那就是，基于窗口标题名称的智能过滤技术，它根据弹出窗口的标题是否含有关于广告的关键字进行封杀，这为提高过滤效果作出了很好的探索。</p><p>　　（2）、基于窗口类和位置的封杀方式</p><p>　　经过分析发现正常浏览窗口的类名是IEFRAME和CabinetWClass,而广告窗口的类名是CabinetWClass。进一步分析发现：广告窗口的WorkerA类和Shell DocObject View类的rect.top的值是相同的，正常IE窗口的WorkerA类和Shell DocObject View类的rect.top的值是不相同的。根据以上两点就可以书写广告杀手程序了。 事实上，我对此程序的通用性持怀疑态度。因为笔者用Spy++分析发现，在Windows2000( 笔者使用的操作系统)中，IE窗口的类都为IEFrame。同时，由于Win2000是一个基于Unicode代码的操作系统，所以没有WorkerA类，而以WorkerW类取而代之。同时，也不存在rect.top不相同的情况，由于笔者没有WindowsXP操作系统，所以不能针对WindowsXP作进一步的试验。</p><p>　　（3）、基于IE COM组件的封杀方式</p><p>　　以上两种方式都是把IE窗口当作一个普通的Windows窗口对待，进行判断的。事实上，IE是一个典型的基于COM组件的浏览器，所有的基于IE内核的浏览器都是包装shdocvw.dll文件，然后书写相应的BHO代码。只有这样才能做到真正的控制IE浏览器，而不是方法一、二这样的隔靴搔痒。</p><p>　　还有一种基于IE内核的弹出窗口封杀方法。它可以在弹出窗口打开之前加以拦截。其原理是：每当IE打开一个新的窗口时候都会触发NewWindow事件，执行OnNewWindow2([out] IDispatch*, [out] BOOL *bCancel)方法。重载此方法，判断打开新窗口事件是否发生在浏览页面已经下载完毕之后。如果是，说明是正常的弹出窗口，反之加以拦截。</p><p>　　由于Gosurf这样的浏览器本身就重载了Shocvm.dll组件，所以使用第三种方法就自然成了顺理成章的事。然而在使用过程中有时也会发现，广告过滤不很完美，但原理基本如此。 </p><p align="right">（出处：<a title="网络学院" href="http://www.vipcn.com/" target="_blank">http://www.vipcn.com</a>）</p><img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6648.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-05-05 18:20 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/05/05/6648.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是DNN(DotNetNuke)</title><link>http://www.cppblog.com/Jeff-Chen/archive/2006/04/28/6410.html</link><dc:creator>Jeff-Chen</dc:creator><author>Jeff-Chen</author><pubDate>Fri, 28 Apr 2006 01:37:00 GMT</pubDate><guid>http://www.cppblog.com/Jeff-Chen/archive/2006/04/28/6410.html</guid><wfw:comment>http://www.cppblog.com/Jeff-Chen/comments/6410.html</wfw:comment><comments>http://www.cppblog.com/Jeff-Chen/archive/2006/04/28/6410.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Jeff-Chen/comments/commentRss/6410.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Jeff-Chen/services/trackbacks/6410.html</trackback:ping><description><![CDATA[
		<span class="SubHead">什么是Dotnetnuke?</span>
		<br />
		<div class="Normal" width="100%">
				<p>
				</p>
				<h1 align="center">
						<font size="3">Dotnetnuke是一个免费、开源、可扩展、几近完美的内容管理系统。可广泛应用于商务网站、企业内网（Intranet）和外网网站、在线内容发布网站。</font>
				</h1>
				<div> </div>
				<div>Dotnetnuke是建立在微软ASP.NET平台之上的一套Web应用框架。</div>
				<div> </div>
				<div>Dotnetnuke是微软第一次向开源说”Yes”的里程碑。</div>
				<div> </div>
				<div>Dotnetnuke 是门户网站的未来。 </div>
				<div> </div>
				<h2>Dotnetnuke的特色</h2>
				<div>        通用性          ――――几乎可以用来构建让任何Web应用：商务网站，企业内网／外网，在线内容发布。</div>
				<div>       用户友好性    ―――—其设计考虑非常周全，借助站点向导，无处不在的帮助图标等等，用户能够很容易的控制项目的各个方面。</div>
				<div>         多网站支持    ――――套程序部署就可以支持多个网站。每个网站都有各自的管理员和独特页面布局。</div>
				<div>         技术支持       ――――Dotnetnuke有一个核心开发团队和国际化的支持社团。DNN的用户组、论坛、资源网站以及专注与DNN技术的很多公司，全方位的提供支持和帮助。</div>
				<div>        安装简单       ――――从<a href="http://www.dotnetnuke.com/">www.Dotnetnuke.com</a> (英文版) 或<a href="http://www.dnnchina.net/">www.DnnChina.net</a> (中文版)下载软件以后，按照安装指导的步骤，只需要几分钟就可以完成。</div>
				<div>         本地化           ――――到目前为止已经有27个语言包，能很轻松的把您的网站转换成几乎任何语言。语言包也是可扩展的，您可以很容易的创建自己的特色语言包。</div>
				<div>         开放源代码    ――――DNN是免费、开放源代码项目，采用类BSD风格的授权方式。容许任何人按自己的想法，商业和非商业的使用DNN.。BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以"为所欲为",可以自由的使用，修改源代码，也可以将修改后的代码作为开源或者专有软件再发布。你只需要源代码中带有原来代码中的BSD协议。</div>
				<div>         高扩展性       ――――DNN内建的功能已经足够构建一个非常复杂的内容管理系统。DNN提供了全新的在线式功能块扩展，无论是第三方模块还您自己开发的模块，都能随时很容易的加入到正在运行的网站中。</div>被广泛认同    ――――Dotnetnuke已经是一个商标，得到了开源社区的广泛认同和尊重。Dotnetnuke.com（英文）已经有超过170,000的注册用户，DnnChina.net（中文）已经有超过2,600的注册用户。</div>
<img src ="http://www.cppblog.com/Jeff-Chen/aggbug/6410.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Jeff-Chen/" target="_blank">Jeff-Chen</a> 2006-04-28 09:37 <a href="http://www.cppblog.com/Jeff-Chen/archive/2006/04/28/6410.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>