﻿<?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>博客园-pwy</title><link>http://www.cnblogs.com/lsjwzh/</link><description>lsjwzh</description><language>zh-cn</language><lastBuildDate>Sat, 11 Oct 2008 23:27:54 GMT</lastBuildDate><pubDate>Sat, 11 Oct 2008 23:27:54 GMT</pubDate><ttl>60</ttl><item><title>c#缓存介绍（转）</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/08/25/1275809.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Mon, 25 Aug 2008 07:08:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/08/25/1275809.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1275809.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/08/25/1275809.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1275809.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1275809.html</trackback:ping><description><![CDATA[摘要: 本章导读缓存主要是为了提高数据的读取速度。因为服务器和应用客户端之间存在着流量的瓶颈，所以读取大容量数据时，使用缓存来直接为客户端服务，可以减少客户端与服务器端的数据交互，从而大大提高程序的性能。本章从缓存所在的命名空间“System.Web.Caching”开始，详细介绍框架提供的缓存类和操作方法，主要涉及简单数据的缓存、数据缓存依赖和数据库缓存依赖三个技术要点，最后演示一个完全使用缓存实现数据&nbsp;&nbsp;<a href='http://www.cnblogs.com/lsjwzh/archive/2008/08/25/1275809.html'>阅读全文</a><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1275809.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42945/" target="_blank">[新闻]Google股价跌破329美元 61%员工期权价值归零</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>ASP.NET 2.0缓存</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/08/25/1275800.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Mon, 25 Aug 2008 07:00:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/08/25/1275800.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1275800.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/08/25/1275800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1275800.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1275800.html</trackback:ping><description><![CDATA[<TABLE class="" cellSpacing=0 cellPadding=5 width="100%" border=0>
<TBODY>
<TR>
<TD class=td_blog_title_style align=left class="td_blog_title_style"><IMG src="http://www.cnblogs.com/images/icon/icon11.gif" align=absMiddle border=0>ASP.NET 2.0缓存</TD></TR>
<TR>
<TD class=td_blog_attribute align=left width="100%" class="td_blog_attribute"></TD></TR>
<TR>
<TD class=td_blog_content_style style="WORD-WRAP: break-word" vAlign=top align=left height=100 class="td_blog_content_style">
<DIV id=div_blogcontent>
<P><STRONG>MSDN上缓存概述：</STRONG><A href="http://msdn2.microsoft.com/zh-cn/library/726btaeh%28VS.80%29.aspx" target=_blank>http://msdn2.microsoft.com/zh-cn/library/726btaeh%28VS.80%29.aspx</A> </P>
<P mce_keep="true">&nbsp;</P>
<P><STRONG>一、页输出缓存<BR><BR><SPAN style="COLOR: brown">1.设置 ASP.NET 页缓存的两种方式</SPAN></STRONG><BR><BR><STRONG><SPAN style="COLOR: green">1.1 以声明方式设置 ASP.NET 页的缓存</SPAN></STRONG><BR><BR>以声明方式设置 ASP.NET 页的缓存的方法是在页中使用 @ OutputCache 指令，它的常用属性如下：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>&lt;%@ OutputCache Duration="" VaryByParam="" VaryByControl="" VaryByHeader="" VaryByCustom="" CacheProfile="" Location="" %&gt;</DIV></DIV>
<P><BR>Duration：设置缓存到期时间，单位：秒。<BR>VaryByParam：可用来使缓存输出因查询字符串而异，多个查询字符用分号隔开。<BR>VaryByControl：可用来使缓存输出因控制值而异。<BR>VaryByHeader：可用来使缓存输出因请求的 HTTP 标头而异。<BR>VaryByCustom：可用来使缓存输出因浏览器类型或您定义的自定义字符串而异。<BR>CacheProfile：结合配置文件使用。<BR>Location：设置页的可缓存性，值有Any,Client,Downstream,None,Server,ServerAndClient。<BR><BR>注：在使用 @ OutputCache 指令时，必须包括一个 VaryByParam 属性，否则将出现分析器错误。如果不希望使用 VaryByParam 属性提供的功能，请将它的值设置为“None”。<BR><BR><I>@ OutputCache 指令使用示例</I><BR><BR>①使用参数对页的各个版本进行缓存：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>&lt;%@ OutputCache Duration="60" VaryByParam="City" %&gt;</DIV></DIV>
<P><BR>注：如果要根据多个参数改变输出缓存，请包括以分号 (;) 作为分隔符的参数名称的列表；如果要根据所有的参数值来改变缓存，请将VaryByParam 属性设置为星号 (*)；如果不要根据参数值来改变缓存，请将 VaryByParam 属性设置为"None"。<BR><BR>②使用 HTTP 标头对某页的各个版本进行缓存：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>&lt;%@ OutputCache Duration="60" VaryByParam="None" VaryByHeader="Accept-Language" %&gt;</DIV></DIV>
<P><BR>注：如果要根据多个标头改变缓存的内容，请以分号 (;) 作为分隔符包括标头名称的列表；如果要根据所有标头值改变缓存的内容，请将VaryByHeader 属性设置为星号 (*)。<BR><BR>③使用请求浏览器缓存页的各个版本：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>&lt;%@ OutputCache Duration="10" VaryByParam="None" VaryByCustom="browser" %&gt;</DIV></DIV>
<P><BR>④使用自定义字符串对页的各个版本进行缓存：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>&lt;%@ OutputCache Duration="10" VaryByParam="None" VaryByCustom="minorversion" %&gt;</DIV></DIV>
<P><BR>注：还要在应用程序的 Global.asax 文件中，重写 GetVaryByCustomString 方法以指定自定义字符串的输出缓存行为。参考：<A href="http://msdn2.microsoft.com/zh-cn/library/5ecf4420(VS.80).aspx" target=_blank>http://msdn2.microsoft.com/zh-cn/library/5ecf4420(VS.80).aspx</A><BR><BR>⑤结合配置文件：<BR>将以下 XML 添加为 system.web 元素的子项：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>&lt;!-- caching section group --&gt;<BR>&lt;caching&gt;<BR>&lt;outputCacheSettings&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;outputCacheProfiles&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;add name="AppCache1" enabled="true" duration="60"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/outputCacheProfiles&gt;<BR>&lt;/outputCacheSettings&gt;<BR>&lt;/caching&gt;</DIV></DIV>
<P><BR>@ OutputCache 指令：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>&lt;%@ OutputCache CacheProfile="AppCache1" VaryByParam="None" %&gt;</DIV></DIV>
<P><BR>使用这种方法我们可以从单个配置文件更改缓存行为，而无需编辑各个页面的 @ OutputCache 指令，并且还可以根据需要建立不同的缓存规则，再应用到各组单独页面中。<BR><BR><STRONG><SPAN style="COLOR: green">1.2 以编程方式设置 ASP.NET 页的缓存</SPAN></STRONG><BR><BR>以编程方式设置 ASP.NET 页的缓存的方法是在页的代码中，调用 Response 对象的 Cache 属性：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>Response.Cache.SetExpires(DateTime.Now.AddSeconds(60)); //设置缓存过期时间<BR>Response.Cache.SetCacheability(HttpCacheability.Public); //设置页的可缓存性<BR>Response.Cache.SetValidUntilExpires(true); //缓存忽略 Cache-Control 无效标头</DIV></DIV>
<P><BR><I>使用示例</I><BR><BR>①使用参数对页的各个版本进行缓存：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>protected void Page_Load(object sender, EventArgs e)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetExpires(DateTime.Now.AddMinutes(1.0));<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetCacheability(HttpCacheability.Public);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetValidUntilExpires(true);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.VaryByParams["Zip"] = true;<BR>}</DIV></DIV>
<P><BR>注：如果要根据多个参数改变缓存的内容，请多次设置 VaryByParams 属性。<BR><BR>②使用 HTTP 标头对某页的各个版本进行缓存：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>protected void Page_Load(object sender, EventArgs e)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetExpires(DateTime.Now.AddMinutes(1.0));<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetCacheability(HttpCacheability.Public);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetValidUntilExpires(true);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.VaryByHeaders["Accept-Language"] = true;<BR>}</DIV></DIV>
<P><BR>注：如果要根据多个标头改变缓存的内容，需要在 VaryByHeaders 属性中设置多个值。如果要根据所有标头改变缓存的内容，请将VaryByHeaders["VaryByUnspecifiedParameters"] 设置为 true。<BR><BR>③使用请求浏览器缓存页的各个版本：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>protected void Page_Load(object sender, EventArgs e)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetExpires(DateTime.Now.AddMinutes(1.0));<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetCacheability(HttpCacheability.Public);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetValidUntilExpires(true);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetVaryByCustom("browser");<BR>}</DIV></DIV>
<P><BR>④使用自定义字符串对页的各个版本进行缓存：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>protected void Page_Load(object sender, EventArgs e)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetExpires(DateTime.Now.AddMinutes(1.0));<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetCacheability(HttpCacheability.Public);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetValidUntilExpires(true);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Response.Cache.SetVaryByCustom("minorversion");<BR>}</DIV></DIV>
<P><BR>说明：要在应用程序的 Global.asax 文件中，重写 GetVaryByCustomString 方法以指定自定义字符串的输出缓存行为。<BR><BR><STRONG><SPAN style="COLOR: brown">2.页输出缓存的几种模型</SPAN></STRONG><BR><BR><STRONG><SPAN style="COLOR: green">2.1 整页缓存：</SPAN></STRONG>当设置 ASP.NET 页缓存的位置发生在页面上时，即是整页缓存。<BR><STRONG><SPAN style="COLOR: green">2.2 部分页缓存(控件缓存)：</SPAN></STRONG>当设置 ASP.NET 页缓存的位置发生在用户控件上时，即是控件缓存。<BR><STRONG><SPAN style="COLOR: green">2.3 部分页缓存(缓存后替换)：</SPAN></STRONG>在整个缓存的页面上以声明方式使用 Substitution 控件或以编程方式使用 Substitution 控件 API 或以隐式方式使用 AdRotator 控件，即是采用了缓存后替换。<BR><BR><I>缓存后替换举例(以声明方式使用 Substitution 控件)</I><BR><BR>aspx代码：<BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>&lt;asp:Label ID="Label1" runat="server" Text="Label" Width="276px"&gt;&lt;/asp:Label&gt;<BR>&lt;br /&gt;<BR>&lt;asp:Substitution ID="Substitution1" runat="server" MethodName="NoCache" /&gt;</DIV></DIV>
<P><BR>aspx.cs代码：<BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>protected void Page_Load(object sender, EventArgs e)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Label1.Text = DateTime.Now.ToString();<BR>}<BR>protected static string NoCache(HttpContext context)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return DateTime.Now.ToString();<BR>}</DIV></DIV>
<P><BR>说明：Substitution 控件的 MethodName 属性值为一个方法的名称(本例为NoCache)，对该方法的要求是它接受的参数类型必须为HttpContext且返回值类型为string，而且还必须为静态方法！<BR><BR><STRONG>二、应用程序缓存</STRONG><BR><BR><STRONG><SPAN style="COLOR: brown">1.创建</SPAN></STRONG><BR><BR>方法1：Cache["CacheName"] = "CacheValue";<BR>方法2：Cache.Insert(String key,object value,System.Web.Caching.CacheDependency dependencies,DateTime absoluteExpiration,TimeSpan slidingExpiration,System.Web.Caching.CacheItemPriority priority,System.Web.Caching.CacheItemRemovedCallback onRemoveCallback);<BR>方法3：Cache.Add(String key,object value,System.Web.Caching.CacheDependency dependencies,DateTime absoluteExpiration,TimeSpan slidingExpiration,System.Web.Caching.CacheItemPriority priority,System.Web.Caching.CacheItemRemovedCallback onRemoveCallback);<BR><BR>Add方法和Insert方法的区别是Add 方法将返回您添加到缓存中的对象。另外，如果使用 Add 方法，并且缓存中已经存在与现有项同名的项，则该方法不会替换该项，并且不会引发异常。<BR><BR><I>创建示例</I><BR><BR>①通过使用 Insert 方法将项添加到缓存中：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>Cache.Insert("CacheItem2", "Cached Item 2");</DIV></DIV>
<P><BR>②通过指定依赖项向缓存添加项：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>string[] dependencies = { "CacheItem2" };<BR>Cache.Insert("CacheItem3", "Cached Item 3",new System.Web.Caching.CacheDependency(null, dependencies));</DIV></DIV>
<P><BR>③将设有过期策略的项添加到缓存中：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>Cache.Insert("CacheItem6", "Cached Item 6",null, DateTime.Now.AddMinutes(1d), System.Web.Caching.Cache.NoSlidingExpiration);</DIV></DIV>
<P><BR>④将设有优先级设置的项添加到缓存中：<BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>Cache.Insert("CacheItem8", "Cached Item 8",<BR>&nbsp;&nbsp;&nbsp;&nbsp;null, System.Web.Caching.Cache.NoAbsoluteExpiration,<BR>&nbsp;&nbsp;&nbsp;&nbsp;System.Web.Caching.Cache.NoSlidingExpiration,<BR>&nbsp;&nbsp;&nbsp;&nbsp;System.Web.Caching.CacheItemPriority.High, null);</DIV></DIV>
<P><BR><STRONG><SPAN style="COLOR: brown">2.检索</SPAN></STRONG><BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>string cachedString;<BR>cachedString = (string)Cache["CacheItem"];<BR>if (cachedString == null)<BR>{<BR>&nbsp;&nbsp;cachedString = "Www.Mzwu.Com";<BR>&nbsp;&nbsp;Cache.Insert("CacheItem", cachedString);<BR>}</DIV></DIV>
<P><BR>注：由于缓存中所存储的信息为易失信息，即该信息可能由 ASP.NET 移除，因此建议的开发模式是首先确定该项是否在缓存中。如果不在，则应将它重新添加到缓存中，然后检索该项。<BR><BR><STRONG><SPAN style="COLOR: brown">3.移除</SPAN></STRONG><BR><BR>&nbsp;</P>
<DIV class=UBBPanel>
<DIV class=UBBTitle><IMG style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</DIV>
<DIV class=UBBContent>Cache.Remove("MyData1");</DIV></DIV></DIV></TD></TR></TBODY></TABLE><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1275800.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42945/" target="_blank">[新闻]Google股价跌破329美元 61%员工期权价值归零</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>插入数据的同时，返回ID值</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259370.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Sun, 03 Aug 2008 11:06:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259370.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1259370.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1259370.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1259370.html</trackback:ping><description><![CDATA[<P><A title=搜索该标签相关文章 href="http://www.bokee.net/searchmodule/weblog/search_search.do?query=SQL&amp;type=3"><SPAN style="TEXT-DECORATION: underline">SQL</SPAN></A> <A title=搜索该标签相关文章 href="http://www.bokee.net/searchmodule/weblog/search_search.do?query=Server&amp;type=3"><SPAN style="TEXT-DECORATION: underline">Server</SPAN></A> 2000中，有三个比较类似的功能：他们分别是：SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY，它们都返回插入到 IDENTITY 列中的值。 </P>
<P>IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制，而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。<BR>@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。<BR>SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值</P>
<P>SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是，SCOPE_IDENTITY 只返回插入到当前作用域中的值；@@IDENTITY 不受限于特定的作用域。</P>
<P><BR>例如，有两个表 T1 和 T2，在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时，触发器被激发，并在 T2 中插入一行。此例说明了两个作用域：一个是在 T1 上的插入，另一个是作为触发器的结果在 T2 上的插入。</P>
<P><BR>假设 T1 和 T2 都有 IDENTITY 列，@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。</P>
<P><BR>@@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值，该值是插入 T2 中的值。</P>
<P><BR>SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值，该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数，则该函数将返回 NULL 值。</P>
<P><BR>而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分别是这两个表最后自增的值。</P>
<P>ajqc的实验:(40条本地线程,40+40条远程线程同时并发测试,插入1200W行),得出的结论是: <BR>1.在典型的级联应用中.不能用@@IDENTITY,在CII850,256M SD的机器上1W多行时就会并发冲突.在P42.8C,512M DDR上,才6000多行时就并发冲突. <BR>2.SCOPE_IDENTITY()是绝对可靠的,可以用在存储过程中,连触发器也不用建,没并发冲突 </P>
<P>SELECT &nbsp; IDENT_CURRENT('TableName') &nbsp; --返回指定表中生成的最后一个标示值&nbsp;&nbsp;&nbsp;<BR>SELECT &nbsp; IDENT_INCR('TableName')--返回指定表的标示字段增量值<BR>SELECT &nbsp; IDENT_SEED('TableName')--返回指定表的标示字段种子值<BR></P>
<P>返回最后插入记录的自动编号<BR>SELECT IDENT_CURRENT('TableName')<BR>&nbsp;返回下一个自动编号:&nbsp;&nbsp;&nbsp;<BR>&nbsp;SELECT &nbsp; IDENT_CURRENT('TableName') &nbsp; + &nbsp; (SELECT &nbsp; IDENT_INCR('TableName'))</P>
<P>SELECT @@IDENTITY --返回当前会话所有表中生成的最后一个标示值</P><A href="http://blog.csdn.net/gyd1/archive/2008/06/03/2506915.aspx" mce_href="http://blog.csdn.net/gyd1/archive/2008/06/03/2506915.aspx"><FONT color=#336699>插入数据的同时，返回ID值</FONT></A> 
<P mce_keep="true">&nbsp;</P>
<P>前几天在做项目时，遇到插入数据的同时，返回ID值的问题，遂记录如下：</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 插入数据的同时，返回ID值的sql语句。 </P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MSSQL:</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INSERT INTO test2 (aa)&nbsp;&nbsp; VALUES ('cc')&nbsp;&nbsp; SELECT @@IDENTITY AS SEQUENCE</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MYSQL: </P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select last_insert_id() as ID from T_D_NM_SHOP_TEMPLET limit 1</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;在ibatis中，可以这样配置：</P>
<P align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!--创建任务MYSQL数据库，在MYSQL数据库中，表T_D_QT_TASK中的task_id为自增字段。--&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp; &lt;!--在插入数据，返回task_id的插入值的配置文件如下--&gt;<BR>&nbsp;&nbsp; &nbsp;&lt;parameterMap id="MapTask" class="java.util.HashMap"&gt;<BR>&nbsp; &nbsp;&nbsp;&lt;parameter property="taskgroup_id" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.Integer" mode="IN" /&gt;<BR>&nbsp; &nbsp;&lt;parameter property="task_name" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="task_content" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="test_object" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="status" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.Integer" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="user_id" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="script_type" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&lt;/parameterMap&gt;<BR>&nbsp;&lt;insert id="insertTask" parameterMap="MapTask"&gt;<BR>&nbsp;&nbsp;insert into T_D_QT_TASK (`TASKGROUP_ID` ,`TASK_NAME`<BR>&nbsp;&nbsp;,`TASK_CONTENT` , `TEST_OBJECT` ,`PRIORITY`,`STATUS`, `USER_ID`<BR>&nbsp;&nbsp;,`SCRIPT_TYPE` ) values(?,?,?,?,'9',?,?,?)<BR>&nbsp;&nbsp;&lt;selectKey resultClass="java.lang.String" keyProperty="tid"&gt;<BR>&nbsp;&nbsp;&nbsp;select last_insert_id() as TASK_ID from T_D_QT_TASK limit 1<BR>&nbsp;&nbsp;&lt;/selectKey&gt;<BR>&nbsp;&lt;/insert&gt;<BR>&lt;!--创建任务ORACLE数据库, 在oracle数据库中，表T_D_QT_TASK中的task_id没有设置为自增。--&gt;<BR>&lt;!--（这样设置我得到的主键返回值总是大于实际插入值）,遂取消task_id与触发器的关联。--&gt;<BR>&lt;!--直接建立一个SEQ：SEQ_D_QT_TASK获取它的返回值，直接插入到表中 .注意配置--&gt;<BR>&lt;!--中的keyProperty="task_id"。是把seq的返回值，放入到对应的映射中的task_id中--&gt;<BR>&nbsp;&lt;parameterMap id="MapTask" class="java.util.HashMap"&gt;<BR>&nbsp;&nbsp;&lt;parameter property="task_id" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.Integer" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="taskgroup_id" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.Integer" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="task_name" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="task_content" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="test_object" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="status" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.Integer" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="user_id" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&nbsp;&lt;parameter property="script_type" jdbcType="varchar"<BR>&nbsp;&nbsp;&nbsp;javaType="java.lang.String" mode="IN" /&gt;<BR>&nbsp;&lt;/parameterMap&gt;<BR>&nbsp;&lt;insert id="insertTask" parameterMap="MapTask"&gt;<BR>&nbsp;&nbsp;&lt;selectKey resultClass="java.lang.Integer"<BR>&nbsp;&nbsp;&nbsp;keyProperty="task_id"&gt;<BR>&nbsp;&nbsp;&nbsp;SELECT SEQ_D_QT_TASK.NEXTVAL AS ID FROM DUAL<BR>&nbsp;&nbsp;&lt;/selectKey&gt;<BR>&nbsp;&nbsp;insert into T_D_QT_TASK (TASK_ID,TASKGROUP_ID ,TASK_NAME<BR>&nbsp;&nbsp;,TASK_CONTENT , TEST_OBJECT ,PRIORITY,STATUS, USER_ID<BR>&nbsp;&nbsp;,SCRIPT_TYPE ) values(?,?,?,?,?,'9',?,?,?)<BR>&nbsp;&lt;/insert&gt;<BR></P><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1259370.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42944/" target="_blank">[新闻]十年祭:昔日明星软件今何在?</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>在.net中aspx改成其它的后缀名</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259287.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Sun, 03 Aug 2008 08:41:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259287.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1259287.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259287.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1259287.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1259287.html</trackback:ping><description><![CDATA[<P><FONT color=#ff0000>下。<IMG style="WIDTH: auto" alt=疑问 src="http://static.xiaonei.com/img/editor/emot/emot-32.gif"></FONT></P>
<P><FONT color=#ff0000>传说中的方法一</FONT>：（源于<A href="http://topic.csdn.net/t/20050203/10/3772606.html" target=_blank><FONT color=#3b5888>http://topic.csdn.net/t/20050203/10/3772606.html</FONT></A>）</P>
<P><A class="" target=_blank name=r_27632523></A><FONT color=#3b5888>47 楼</FONT>Truly（）回复于 2005-02-03 20:19:58 得分 15 </P>
<P>1.iis默认站点－主目录－设置－添加－ &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; Executable: &nbsp; C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\aspnet_isapi.dll &nbsp; <BR>&nbsp; Extension:.mspx &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; 确定 &nbsp; <BR>&nbsp; &nbsp; <BR>&nbsp; 2.web.config &nbsp; <BR>&nbsp; &nbsp; &nbsp; &lt;system.web&gt; &nbsp; <BR>&nbsp; &lt;httpHandlers&gt; &nbsp; <BR>&nbsp; &nbsp; &nbsp; &lt;add &nbsp; verb="*" &nbsp; path="*.mspx" &nbsp; type="System.Web.UI.PageHandlerFactory"/&gt; &nbsp; <BR>&nbsp; &lt;/httpHandlers&gt;</P>
<P><FONT color=#ff0000>传说中的方法二</FONT>：<A class=singleposttitle id=AjaxHolder_ctl01_TitleUrl href="http://www.cnblogs.com/robin0925/archive/2007/03/20/681151.html" target=_blank><FONT color=#3b5888>HttpHandler HttpModule 做出属于自己的后缀的网页 ! </FONT></A></P>
<P>&nbsp;首先谈谈ASP.net的一些参数传递和页面定向的方式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第一，ASP.net是用Page.Navigate()调用新页面的URL。Page.Navigate()向浏览器返回了一个http状态码302，使得浏览器向server请求那个新的URL。这种导航方法导致每次客户请求都需两次在client和server之间往返。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第二，任何要传递到新页面的信息都需作为URL的参数或存储在Session中或存储在数据库中以便新页面得到这些信息。传统的ASP开发人员很习惯这种做法，但其他的web编程人员则有一些更高级的方法。但是很明显的这两个页面是有依赖性的，而依赖性是编译器捕捉不到的也是不容易在设计阶段建模的。所以在debug时，参数是否被正确的传递就只有我们自己检查了。再有传统的数据传递方式有可能会暴露一些关键的数据。更为关键的是这使得面向对象的设计变得很复杂。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;但是我们可以自定义httphandler来扩充这种支持。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;要对HTTPMODULE和IHTTPHANDLER进行研究，必须先对ASP.NET的处理管道有一个了解。&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;在ASP.NET应用程序中，系统使用一组相关的类，通过一定的顺序来处理客户端的请求(REQUEST)，ASP.NET应用程序的处理模式可称之为HTTP处理管道。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp; HTTPMODULE和IHTTPHANDLER就是这个处理管道上的两个处理环节。 HTTP处理管道中的类在SYSTEM.WEB名称空间中定义，主要有以下类型： HTTPWORKERREQUEST 抽象类定义了ASP.NET页面处理请求的基本方法；&nbsp;<BR>&nbsp;&nbsp;&nbsp;HTTPRutime 提供了处理应用的一组服务；&nbsp;<BR>&nbsp;&nbsp;&nbsp;HTTPContext 保存了处理一次请求的所有相关上下文信息；&nbsp;<BR>&nbsp;&nbsp;&nbsp;HTTPApplicationFactory 提供相关目录的应用程序；&nbsp;<BR>&nbsp;&nbsp;&nbsp;HTTPApplication 定义了所有ASP.NET应用程序的通用的方法、属性和事件。这个类也是在用户在GLOBAL.ASAX文件中定义的应用的基类；&nbsp;<BR>&nbsp;&nbsp;&nbsp;Modules 处理请求前和响应后的事件；&nbsp;<BR>&nbsp;&nbsp;&nbsp;Handlerfactories 提供应用程序中的HANDLERS；&nbsp;<BR>&nbsp;&nbsp;&nbsp;Handlers 处理请求和响应。&nbsp;<BR><BR>&nbsp;&nbsp; 在WINDOWS平台上，HTTP PIPLINE需要IIS的支持。为了运行ASP.NET应用，IIS需要以下两个文件：ASPNET_ISAPI.DLL和ASPNET_WP.EXE ASPNET_ISAPI.DLL是一个ISAPI EXTENTION他将发向IIS的请转交ASPNET_WP.EXE处理 ASPNET_WP.EXE使用HTTPRUNTIME对请求进行具体处理 处理的过程可以用图表示如下:<BR><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <IMG style="WIDTH: 400px" height=220 alt="" src="http://www.cnblogs.com/images/cnblogs_com/robin0925/elmah_fig04.gif" width=449 border=0><BR><BR><FONT face=Simsun>下面一个简单的例子来理解!</FONT>&nbsp;1). 建立一个名为SimpleHandler的工程，添加一个类MyHandler.cs，代码如下：<BR><BR>namespace&nbsp;SimpleHandler<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;MyHandler&nbsp;:&nbsp;IHttpHandler<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;ProcessRequest(HttpContext&nbsp;ctx)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpResponse&nbsp;response&nbsp;=&nbsp;ctx.Response;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.Write("&nbsp;My&nbsp;first&nbsp;Handler&nbsp;!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;bool&nbsp;IsReusable<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;{&nbsp;return&nbsp;true;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>&nbsp;2). 将上面的代码编译，生成SimpleHandler.dll 文件；<BR><BR>&nbsp;3). 建立一个新的Web项目,将文件SimpleHandler.dll 添加到项目的引用中；<BR>&nbsp;4). 修改Web.config ，添加如下内容:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&lt;system.web&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;httpHandlers&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add verb="*" path="*.ASPX" type="SimpleHandler.MyHandler,SimpleHandler" /&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/httpHandlers&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/system.web&gt;<BR>&nbsp;&nbsp;&nbsp;配置文件中的选项说明：&nbsp;<BR>&nbsp;&nbsp;&nbsp;VERB可以是"GET"或"POST"，表示对GET或POST的请求进行处理。<BR>&nbsp;&nbsp;&nbsp;"*"表示对所有请求进行处理。&nbsp;<BR>&nbsp;&nbsp;&nbsp;PATH指明对相应的文件进行处理，"*.ASPX"表示对发给所有ASPX页面的请求进行处理。可以指明路径，如"/TEST/*.ASPX"，表明只对TEST目录下的ASPX文件进行处理。&nbsp;<BR>&nbsp;&nbsp;&nbsp;TYPE属性中，逗号前的字符串指明HTTPHANDLER的实现类的类名，后面的字符串指明DLL文件的名称。&nbsp;<BR>&nbsp;&nbsp;&nbsp;现在，请求项目中的任何ASPX页面，页面上显示的始终只有如下一行字： My first Handler !<BR><BR><BR><BR><BR>因为，我们自定义的HANDLER截获了所有发向ASPX页面的请求，并且用自己的的方法来处理这些请求了。 <BR><BR>为了使我们的字定义页面 如: *.AAA 能够顺利运行，我们需要修改WEB.CONFIG文件：&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;<FONT face="Times New Roman" size=3>&nbsp;&lt;system.web&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;httpHandlers&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add verb="*" path="*.AAA" type="SimpleHandler.MyHandler,SimpleHandler" /&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/httpHandlers&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/system.web&gt;</FONT><BR>为了让对后缀名为.AAA 的文件的请求能够被我们的HANDLER截获运行，我们还需要一些额外的工作。打开IIS的管理控制台，又键单击站点，选择"属性"，跳出站点的属性对话框。选择主目录选项,选择配置，弹出应用程序配置对话框，将".AAA"添加到应用程序映射中 . 好了，我们现在可以在项目中添加一个.AAA 文件，当向该文件发送请求时，浏览器显示：&nbsp; My first Handler !&nbsp;&nbsp; 而对其他ASPX文件的访问不受影响。</P><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1259287.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42944/" target="_blank">[新闻]十年祭:昔日明星软件今何在?</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>几个.Net开源的CMS&amp;Portal系统</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259282.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Sun, 03 Aug 2008 08:34:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259282.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1259282.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259282.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1259282.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1259282.html</trackback:ping><description><![CDATA[<P><SPAN id=txtObj_962315>几个.Net开源的CMS&amp;Portal系统 最近打算花些功夫研究.Net环境下的CMS&amp;Portal系统，很多优秀的开源CMS&amp;Portal系统，都是PHP开发的，比如Xoops、Mambo、Drupal，比起Php在OpenSource中的群星璀璨来，.Net CMS&amp;Portal开源项目有点暗淡。在sourceforge上找了一个下午，把一些比较有成熟、有特点的项目下载下来准备研究。 <BR>一、DotNetNuke DotNetNuke<BR>是一个.Net平台下，最负盛名的CMS系统，爱好者们都称它为DNN，开发语言是VB.Net。<BR>其相关资源有：<BR>Sourceforge上的项目地址：http://sourceforge.net/projects/dnn/ <BR>官方网址：http://www.dotnetnuke.com/ <BR>有汉化版本，国内有不少的研究者，主要集中在：http://www.dnnchina.net/，那里提供有很多的学习教程和Skin。 DNN是一个比较成熟的CMS系统，提供有大量的插件（Feed、相册等），目前最高版本是4.0，在.Net2.0框架下运行。 <BR>DNN是VB.Net开发的，很多开发者并不习惯VB.Net的风格，所以DNN爱好者创建了个C#版本的项目SharpNuke.NET。 <BR>Sourceforge上的项目地址：http://sourceforge.net/projects/sharpnukenet <BR>官方地址为：http://sharpnuke.net/ <BR>二、dBlog Sourceforge<BR>介绍说dBlog是asp和asp.net混合开发的，实际上主要还是asp环境下运行的CMS系统，这是一个轻量级的系统，其实主要用于Blog的发布，而并非Portal。 <BR>Sourceforge上的项目地址：http://sourceforge.net/projects/dblog/ <BR>官方地址：http://www.dblog.it/ <BR>比较有特点的地方就是blog、podcast的相关功能的实现。 <BR>三、Rainbow Portal<BR>一个酷酷的名字--Rainbow，使用C#开发，这个系统是在MS iBuySpy的基础架构上强化而来的，目前的Rainbow2006和iBuySpy项目已经很不一样了，大大的超出了很多，比起DNN来，Rainbow也有不少的优点，它支持多种语言，可以定制主体风格，可以创建工作流等。 <BR>Sourceforge上的项目地址：http://sourceforge.net/projects/rainbowportal/ <BR>官方地址：http://www.rainbowportal.net/ <BR>Rainbow在国内也有相关的研究：http://rata.cnblogs.com/ <BR>我发现Rainbow2006的安装有些问题，他的数据库创建脚本不适应大字符集的环境，我在简体中文的系统打开脚本查看，一些Insert的配置参数是乱码。 <BR>四、OmniPortal OmniPortal<BR>并不是一个直接的应用程序，实际上是一个Portal的框架内核，可以在它的基础上建立任何的Web应用系统。对于一个Web开发者，OmniPortal提供了优秀的二次开发基础类库，虽然目前OmniPortal还不是一个Release版本，但是非常值得关注。<BR>Sourceforge上的项目地址：http://sourceforge.net/projects/omniportal/ <BR>官方地址：http://www.omniportal.net/ <BR>由于OmniPortal是一个基础框架，因此参考文档相当重要，可是官方网站不知道为什么总连不上去，Sourceforge上又没有相关的文档，让人非常遗憾。 <BR>五、Ludico 这个Portal&amp;CMS系统也不是一个正式版本的，去年11月份才开始的项目，但是我发现它的架构非常优秀，采用NHibernate.Net作为系统框架，因此可以作为一个很好的学习对象，值得关注之。 <BR>Sourceforge上的项目地址：http://sourceforge.net/projects/ludico/ Technorati : .Net, CMS, OpenSource, Portal</SPAN></P><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1259282.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42944/" target="_blank">[新闻]十年祭:昔日明星软件今何在?</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>为什么要使用接口编程(转)</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259275.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Sun, 03 Aug 2008 08:11:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259275.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1259275.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/08/03/1259275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1259275.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1259275.html</trackback:ping><description><![CDATA[<H3 class="" title=""><A href="http://www.cnblogs.com/blog/162866"><FONT color=#108ac6><SPAN class=hilite1><FONT style="BACKGROUND-COLOR: #ffff00" size=2>为什么要使用接口</FONT></SPAN>编程(转)</FONT></A></H3>
<DIV class=blog_content>看了接口编程这篇文章,理解蛮透彻的.记录下: <BR><BR>进行接口的介绍，必须介绍一下程序语言发展的历史才行，鲁迅先生说过“治学先治史”，明白了程序语言发展的前世今生，才能知道为什么这么多语言为什么会这样，为什么么会那样？ <BR><BR>计算机出现以后，科学家相继开发了多种语言，从smalltalk，Pascal，Basic，C语言，C++，java,.net等等，这些语言的发展步伐，可以看作是从面向过程向面向对象发展的一段历史。很多面向对象的书在介绍自己的历史的时候，都会给读者介绍这一段历史，并鼓吹OO编程是多么多么的优异。问题是，很多刚开始学程序的人根本不知道为什么要有这个转变，他们也很难理解OO语言中的虚函数，接口等概念到底为了什么而提出来。 <BR><BR>我们在了解这一段历史以前，首先给大家介绍一个概念——“粒度”，什么是粒度？作者认为所谓粒度其实就是一个程序中使用代码单元的组合尺度，我们可以举一个例子，沙砾——砖块——房屋模板，我们设想去修建一座房子，其实有很多中修筑方法，如果你不闲麻烦，可以使用沙砾一点点地建筑，或者将沙砾烧制为砖块，用砖块来砌，甚至直接从工厂购买房屋的门，窗，墙组件来堆砌。这三种不同的方法代表了三种不同的组合尺度。沙砾是最小的单位，使用它搭建小的房子说不定还可以，但是毫无疑问，我们必须使用很多很多“沙砾”，不便于管理；砖块比沙砾聚合了一层，可以用来修建较大的房子了；房屋模板是最高的尺寸，使用它可以快速地搭建大规模的房屋。这三种尺度的区别和联系，与我们编写程序概念是有很大的相似之处的。 <BR><BR>在早期学习Pascal，老师告诉我们这种面向过程语言的最基本的单元是过程和函数，它们是程序中的最小的组件。过程和函数可以实现最基本的代码重用，当我们把某些固定功能的代码使用过程和函数编写后，我们可以在程序中调用它们而不必在任何需要的地方都写上这样一段代码，这样的好处是显而易见的。在一些小型的程序里面，使用过程和函数是合适的，但是在大中型程序中，它们的弊端就显示出来，过程和函数的粒度太低了，如果我们一个系统，有10000个函数和过程，我们的程序员将不得不花费大量的时间去寻找和维护它们，10000个没有任何关系的函数和过程的管理难度是显而易见的，就好像10000个人的企业一样，如果没有部门和职务，这还不乱了套？！ <BR><BR>面向对象语言的出现，就是为了解决这个问题，别听OO语言吹的天花乱坠，其实它出现就为一个理由——提高编程的粒度。面向对象语言的基本单位是类 CLASS，类封装了很多数据成员和成员函数，过程，将最小组件的提高了一个等级，我们需要直接操作的不是过程和函数了，而是一个个更高层次上的类。我们把10000人分了很多部门，不同的部门负责不同的事宜，这样公司终于可以走上正轨了。 <BR><BR>做成了类CLASS是否就万事大吉了呢？不一定，新的问题随之而来，也许我们有一个部门的人很多，可以做很多事情，如何在部门内部实现更好的管理呢？好比我们有一个类，它提供了很多种方法和属性，这些方法和属性其实可以分为一堆堆，为不同的功能服务，但是我们的类并没有做这个管理。在AO种，map对象拥有很多功能，比如管理图层，管理元素，管理选择集，进行地图显示，每种不同的功能都有好多方法和属性，现在这些属性和方法是杂乱无章，没有任何区别堆积在一个类里面的，当我们的程序员需要寻找一个方法的时候，不得不一个个去寻找，很不方便。 <BR><BR>这个时候，接口interface出现了，C++的发明者第一次提出纯虚函数（其实就是接口）概念的时候，遭到了很多抵制，很多人都不明白接口的意义何在，我们用虚函数好好的，何必又出来个啥东西都没有的空架子？说它是类吧，又不能实现产生一个对象；说它是对象吧，又没有方法体来使用。接口出来干了一件好事，就是将类内部进行分类。对于map对象，我们可以做好几个接口，这些接口中定义不同功能的方法，函数和属性，map类实现这些接口，这样我们可以使用接口定义，实现对象。因此，所谓接口就是一系列相关方法与属性集合的定义。 <BR><BR>Dim pGraphicsContainer as iGraphicsContainer <BR>pGraphicsContainer=application.document.ActiveView.focusMap <BR>pGraphicsContainer可以使用的属性和方法就只能是它定义的那部分了，而不能使用管理元素等的接口定义的方法和属性，那我们如何使用其它的功能呢？这就是所谓的QI(Query Interface)功能。从一个接口查询另一个接口。 <BR><BR>Dim pGeoFeatureLayer as iGeofeatureLayer <BR>pGeoFeatureLayer= pGraphicsContainer QI <BR><BR>好了，我们罗嗦了这么多，已经走进了COM的概念了，在正式介绍COM以前我们得最后罗嗦一点：计算机语言的发展历史，其实就是一部不断提高组件粒度的历史，不断提高代码重用的历史。以前我们使用过程和函数，后来我们使用类，现在我们使用接口，都是为了一个目的，让我们操作的组件在具体和抽象之间寻找一个平衡点。太具体了，如过程和函数，就没有了框架；太抽象，如类，就无法分别。 <BR><BR><BR>一个代码示例： <BR>public interface IForm <BR>{ <BR>void Show(); <BR>void ShowDialog(); <BR>} <BR><BR>public class A:IForm <BR>{ <BR>public void Show() <BR>{ <BR>} <BR>public void ShowDialog() <BR>{ <BR>} <BR>} <BR><BR>public class B:IForm <BR>{ <BR>public void Show() <BR>{ <BR>} <BR>public void ShowDialog() <BR>{ <BR>} <BR>} <BR><BR><BR>public class FormFactory <BR>{ <BR>public static IForm CreateInstance(string parm) <BR>{ <BR><BR>if (parm == "A") <BR>{ <BR>return new A(); <BR>else if (parm == "B") <BR>return new B(); <BR>} <BR>return null; <BR>} <BR>} </DIV><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1259275.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42944/" target="_blank">[新闻]十年祭:昔日明星软件今何在?</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>AjaxPro使用Session注意地方（转）</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/08/02/1259017.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Sat, 02 Aug 2008 15:01:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/08/02/1259017.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1259017.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/08/02/1259017.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1259017.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1259017.html</trackback:ping><description><![CDATA[<DIV class=post>
<DIV class=postTitle><A class=postTitle2 id=AjaxHolder_ctl01_TitleUrl href="http://www.cnblogs.com/over140/archive/2007/10/19/930405.html">AjaxPro使用Session出错(AjaxPro "Session"引发了"System.NullReferenceException"类型的异常)</A> </DIV><FONT face=Verdana>关于在<FONT face=Verdana>ASP.NET</FONT>如何使用<FONT face=Verdana>AjaxPro</FONT>，这里就不多说了，先看代码:<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;[AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequirement.ReadWrite)]<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;btnNextZX(</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;data)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuilder&nbsp;zx_Ret&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;StringBuilder();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hashtable&nbsp;hash&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Hashtable)Session[</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jgd_data</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;&nbsp;&nbsp;&nbsp;<IMG alt="" src="http://www.cnblogs.com/Images/dot.gif"><IMG alt="" src="http://www.cnblogs.com/Images/dot.gif"></SPAN></DIV>注意：这里排除Session中没有["jgd_data"]这个数据而引起的出错，当然即使不存在也报的并不是如下的错误：<BR><IMG height=113 alt="" src="http://images.cnblogs.com/cnblogs_com/over140/10月/20071019.JPG" width=630 border=0><BR>很奇怪！我明明加了如下代码啊！！<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">[AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequirement.ReadWrite)]</SPAN></DIV><BR><BR><STRONG style="COLOR: red"><SPAN style="COLOR: #0000ff"><STRONG>
<H3>解决办法：</H3></STRONG></SPAN></STRONG>将如下代码行：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">Hashtable&nbsp;hash&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Hashtable)Session[</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jgd_data</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">];</SPAN></DIV>替换成如下代码：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">Hashtable&nbsp;hash&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(Hashtable）HttpContext.Current.Session[</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jgd_data</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">];</SPAN></DIV></FONT><BR><FONT face="宋体, MS Song">执行OK!! </FONT>
<DIV class=postDesc><BR>&nbsp;</DIV></DIV>
<DIV id=AjaxHolder_UpdatePanel1>
<DIV class=feedbackItem>
<DIV class=feedbackListSubtitle>
<DIV align=left>找到原因了：Session以及Application 、Request等，都是由Page类继承下来的（你可以this.Session点出来），而用Ajax.net对后台方法访问的时候，这些方法并不属于Page类，所以才需要从HttpContext.Current中读取。而Session又更特别些，需要加[AjaxPro.AjaxMethod(AjaxPro.HttpSessionStateRequirement.ReadWrite)]才能被访问。 <BR></DIV></DIV></DIV></DIV><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1259017.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42943/" target="_blank">[新闻]六大可能出售IT企业名单：SUN领头或被猎走</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>建立基于 Web 的事件日历</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/07/26/1252225.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Sat, 26 Jul 2008 13:19:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/07/26/1252225.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1252225.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/07/26/1252225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1252225.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1252225.html</trackback:ping><description><![CDATA[<H1 class=tit><FONT size=4>建立基于 Web 的事件日历</FONT></H1>
<DIV class=date><FONT size=4>2007-02-02 23:34</FONT></DIV>
<TABLE class="" style="TABLE-LAYOUT: fixed">
<TBODY>
<TR>
<TD class="">
<DIV class=cnt id=blog_text><FONT size=4>Scott&nbsp;Semyan<BR>Microsoft&nbsp;Corporation&nbsp;<BR>2000年7月&nbsp; </FONT>
<P mce_keep="true">&nbsp;</P>
<P><FONT size=4><STRONG>摘要：</STRONG>本文说明如何使用&nbsp;ASP、Internet&nbsp;Information&nbsp;Services&nbsp;和&nbsp;Microsoft&nbsp;SQL&nbsp;Server&nbsp;建立日历。</FONT></P>
<P><STRONG><FONT size=4>目录</FONT></STRONG></P>
<UL>
<LI><A href="http://www.microsoft.com/china/msdn/library/archives/workshop/calendar.asp#calendar_topic1"><FONT size=4>简介</FONT></A><FONT size=4>&nbsp; </FONT>
<LI><A href="http://www.microsoft.com/china/msdn/library/archives/workshop/calendar.asp#calendar_topic2"><FONT size=4>SQL&nbsp;后端</FONT></A><FONT size=4>&nbsp; </FONT>
<LI><A href="http://www.microsoft.com/china/msdn/library/archives/workshop/calendar.asp#calendar_topic3"><FONT size=4>ASP&nbsp;前端</FONT></A><FONT size=4>&nbsp; </FONT>
<LI><A href="http://www.microsoft.com/china/msdn/library/archives/workshop/calendar.asp#calendar_topic4"><FONT size=4>性能问题</FONT></A><FONT size=4>&nbsp; </FONT>
<LI><A href="http://www.microsoft.com/china/msdn/library/archives/workshop/calendar.asp#calendar_topic5"><FONT size=4>结论</FONT></A><FONT size=4> </FONT></LI></UL>
<P><FONT size=4><BR></FONT></P>
<H2><A class="" name=calendar_topic1></A><FONT size=4>简介</FONT></H2>
<P><FONT size=4>在本文中我将示范如何建立基于&nbsp;Web&nbsp;的日历。本文为不熟悉&nbsp;Active&nbsp;Server&nbsp;Pages&nbsp;(ASP)、Structured&nbsp;Query&nbsp;Language&nbsp;(SQL)&nbsp;和&nbsp;ActiveX®&nbsp;Data&nbsp;Objects&nbsp;(ADO)&nbsp;的开发者提供了对数据驱动的&nbsp;Web&nbsp;站点的很好介绍。同时也为很有经验的开发者提供了可伸缩性方面的技巧。</FONT></P>
<P><FONT size=4><IMG alt="基于 Web 的事件日历" src="http://www.microsoft.com/china/msdn/Archives/library/images/calendar01a.gif" border=0>&nbsp;</FONT></P>
<P class=label><STRONG><FONT size=4>图&nbsp;1.&nbsp;基于&nbsp;Web&nbsp;的事件日历</FONT></STRONG></P>
<P><FONT size=4><STRONG>什么是基于&nbsp;Web&nbsp;的日历？</STRONG>&nbsp;<BR>基于&nbsp;Web&nbsp;的日历最近已变得十分流行。起初人们将其日程表保存在个人信息管理器，如&nbsp;Microsoft®&nbsp;Outlook®&nbsp;中。简单地说，这些日历的问题在于它们是属于个人的，并且很难共享日历供其他人查看或使用。这样就需要有一种方法，要么使您的个人日历可供其他人查看，要么有一个小组日历可供许多人同时使用。随着&nbsp;Internet&nbsp;的兴起&nbsp;—&nbsp;任何时间、任何地方均可用&nbsp;—&nbsp;基于&nbsp;Web&nbsp;的日历已变得可行。</FONT></P>
<P><FONT size=4><STRONG>用基于&nbsp;Web&nbsp;的日历您可以做什么？</STRONG>&nbsp;<BR>基于&nbsp;Web&nbsp;的日历允许您与其他人共享您的日程表或管理一组人员的日历。如果您希望人们可以访问您的日程表，则共享您的日程表是有用的。另一方面，小组日历对于显示诸如最后期限或里程碑之类的主要事件，或显示谁在什么时候休假都是有用的。</FONT></P>
<P><FONT size=4><STRONG>在这里提供了什么？</STRONG><BR>在我的公司我们有一个&nbsp;intranet&nbsp;站点，在此站点中我们将所有与我们小组有关的信息，包括预定的休假、里程碑和假日，都集中在一起。为了做到这一点，我建立了一个简单的基于&nbsp;Web&nbsp;的日历，来供任何人查看、添加和/或删除事件（请参见图&nbsp;1）。</FONT></P>
<P><FONT size=4>我在本文中描述了如何使用&nbsp;Microsoft&nbsp;Internet&nbsp;Information&nbsp;Services&nbsp;(IIS)&nbsp;和&nbsp;Microsoft&nbsp;SQL&nbsp;Server™&nbsp;内的&nbsp;ASP&nbsp;页建立一个非常简单的基于&nbsp;Web&nbsp;的日历。在本文的结论部分，我将讨论当扩展此应用程序以支持许多用户时所必须考虑的性能方面牵涉的问题。对于不熟悉&nbsp;IIS&nbsp;和&nbsp;ASP&nbsp;的人，本文可视为建立数据驱动&nbsp;Web&nbsp;站点的一个好的教程。</FONT></P>
<H2>
<P><BR><STRONG><A class="" name=calendar_topic2></A><FONT color=#000000 size=4>SQL后端</FONT><FONT size=4>&nbsp;</FONT></STRONG></P>
<P><FONT size=4><STRONG>要保存什么数据？</STRONG><BR>第一个问题是您希望每个日期保存何种数据？就我的日历而言，我仅需保存表明事件性质的一个文本字符串，最长&nbsp;100&nbsp;个字符。可以容易地扩展此数据模型以包括很多内容，而不是仅仅包括一个文本字符串。</FONT></P>
<P><STRONG><FONT size=4>架构</FONT></STRONG></P>
<P><STRONG><FONT size=4>Calendar.sql</FONT></STRONG></P>
<P><FONT size=4>SQL&nbsp;代码包含在以下代码片断中：</FONT></P><PRE class=clsCode><FONT size=4>--------------------------------------------------
--&nbsp;表
--------------------------------------------------

create&nbsp;table&nbsp;Schedule
(
&nbsp;&nbsp;&nbsp;idSchedule&nbsp;&nbsp;&nbsp;smallint&nbsp;identity&nbsp;primary&nbsp;key,
&nbsp;&nbsp;&nbsp;dtDate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;smalldatetime&nbsp;not&nbsp;null,
&nbsp;&nbsp;&nbsp;vcEvent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;varchar(100)&nbsp;not&nbsp;null
)
go

--------------------------------------------------
--&nbsp;存储过程
--------------------------------------------------

create&nbsp;procedure&nbsp;GetSchedule&nbsp;(@nMonth&nbsp;tinyint,&nbsp;@nYear&nbsp;smallint)
as
&nbsp;&nbsp;&nbsp;select&nbsp;idSchedule,&nbsp;convert(varchar,&nbsp;datepart(dd,&nbsp;dtDate))&nbsp;'nDay',&nbsp;vcEvent
&nbsp;&nbsp;&nbsp;from&nbsp;Schedule
&nbsp;&nbsp;&nbsp;where&nbsp;datepart(yy,&nbsp;dtDate)&nbsp;=&nbsp;@nYear&nbsp;and&nbsp;datepart(mm,&nbsp;dtDate)&nbsp;=&nbsp;@nMonth
&nbsp;&nbsp;&nbsp;order&nbsp;by&nbsp;datepart(dd,&nbsp;dtDate)
go

create&nbsp;procedure&nbsp;AddEvent&nbsp;(@vcDate&nbsp;varchar(20),&nbsp;@vcEvent&nbsp;varchar(100))
as
&nbsp;&nbsp;&nbsp;insert&nbsp;Schedule
&nbsp;&nbsp;&nbsp;select&nbsp;@vcDate,&nbsp;@vcEvent&nbsp;
go

create&nbsp;procedure&nbsp;DeleteEvent&nbsp;(@idSchedule&nbsp;smallint)
as
&nbsp;&nbsp;&nbsp;delete&nbsp;Schedule&nbsp;where&nbsp;idSchedule&nbsp;=&nbsp;@idSchedule
go
</FONT></PRE>
<P><FONT size=4>对于我的&nbsp;schedule&nbsp;表，我使用一个标识键（自身递增）为主键，因此我自己无需创建一个唯一键。我为&nbsp;<STRONG>idSchedule</STRONG>&nbsp;选择&nbsp;<STRONG>smallint</STRONG>，这是因为根据我的需要，我不会有&nbsp;32,000&nbsp;多种不同的事件。而对于大型应用程序，则很可能希望使用一个长整数来获得多达&nbsp;20&nbsp;亿个记录。因为我无需按秒记录时间，所以我将日期保存为&nbsp;<STRONG>smalldatetime</STRONG>&nbsp;以节省空间。通常的日期时间会精确到毫秒，占用的空间是精确到分钟的&nbsp;smalldatetime&nbsp;的两倍。大型应用程序可能需要选用其它占用更少空间的记录日期的方法（例如，用一个整数来表示特定日期，如&nbsp;1970&nbsp;年&nbsp;1&nbsp;月&nbsp;1&nbsp;日之后的天数）。</FONT></P>
<P><FONT size=4>对于我的数据，我选择变长字符串&nbsp;(varchar)，最长为&nbsp;100&nbsp;个字符。在&nbsp;SQL&nbsp;Server&nbsp;7.0&nbsp;中您可以使用&nbsp;nvarchar，它可以容纳&nbsp;Unicode&nbsp;字符，从而使您的应用程序可以在全球使用。然而，创建全球可以使用的&nbsp;Web&nbsp;页还有其它问题，但这超出了本文讨论的范围。</FONT></P>
<P><STRONG><FONT size=4>存储过程</FONT></STRONG></P>
<P><FONT size=4>有关&nbsp;SQL&nbsp;中的存储过程的简短注释：存储过程优于&nbsp;ASP&nbsp;中的硬编码的&nbsp;SQL&nbsp;有两个主要原因。第一个原因是，将数据访问代码与表示代码保持分离可确保数据的独立性。这允许您更改数据结构（及其伴随的存储过程），而无需修改&nbsp;ASP&nbsp;页。这是经典的&nbsp;Microsoft&nbsp;Windows®&nbsp;DNA&nbsp;<EM>n</EM>&nbsp;层体系结构。首选存储过程的第二个原因是它们比文本查询运行得更快，因为存储过程第一次被调用时就经过分析。因此，随后的调用不必再分析此过程。</FONT></P>
<P><FONT size=4>我需要以下三个存储过程来访问和操纵此表中的数据：<STRONG>GetSchedule</STRONG>、<STRONG>AddEvent</STRONG>&nbsp;和&nbsp;<STRONG>DeleteEvent</STRONG>。</FONT></P>
<P><FONT size=4>对于&nbsp;<STRONG>GetSchedule</STRONG>&nbsp;过程，我将希望返回的数据的月份和年份传递给它。下一步，我使用&nbsp;<STRONG>Datepart()</STRONG>&nbsp;函数来获得事件的数字日期。然后在我建立日历的同时使用此数字来与该月的这一天相匹配。按天对结果进行排序是很重要的，稍后我们就可以看到这一点。</FONT></P>
<P><FONT size=4><STRONG>AddEvent</STRONG>&nbsp;过程仅向某个给定日期添加文本事件。由于所有的事件都标记有唯一的日程表&nbsp;ID，因此我不担心添加重复事件。</FONT></P>
<P><FONT size=4>从此日程表删除事件仅需唯一日程表&nbsp;ID。将此&nbsp;ID&nbsp;传递给&nbsp;<STRONG>DeleteEvent</STRONG>&nbsp;过程即会删除此事件。</FONT></P>
<H2><A class="" name=calendar_topic3></A><FONT size=4>ASP&nbsp;前端</FONT></H2>
<P><STRONG><FONT size=4>基本&nbsp;UI</FONT></STRONG></P>
<P><FONT size=4>图&nbsp;1&nbsp;显示主要的用户界面&nbsp;(UI)。设置的&nbsp;UI&nbsp;象挂式日历。我的一周从星期天开始，包含&nbsp;7&nbsp;天。为了简易起见，我没有进行繁琐的格式化，但使用样式表可容易地使此日历看起来更专业。由此主页，用户可以看到哪些事件是已安排的。另外，使用底部的链接可以在日历中按月前后翻动，或者使用此页左上角的下拉式列表框可以选择特定的月份和年份。到“添加/删除事件”页的链接就在日历的下方。</FONT></P>
<P><STRONG><FONT size=4>ASP&nbsp;代码基础</FONT></STRONG></P>
<P><STRONG><FONT size=4>header.asp</FONT></STRONG></P><PRE class=clsCode><FONT size=4>&lt;%@&nbsp;LANGUAGE="VBSCRIPT"&nbsp;
&nbsp;&nbsp;&nbsp;ENABLESESSIONSTATE&nbsp;=&nbsp;False&nbsp;%&gt;
&lt;%
'********************************************************************
'&nbsp;名称：header.asp
'
'&nbsp;目的：标头包括用来启动所有页的文件，
'&nbsp;&nbsp;&nbsp;还包括全局函数
'
'********************************************************************

Option&nbsp;Explicit
Response.Buffer&nbsp;=&nbsp;True
Response.Expires&nbsp;=&nbsp;0

sub&nbsp;Doheader(strTitle)
%&gt;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&lt;html&gt;
&nbsp;&nbsp;&nbsp;&lt;head&gt;
&nbsp;&nbsp;&nbsp;&lt;META&nbsp;HTTP-EQUIV="Content-Type"&nbsp;CONTENT="text/html;&nbsp;charset=gb2312"&gt;
&nbsp;&nbsp;&nbsp;&lt;title&gt;Event&nbsp;Calendar&nbsp;-&nbsp;&lt;%=&nbsp;strTitle&nbsp;%&gt;&lt;/title&gt;
&nbsp;&nbsp;&nbsp;&lt;/head&gt;

&nbsp;&nbsp;&nbsp;&lt;body&nbsp;bgcolor="white"&nbsp;link="blue"&nbsp;alink="blue"&nbsp;vlink="blue"&gt;
&nbsp;&nbsp;&nbsp;&lt;basefont&nbsp;face="Verdana,&nbsp;Arial"&gt;

&nbsp;&nbsp;&nbsp;&lt;center&gt;&lt;h1&gt;Event&nbsp;Calendar&lt;/h1&gt;
&nbsp;&nbsp;&nbsp;&lt;h3&gt;&lt;%=&nbsp;strTitle&nbsp;%&gt;&lt;/h3&gt;
&lt;%
end&nbsp;sub

sub&nbsp;DoFooter(strTitle)
%&gt;
&nbsp;&nbsp;&nbsp;&lt;/center&gt;
&nbsp;&nbsp;&nbsp;&lt;/body&gt;&lt;/html&gt;
&lt;%
end&nbsp;sub

function&nbsp;GetDataConnection()
&nbsp;&nbsp;&nbsp;dim&nbsp;oConn,&nbsp;strConn
&nbsp;&nbsp;&nbsp;Set&nbsp;oConn&nbsp;=&nbsp;Server.CreateObject("ADODB.Connection")
&nbsp;&nbsp;&nbsp;strConn&nbsp;=&nbsp;"Provider=SQLOLEDB;&nbsp;Data&nbsp;Source=adspm;&nbsp;Initial&nbsp;Catalog=TeamWeb;&nbsp;"
&nbsp;&nbsp;&nbsp;strConn&nbsp;=&nbsp;strConn&nbsp;&amp;&nbsp;"User&nbsp;Id=TeamWeb;&nbsp;Password=x"
&nbsp;&nbsp;&nbsp;oConn.Open&nbsp;strConn
&nbsp;&nbsp;&nbsp;set&nbsp;GetDataConnection&nbsp;=&nbsp;oConn
end&nbsp;function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
%&gt;
</FONT></PRE>
<P><FONT size=4>在我用&nbsp;ASP&nbsp;对&nbsp;Web&nbsp;站点进行编码时，我喜欢整个站点使用单个标头页。这使我可以将常用的函数、样式、Microsoft&nbsp;JScript®&nbsp;等置于一页上。对于此站点，我已经建立了一个标头页（请参阅前面的代码示例），它为整个站点设定了一些&nbsp;ASP&nbsp;设置并包含了我在所有其他页中使用的三个函数：一个&nbsp;HTML&nbsp;标头和注脚以及我的数据连接代码。</FONT></P>
<P><FONT size=4>我做的第一件事情是将语言设置为&nbsp;Microsoft&nbsp;Visual&nbsp;Basic®&nbsp;Scripting&nbsp;Edition&nbsp;(VBScript)&nbsp;并禁用会话状态。设置语言不是必需的，但这是一个好主意。另外，我显式告知&nbsp;IIS&nbsp;此站点不使用&nbsp;ASP&nbsp;会话状态，这样可以稍微提高性能。我的其他编码约定是设置&nbsp;Option&nbsp;Explicit（意思是我必须在使用变量之前&nbsp;dim&nbsp;它们）、缓冲的输出（IIS&nbsp;将保留输出，然后立即将其全部吐出&nbsp;—&nbsp;这可以提高性能），以及将此页设置为立即到期（以便用户始终可以获得刷新的页面）。</FONT></P>
<P><FONT size=4>我使用处理所有我的&nbsp;HTML&nbsp;标头代码的&nbsp;<STRONG>Doheader</STRONG>&nbsp;函数。我传入页名，它同时显示在&nbsp;HTML&nbsp;标题中和页顶部的&nbsp;H3&nbsp;标记中。这给予我一个单独的位置来编辑&nbsp;HTML&nbsp;BODY&nbsp;属性、样式等。与&nbsp;<STRONG>Doheader</STRONG>&nbsp;函数类似，我喜欢在需要添加一个普通的注脚（包括联系信息等）时有一个注脚函数。</FONT></P>
<P><FONT size=4>ADO&nbsp;使我可以很容易地将我的&nbsp;ASP&nbsp;页与我的&nbsp;SQL&nbsp;数据库相连接。首先我创建一个到数据库的连接。为了获得记录集，我调用&nbsp;<STRONG>Connection</STRONG>&nbsp;对象的&nbsp;<STRONG>Execute</STRONG>&nbsp;方法，将希望执行的命令的文本字符串传入。一旦有了记录集，就可以在其中循环。header.asp&nbsp;包含获得我的数据连接的函数。这意味着如果我的数据源有变化我就只有一个位置需要编辑连接信息（服务器、用户、口令）。请注意，作为结果我必须在函数的末尾使用&nbsp;<STRONG>set</STRONG>&nbsp;命令传出新连接。</FONT></P>
<P><STRONG><FONT size=4>工作原理</FONT></STRONG></P>
<P><STRONG><FONT size=4>Calendar.asp</FONT></STRONG></P><PRE class=clsCode><FONT size=4>&lt;!--#includes&nbsp;file="header.asp"--&gt;
&lt;%
'********************************************************************
'&nbsp;名称：Calendar.asp
'
'&nbsp;目的：主日历页以日历格式显示事件
'
'********************************************************************

dim&nbsp;dbConn,&nbsp;rs,&nbsp;nDex,&nbsp;nMonth,&nbsp;nYear,&nbsp;dtDate

'&nbsp;获取当前日期
dtDate&nbsp;=&nbsp;Now()

'&nbsp;设置月份和年份
nMonth&nbsp;=&nbsp;Request.QueryString("nMonth")
nYear&nbsp;=&nbsp;Request.QueryString("nYear")
if&nbsp;nMonth&nbsp;=&nbsp;""&nbsp;then&nbsp;nMonth&nbsp;=&nbsp;Month(dtDate)
if&nbsp;nYear&nbsp;=&nbsp;""&nbsp;then&nbsp;nYear&nbsp;=&nbsp;Year(dtDate)

'&nbsp;将日期设置为当前月份的第一天
dtDate&nbsp;=&nbsp;DateSerial(nYear,&nbsp;nMonth,&nbsp;1)

Set&nbsp;dbConn&nbsp;=&nbsp;GetDataConnection
Set&nbsp;rs&nbsp;=&nbsp;dbConn.Execute&nbsp;("GetSchedule&nbsp;"&nbsp;&amp;&nbsp;nMonth&nbsp;&amp;&nbsp;",&nbsp;"&nbsp;&amp;&nbsp;nYear)&nbsp;

Doheader(MonthName(Month(dtDate))&nbsp;&amp;&nbsp;"&amp;nbsp;&amp;nbsp;"&nbsp;&amp;&nbsp;nYear)
%&gt;
&lt;form&nbsp;method="get"&nbsp;name="DateSelect"&nbsp;action="Calendar.asp"&gt;

&lt;table&nbsp;width=700&gt;
&lt;tr&gt;&lt;td&nbsp;colspan=2&gt;&lt;select&nbsp;name="nMonth"&nbsp;onChange="DateSelect.submit();"&gt;&lt;%
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;nDex&nbsp;=&nbsp;1&nbsp;to&nbsp;12
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;option&nbsp;value="""&nbsp;&amp;&nbsp;nDex&nbsp;&amp;&nbsp;""""
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;MonthName(nDex)&nbsp;=&nbsp;MonthName(nMonth)&nbsp;then&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&nbsp;selected"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;if
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&gt;"&nbsp;&amp;&nbsp;MonthName(nDex)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next&nbsp;%&gt;&lt;/select&gt;&amp;nbsp;
&nbsp;&nbsp;&nbsp;&lt;select&nbsp;name="nYear"&nbsp;onChange="DateSelect.submit();"&gt;&lt;%
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;注：已将年份设置为&nbsp;1999&nbsp;年和&nbsp;2000&nbsp;年之间
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;nDex&nbsp;=&nbsp;1999&nbsp;to&nbsp;2002
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;option&nbsp;value="""&nbsp;&amp;&nbsp;nDex&nbsp;&amp;&nbsp;""""
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;nDex&nbsp;=&nbsp;CInt(nYear)&nbsp;then&nbsp;Response.Write&nbsp;"&nbsp;selected"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&gt;"&nbsp;&amp;&nbsp;nDex
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next&nbsp;%&gt;&lt;/select&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td&nbsp;colspan=2&gt;
&nbsp;&nbsp;&nbsp;&lt;table&nbsp;border=1&nbsp;bgcolor="gray"&nbsp;cellpadding=3&gt;
&nbsp;&nbsp;&nbsp;&lt;tr&nbsp;bgcolor="Blue"&gt;&lt;td&nbsp;width=90&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Sunday&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;width=90&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Monday&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;width=90&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Tuesday&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;width=90&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Wednesday&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;width=90&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Thursday&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;width=90&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Friday&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;width=90&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Saturday&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;
&nbsp;&nbsp;&nbsp;&lt;tr&nbsp;bgcolor="#ffffc0"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;%&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;添加空单元格，直至到达正确日期为止
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;nDex&nbsp;=&nbsp;1&nbsp;to&nbsp;Weekday(dtDate)&nbsp;-&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;td&nbsp;bgcolor=""#c0c0c0""&gt;&amp;nbsp;&lt;/td&gt;"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;td&nbsp;valign=""top""&gt;"&nbsp;&amp;&nbsp;Day(dtDate)&nbsp;&amp;&nbsp;"&lt;br&gt;&amp;nbsp;&lt;br&gt;"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;not&nbsp;rs.EOF&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;CInt(rs("nDay"))&nbsp;&lt;&gt;&nbsp;CInt(Day(dtDate))&nbsp;then&nbsp;exit&nbsp;do

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;font&nbsp;size=""-1""&gt;&lt;b&gt;"&nbsp;&amp;&nbsp;rs("vcEvent")&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;/b&gt;&lt;/font&gt;&lt;br&gt;"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rs.MoveNext
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;rs.EOF&nbsp;then&nbsp;exit&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;if

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;/td&gt;"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;WeekDay(dtDate)&nbsp;=&nbsp;7&nbsp;then&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;/tr&gt;"&nbsp;&amp;&nbsp;vbCrLf&nbsp;&amp;&nbsp;"&lt;tr&nbsp;&nbsp;bgcolor=""#ffffc0""&gt;"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;if
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dtDate&nbsp;=&nbsp;DateAdd("d",&nbsp;1,&nbsp;dtDate)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop&nbsp;until&nbsp;(Month(dtDate)&nbsp;&lt;&gt;&nbsp;CInt(nMonth))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;如果需要添加空白单元格填充剩余的月份
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;Weekday(dtDate)&nbsp;&lt;&gt;&nbsp;1&nbsp;then&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;nDex&nbsp;=&nbsp;Weekday(dtDate)&nbsp;to&nbsp;7
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;td&nbsp;bgcolor=""#C0C0C0""&gt;&amp;nbsp;&lt;/td&gt;"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;if
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;
&nbsp;&nbsp;&nbsp;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;
&nbsp;&nbsp;&nbsp;
&lt;tr&gt;&lt;td&nbsp;colspan=2&nbsp;align="center"&gt;&lt;b&gt;&lt;a&nbsp;
&nbsp;&nbsp;&nbsp;href="Events.asp?nMonth=&lt;%=&nbsp;nMonth&nbsp;%&gt;&amp;nYear=&lt;%=&nbsp;nYear&nbsp;%&gt;"
&nbsp;&nbsp;&nbsp;&gt;Add/Remove&nbsp;Events&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt;&lt;td&gt;&lt;a&nbsp;href="Calendar.asp?nMonth=&lt;%
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;nMonth&nbsp;=&nbsp;1&nbsp;then&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"12&amp;nYear="&nbsp;&amp;&nbsp;nYear&nbsp;-&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;nMonth&nbsp;-&nbsp;1&nbsp;&amp;&nbsp;"&amp;nYear="&nbsp;&amp;&nbsp;nYear
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;if&nbsp;%&gt;"&gt;&lt;b&gt;&amp;lt;-&nbsp;Previous&nbsp;Month&lt;/b&gt;&lt;/a&gt;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;align=right&gt;&lt;a&nbsp;href="Calendar.asp?nMonth=&lt;%
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;nMonth&nbsp;=&nbsp;12&nbsp;then&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"1&amp;nYear="&nbsp;&amp;&nbsp;nYear&nbsp;+&nbsp;1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;nMonth&nbsp;+&nbsp;1&nbsp;&amp;&nbsp;"&amp;nYear="&nbsp;&amp;&nbsp;nYear
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;if&nbsp;%&gt;"&gt;&lt;b&gt;Next&nbsp;Month&nbsp;-&nbsp;&amp;gt;&lt;/b&gt;&lt;/a&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&lt;/tr&gt;
&lt;/table&gt;

&lt;/form&gt;

&lt;%
DoFooter("Home")
%&gt;
</FONT></PRE>
<P><FONT size=4>此项目最具挑战性的部分是建立一个精确的&nbsp;HTML&nbsp;日历。有多个算法要确定。例如，每月有多少天，是否为闰年等。我不做所有这些工作，而是使用&nbsp;Visual&nbsp;Basic&nbsp;内的&nbsp;<STRONG>date</STRONG>&nbsp;对象来建立我的日历。</FONT></P>
<P><FONT size=4>为了设计某个给定月份的日历，我首先为该年该月的第一天创建&nbsp;<STRONG>date</STRONG>&nbsp;对象。然后我使用&nbsp;<STRONG>DateAdd()</STRONG>&nbsp;函数只是将日期向前递增，一次一天。接着我可以使用内建方法来显示它是一周的星期几以及此月何时结束。我还知道这是此月的哪一天，并利用这一点来与我的日程表信息同步。这使我可以建立显示日历的表。</FONT></P>
<P><FONT size=4>Event&nbsp;Calendar&nbsp;页是通过使用在查询字符串中传递的日期和年份动态创建的。如果未传入月份和年份，则使用当前的月份和年份。</FONT></P>
<P><FONT size=4>这简化了建立可在月份之间移动的&nbsp;UI。向后移动一个月的链接是通过调用&nbsp;Calendar.asp&nbsp;和提供表明上一月的查询字符串（如果在一月份则递减年份）创建的。向前移动一个月与此一样容易（首先检查一下看看是否在十二月份）。移动到特定的月份和年份就更容易了。所有要做的工作是用&nbsp;Calendar.asp&nbsp;建立一个表格作为目标，用我们希望包含的月份和年份填充下拉式列表框，然后将提交事件附加到下拉式列表框的&nbsp;<STRONG>onChange()</STRONG>&nbsp;事件中。这使得页在用户选择新的月份或年份时自动更新。请注意我是如何使用&nbsp;<STRONG>MonthName()</STRONG>&nbsp;函数来列出月份的。</FONT></P>
<P><FONT size=4>显示事件是十分容易的。首先我使用&nbsp;ADO&nbsp;连接到我的&nbsp;SQL&nbsp;数据库来抽出给定月份的事件。我调用我的&nbsp;<STRONG>GetSchedule</STRONG>&nbsp;存储过程并传入正在讨论的月份和年份。这提供给我一个包含事件列表以及它们发生的日子（按天排序）的记录集。</FONT></P>
<P><FONT size=4>现在，在我建立日历的同时，我仅在其发生的日子显示事件。因为我知道我的事件是按天排序的，所以我可以做到这一点。</FONT></P>
<P><FONT size=4><IMG alt=“添加/删除事件”页 src="http://www.microsoft.com/china/msdn/Archives/library/images/calendar02a.gif" border=0>&nbsp;</FONT></P>
<P class=label><STRONG><FONT size=4>图&nbsp;2.&nbsp;“添加/删除事件”页</FONT></STRONG></P>
<P><FONT size=4>“添加/删除事件”页使用户可以添加新事件或删除现有的事件。首先将日历移动到适当的月份，然后单击“添加/删除事件”链接可访问此页。此链接是为包括表明添加/删除事件的月份和年份的查询字符串而创建的。</FONT></P>
<P><FONT size=4>此月的当前事件列表是通过使用与&nbsp;Calendar.asp&nbsp;相同的&nbsp;<STRONG>GetSchedule</STRONG>&nbsp;存储过程生成的。这一次所有我们要做的工作只是在记录集中循环以显示此月的所有事件。</FONT></P>
<P><STRONG><FONT size=4>Events.asp</FONT></STRONG></P><PRE class=clsCode><FONT size=4>&lt;!--#includes&nbsp;file="header.asp"--&gt;
&lt;%
&nbsp;&nbsp;&nbsp;'********************************************************************
&nbsp;&nbsp;&nbsp;'&nbsp;名称：Events.asp
&nbsp;&nbsp;&nbsp;'
&nbsp;&nbsp;&nbsp;'&nbsp;目的：用于向事件数据库中添加事件以及从中删除事件。
&nbsp;&nbsp;&nbsp;'
&nbsp;&nbsp;&nbsp;'********************************************************************
&nbsp;
&nbsp;&nbsp;&nbsp;dim&nbsp;dbConn,&nbsp;rs,&nbsp;nDex,&nbsp;nMonth,&nbsp;nYear,&nbsp;dtDate,&nbsp;dtTemp

&nbsp;&nbsp;&nbsp;'&nbsp;获取当前日期
&nbsp;&nbsp;&nbsp;dtDate&nbsp;=&nbsp;Now()

&nbsp;&nbsp;&nbsp;'&nbsp;设置月份和年份
&nbsp;&nbsp;&nbsp;nMonth&nbsp;=&nbsp;Request("nMonth")
&nbsp;&nbsp;&nbsp;nYear&nbsp;=&nbsp;Request("nYear")
&nbsp;&nbsp;&nbsp;if&nbsp;nMonth&nbsp;=&nbsp;""&nbsp;then&nbsp;nMonth&nbsp;=&nbsp;Month(dtDate)
&nbsp;&nbsp;&nbsp;if&nbsp;nYear&nbsp;=&nbsp;""&nbsp;then&nbsp;nYear&nbsp;=&nbsp;Year(dtDate)

&nbsp;&nbsp;&nbsp;Set&nbsp;dbConn&nbsp;=&nbsp;GetDataConnection
&nbsp;&nbsp;&nbsp;Set&nbsp;rs&nbsp;=&nbsp;dbConn.Execute&nbsp;("GetSchedule&nbsp;"&nbsp;&amp;&nbsp;nMonth&nbsp;&amp;&nbsp;",&nbsp;"&nbsp;&amp;&nbsp;nYear)&nbsp;

&nbsp;&nbsp;&nbsp;Doheader("Add/Remove&nbsp;Events")
%&gt;
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&lt;form&nbsp;method="get"&nbsp;action="AddEvent.asp"&gt;

&nbsp;&nbsp;&nbsp;&lt;br&gt;Currently&nbsp;Scheduled&nbsp;Events&nbsp;for&nbsp;&lt;b&gt;&lt;%
&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;MonthName(nMonth)&nbsp;&amp;&nbsp;"&amp;nbsp;&amp;nbsp;"&nbsp;&amp;&nbsp;nYear&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;%&gt;&lt;/b&gt;:&lt;p&gt;
&nbsp;&nbsp;&nbsp;&lt;table&nbsp;bgcolor="gray"&nbsp;border=1&nbsp;cellpadding=3&gt;
&nbsp;&nbsp;&nbsp;&lt;tr&nbsp;bgcolor="Blue"&gt;&lt;td&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Day&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&nbsp;colspan=2&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Event&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&lt;%&nbsp;if&nbsp;rs.EOF&nbsp;then&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;tr&gt;&lt;td&nbsp;colspan=3&nbsp;bgcolor=""#ffffc0""&gt;No&nbsp;events&nbsp;listed&lt;/td&gt;&lt;/tr&gt;"
&nbsp;&nbsp;&nbsp;end&nbsp;if
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;while&nbsp;not&nbsp;rs.EOF
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;tr&nbsp;bgcolor=""#ffffc0""&gt;&lt;td&gt;"&nbsp;&amp;&nbsp;rs("nDay")&nbsp;&amp;&nbsp;"&lt;/td&gt;&lt;td&gt;"&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;rs("vcEvent")&nbsp;&amp;&nbsp;"&lt;/td&gt;&lt;td&gt;&lt;input&nbsp;type=""button""&nbsp;value=""Remove"""
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&nbsp;onClick=""window.location.href='RemoveEvent.asp?nMonth="&nbsp;&amp;&nbsp;nMonth&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&amp;nYear="&nbsp;&amp;&nbsp;nYear&nbsp;&amp;&nbsp;"&amp;idSchedule="&nbsp;&amp;&nbsp;rs("idSchedule")&nbsp;&amp;&nbsp;"'""&gt;&lt;/td&gt;&lt;/tr&gt;"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rs.MoveNext
&nbsp;&nbsp;&nbsp;wend
&nbsp;&nbsp;&nbsp;%&gt;&lt;/table&gt;

&nbsp;&nbsp;&nbsp;&lt;p&gt;&lt;br&gt;
&nbsp;&nbsp;&nbsp;&lt;table&nbsp;bgcolor="gray"&nbsp;border=1&nbsp;cellpadding=3&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&nbsp;bgcolor="Blue"&gt;&lt;td&gt;&lt;font&nbsp;color="white"&gt;&lt;b&gt;Add&nbsp;New&nbsp;Event:&lt;/b&gt;&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&nbsp;bgcolor="#ffffc0"&gt;&lt;td&gt;Event:&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="text"&nbsp;size=30&nbsp;maxlength=100&nbsp;name="Event"&gt;&nbsp;Day:&nbsp;&lt;select&nbsp;name="nDay"&gt;&lt;%
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;将日期设置为当前月份的第一天
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dtDate&nbsp;=&nbsp;DateSerial(nYear,&nbsp;nMonth,&nbsp;1)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dtTemp&nbsp;=&nbsp;dtDate
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write&nbsp;"&lt;option&nbsp;value="""&nbsp;&amp;&nbsp;Day(dtTemp)&nbsp;&amp;&nbsp;"""&gt;"&nbsp;&amp;&nbsp;Day(dtTemp)&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dtTemp&nbsp;=&nbsp;DateAdd("d",&nbsp;1,&nbsp;dtTemp)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop&nbsp;until&nbsp;(Month(dtTemp)&nbsp;&lt;&gt;&nbsp;CInt(nMonth))&nbsp;%&gt;&lt;/select&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="hidden"&nbsp;name="nMonth"&nbsp;value="&lt;%=&nbsp;nMonth&nbsp;%&gt;"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="hidden"&nbsp;name="nYear"&nbsp;value="&lt;%=&nbsp;nYear&nbsp;%&gt;"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="Submit"&nbsp;value="Add&nbsp;Event"&gt;&lt;/td&gt;&lt;/tr&gt;
&nbsp;&nbsp;&nbsp;&lt;/table&gt;
&nbsp;&nbsp;&nbsp;&lt;/form&gt;

&nbsp;&nbsp;&nbsp;&lt;p&gt;&lt;a&nbsp;href="Calendar.asp?nMonth=&lt;%=&nbsp;nMonth&nbsp;%&gt;&amp;nYear=&lt;%=&nbsp;nYear&nbsp;%&gt;"&gt;Back&nbsp;to&nbsp;Calendar&lt;/a&gt;

&lt;%
&nbsp;&nbsp;&nbsp;DoFooter("Home")
%&gt;
</FONT></PRE>
<P><FONT size=4>要添加新事件，用户只是将其事件键入窗体，然后单击<STRONG>提交</STRONG>按钮。通过使用&nbsp;<STRONG>maxlength</STRONG>&nbsp;属性将窗体元素长度限制为&nbsp;100&nbsp;个字符，以匹配&nbsp;Schedule&nbsp;表中的&nbsp;event&nbsp;字段。</FONT></P>
<P><FONT size=4>要删除一个事件，用户单击希望删除的事件旁边的按钮。此按钮调用&nbsp;RemoveEvent.asp，传入此事件的&nbsp;<STRONG>idSchedule</STRONG>&nbsp;以及当前月份和年份，以便可以建立回到&nbsp;Events.asp&nbsp;链接。</FONT></P>
<P><STRONG><FONT size=4>AddEvent.asp</FONT></STRONG></P><PRE class=clsCode><FONT size=4>&lt;!--#includes&nbsp;file="header.asp"--&gt;
&lt;%
&nbsp;&nbsp;&nbsp;'********************************************************************
&nbsp;&nbsp;&nbsp;'&nbsp;名称：AddEvent.asp
&nbsp;&nbsp;&nbsp;'
&nbsp;&nbsp;&nbsp;'&nbsp;目的：用于向事件数据库中添加事件。
&nbsp;&nbsp;&nbsp;'
&nbsp;&nbsp;&nbsp;'********************************************************************
&nbsp;
&nbsp;&nbsp;&nbsp;dim&nbsp;dbConn,&nbsp;strSQL

&nbsp;&nbsp;&nbsp;Set&nbsp;dbConn&nbsp;=&nbsp;GetDataConnection
&nbsp;&nbsp;&nbsp;strSQL&nbsp;=&nbsp;"AddEvent&nbsp;'"&nbsp;&amp;&nbsp;Request("nMonth")&nbsp;&amp;&nbsp;"/"&nbsp;&amp;&nbsp;Request("nDay")&nbsp;
&nbsp;&nbsp;&nbsp;strSQL&nbsp;=&nbsp;strSQL&nbsp;&amp;&nbsp;"/"&nbsp;&amp;&nbsp;Request("nYear")&nbsp;&amp;&nbsp;"',&nbsp;'"&nbsp;
&nbsp;&nbsp;&nbsp;strSQL&nbsp;=&nbsp;strSQL&nbsp;&amp;&nbsp;Replace(Request("Event"),&nbsp;"'",&nbsp;"''")&nbsp;&amp;&nbsp;"'"&nbsp;

&nbsp;&nbsp;&nbsp;dbConn.Execute&nbsp;(strSQL)

&nbsp;&nbsp;&nbsp;Response.Redirect("Events.asp?nMonth="&nbsp;&amp;&nbsp;Request("nMonth")&nbsp;&amp;&nbsp;"&amp;nYear="&nbsp;&amp;&nbsp;Request("nYear"))
%&gt;
</FONT></PRE>
<P><FONT size=4>AddEvent.asp&nbsp;页接收由窗体传入的信息并使用&nbsp;<STRONG>AddEvent</STRONG>&nbsp;存储过程将其插入到数据库中。然后此页重定向回到“添加/删除事件”页，因此用户可立即看到他们的新事件。请注意我是如何使用&nbsp;<STRONG>Replace()</STRONG>&nbsp;函数来将单引号&nbsp;(')&nbsp;更改为一对单引号&nbsp;('&nbsp;')&nbsp;的，SQL&nbsp;将后者解释为单引号。如果您不这样做，在用户试图输入类似“All&nbsp;Saint's&nbsp;Day”的事件时您会得到一个错误。</FONT></P>
<P><STRONG><FONT size=4>RemoveEvent.asp</FONT></STRONG></P><PRE class=clsCode><FONT size=4>&lt;!--#includes&nbsp;file="header.asp"--&gt;
&lt;%
&nbsp;&nbsp;&nbsp;'********************************************************************
&nbsp;&nbsp;&nbsp;'&nbsp;名称：RemoveEvent.asp
&nbsp;&nbsp;&nbsp;'
&nbsp;&nbsp;&nbsp;'&nbsp;目的：用于从事件数据库中删除事件。
&nbsp;&nbsp;&nbsp;'
&nbsp;&nbsp;&nbsp;'********************************************************************
&nbsp;
&nbsp;&nbsp;&nbsp;dim&nbsp;dbConn

&nbsp;&nbsp;&nbsp;Set&nbsp;dbConn&nbsp;=&nbsp;GetDataConnection
&nbsp;&nbsp;&nbsp;dbConn.Execute&nbsp;("DeleteEvent&nbsp;"&nbsp;&amp;&nbsp;Request("idSchedule")&nbsp;)

&nbsp;&nbsp;&nbsp;Response.Redirect("Events.asp?nMonth="&nbsp;&amp;&nbsp;Request("nMonth")&nbsp;&amp;&nbsp;"&amp;nYear="&nbsp;&amp;&nbsp;Request("nYear"))
%&gt;
</FONT></PRE>
<P><FONT size=4>RemoveEvent.asp&nbsp;页使用&nbsp;<STRONG>DeleteEvent</STRONG>&nbsp;存储过程来删除给定的事件&nbsp;ID，然后立即向用户发送回“事件”页。</FONT></P>
<P><FONT size=4><BR></FONT></P>
<H2><A class="" name=calendar_topic4></A><FONT size=4>性能问题</FONT></H2>
<P><STRONG><FONT size=4>伸展</FONT></STRONG></P>
<P><FONT size=4>ASP&nbsp;的美妙之处在于它使建立&nbsp;Web&nbsp;页变得十分容易。然而，如果您希望建立一个可以适应大量用户的站点，则您需要仔细编码。在本节中我将讨论增强我在这里所提供的基于&nbsp;Web&nbsp;的日历的可伸缩性的各种方法。虽然我说明的这些方法是针对此应用程序的，但是它们可用于提高任何&nbsp;ASP&nbsp;Web&nbsp;站点上的性能。</FONT></P>
<P><STRONG><FONT size=4>SQL&nbsp;优化</FONT></STRONG></P>
<P><FONT size=4>提高站点性能的一个简单方法是给&nbsp;Schedule&nbsp;表的&nbsp;date&nbsp;字段添加一个索引。这将加速&nbsp;<STRONG>GetEvents</STRONG>&nbsp;存储过程，其原因是它在给定日期之间查找事件。</FONT></P>
<P><FONT size=4>对于小站点，可以将&nbsp;SQL&nbsp;与&nbsp;IIS&nbsp;安装在同一服务器上。一旦站点开始增长，您就会希望将&nbsp;SQL&nbsp;移动到其自身的服务器上。当站点进一步增长时，您可能希望添加均指向同一&nbsp;SQL&nbsp;服务器的多个&nbsp;IIS&nbsp;服务器。如果到&nbsp;SQL&nbsp;服务器的通信量过度增长，您就可以将数据分割到不同的服务器上。您可能想将奇数月份分配到一台服务器，将偶数月份分配到另一台服务器上。当然，您将希望修改&nbsp;header.asp&nbsp;中的&nbsp;<STRONG>GetDataConnection</STRONG>，以便它为您提供基于此月份的正确连接。</FONT></P>
<P><STRONG><FONT size=4>ASP&nbsp;优化</FONT></STRONG></P>
<P><FONT size=4>ASP&nbsp;解释的主要优化将是高速缓存页面，以便无需每次都对它们进行解释。做到这一点的最简易的方法是借助&nbsp;ASP&nbsp;<STRONG>Application</STRONG>&nbsp;对象。要做到这一点，您只是将页&nbsp;HTML&nbsp;保存到含有月份和年份名称的应用程序变量（例如&nbsp;Calendar07-2000）中。然后,当显示&nbsp;Event&nbsp;Calendar&nbsp;页时，您首先检查一下看看日历是否已经保存在应用程序变量中，如果是这样，只需检索它。这省去了到&nbsp;SQL&nbsp;框的过程。下面的一些伪代码显示这是如何工作的：</FONT></P><PRE class=clsCode><FONT size=4>&lt;&lt;do&nbsp;header&gt;&gt;

ShowCalendar(nMonth,&nbsp;nYear)

&lt;&lt;do&nbsp;Footer&gt;&gt;

sub&nbsp;ShowCalendar(nMonth,&nbsp;nYear)

&nbsp;&nbsp;&nbsp;if&nbsp;Application("Calendar"&nbsp;&amp;&nbsp;nMonth&nbsp;&amp;&nbsp;"-"&nbsp;&amp;&nbsp;nYear)&nbsp;=&nbsp;""&nbsp;then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;&lt;Build&nbsp;Calendar&gt;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Application("Calendar"&nbsp;&amp;&nbsp;nMonth&nbsp;&amp;&nbsp;"-"&nbsp;&amp;&nbsp;nYear)&nbsp;=&nbsp;&lt;&lt;Calendar&gt;&gt;
&nbsp;&nbsp;&nbsp;End&nbsp;if
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;Response.Write&nbsp;Application("Calendar"&nbsp;&amp;&nbsp;nMonth&nbsp;&amp;&nbsp;"-"&nbsp;&amp;&nbsp;nYear)&nbsp;
End&nbsp;sub
</FONT></PRE>
<P><FONT size=4>当然，在&nbsp;Events.asp&nbsp;页更改某个月份的事件时，您将需要清空该月份的应用程序变量，以便反映这些更改。</FONT></P>
<P><STRONG><FONT size=4>安全性</FONT></STRONG></P>
<P><FONT size=4>有几种方法可实现此站点上的安全性。对于&nbsp;intranet&nbsp;站点，基于&nbsp;Microsoft&nbsp;Windows&nbsp;NT®&nbsp;的验证是最容易设置的，其原因是您的用户将很可能已经登录到网络。您可能希望让所有用户查看&nbsp;Event&nbsp;Calendar&nbsp;页，但是只有管理员能访问&nbsp;Add/Remove&nbsp;Events&nbsp;页。</FONT></P>
<P><FONT size=4>如果关心审计，您可以容易地修改&nbsp;<STRONG>AddEvent</STRONG>&nbsp;和&nbsp;<STRONG>DeleteEvent</STRONG>&nbsp;过程将其信息保存到审计表中。您还可以确保&nbsp;IIS&nbsp;为每个页命中的查询字符串和用户进行日志记录。然后逐个分析日志以确定何人于何时做了什么，这是很简单的。</FONT></P>
<P><FONT size=4><BR></FONT></P>
<H2><A class="" name=calendar_topic5></A><FONT size=4>结论</FONT></H2>
<P><FONT size=4>在本文中我演示了如何建立基于&nbsp;Web&nbsp;的日历。我的基于&nbsp;Web&nbsp;的日历是很简单的，但是可以容易地将其扩展为功能完备的站点。我试图细致地说明创建基于&nbsp;Web&nbsp;的日历所遵循的步骤，以便入门用户可以看到在工作的&nbsp;ASP、SQL&nbsp;和&nbsp;ADO。最后，我提供了一些有关如何尽可能大地扩展此站点的几点技巧。如果您发现任何错误或者可能有什么想法能够改进此代码，请给我发送电子邮件，地址为&nbsp;<STRONG>semyan@hotmail.com</STRONG>。</FONT></P></H2></DIV></TD></TR></TBODY></TABLE><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1252225.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42942/" target="_blank">[新闻]Linux内核2.6.27正式到来</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>C#通讯编程(转)</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/07/11/1240654.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Fri, 11 Jul 2008 04:21:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/07/11/1240654.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1240654.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/07/11/1240654.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1240654.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1240654.html</trackback:ping><description><![CDATA[摘要: http://topic.csdn.net/u/20080623/08/4bbd2475-45f1-42e3-a613-16b094759ade.htmlSocket通讯: C# code public class XmlSocket { //异步socket诊听 // Incoming data from client.从客户端传来的数据 public static string data = &nbsp;&nbsp;<a href='http://www.cnblogs.com/lsjwzh/archive/2008/07/11/1240654.html'>阅读全文</a><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1240654.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42941/" target="_blank">[新闻]《星际争霸2》一分为三 各种族依次登场</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>ASP.NET中的Web.config详解</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/07/09/1238706.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Wed, 09 Jul 2008 02:39:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/07/09/1238706.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1238706.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/07/09/1238706.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1238706.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1238706.html</trackback:ping><description><![CDATA[<P><STRONG>Applications of <A class=glossary title="eXtensible Markup Language, or XML, is a text markup language designed for the easy sharing of data." href="http://www.sitepoint.com/glossary.php?q=X#term_3">XML</A> have been integrated into <A class=glossary title=".NET is an application framework from Microsoft." href="http://www.sitepoint.com/glossary.php?q=%23#term_2">.NET</A> to such an extent that XML is hardly a buzzword anymore. Microsoft, as you probably know, has taken XML into the core of its .NET framework. Not only is XML a generally accepted format for the exchange of data, it's also used to store configuration settings.</STRONG></P>
<P>Configuration settings for any of your <A class=glossary title=".NET is an application framework from Microsoft." href="http://www.sitepoint.com/glossary.php?q=%23#term_2">ASP.NET</A> Web applications can be stored in a simple text file. Presented in an easily understandable XML format, this file, called Web.config, can contain application-wide data such as database connection strings, custom error messages, and culture settings. </P>
<P>Because the Web.config is an XML file, it can consist of any valid XML tags, but the root element should always be <CODE>&lt;configuration&gt;</CODE>. Nested within this tag you can include various other tags to describe your settings. Since a Web.config file comes as a standard when you start to build a new Web application, let's look at the default XML file generated by Visual Studio .NET:</P>
<P><CODE>&lt;?xml version="1.0" encoding="utf-8" ?&gt; <BR>&lt;configuration&gt; <BR>&nbsp;&lt;system.web&gt; <BR>&nbsp; &nbsp;&lt;compilation &nbsp;<BR>&nbsp; &nbsp; &nbsp; &nbsp; defaultLanguage="c#" <BR>&nbsp; &nbsp; &nbsp; &nbsp; debug="true" <BR>&nbsp; &nbsp;/&gt; <BR>&nbsp; &nbsp;&lt;customErrors &nbsp;<BR>&nbsp; &nbsp;mode="RemoteOnly" &nbsp;<BR>&nbsp; &nbsp;/&gt; &nbsp;<BR>&nbsp; &nbsp;&lt;authentication mode="Windows" /&gt; &nbsp;<BR>&nbsp; &nbsp;&lt;authorization&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp;&lt;allow users="*" /&gt; <BR>&nbsp; &nbsp;&lt;/authorization&gt; <BR>&nbsp; &nbsp;&lt;trace <BR>&nbsp; &nbsp; &nbsp; &nbsp;enabled="false" <BR>&nbsp; &nbsp; &nbsp; &nbsp;requestLimit="10" <BR>&nbsp; &nbsp; &nbsp; &nbsp;pageOutput="false" <BR>&nbsp; &nbsp; &nbsp; &nbsp;traceMode="SortByTime" <BR>&nbsp; &nbsp;localOnly="true" <BR>&nbsp; &nbsp;/&gt; <BR>&nbsp; &nbsp;&lt;sessionState &nbsp;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mode="InProc" <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;stateConnectionString="tcpip=127.0.0.1:42424" <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cookieless="false" &nbsp;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;timeout="20" &nbsp;<BR>&nbsp; &nbsp;/&gt; <BR>&nbsp; &nbsp;&lt;globalization &nbsp;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;requestEncoding="utf-8" &nbsp;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;responseEncoding="utf-8" &nbsp;<BR>&nbsp; /&gt; <BR>&nbsp; &nbsp;<BR>&lt;/system.web&gt; <BR><BR>&lt;/configuration&gt;</CODE></P>
<P>Experienced ASP.NET programmers will have noticed that I've left out the comment tags that are generated automatically with the file. I've done that to provide a clear view of the XML that's used here. Also, I'll elaborate on each configuration tag later in this article, and this discussion will make the comment tags rather obsolete.</P>
<P>If you look at the example XML, you'll notice that the <CODE>&lt;configuration&gt;</CODE> tag has only one child tag, which we call section group, the <CODE>&lt;system.web&gt;</CODE> tag. A section group typically contains the setting sections, such as: <CODE>compilation</CODE>, <CODE>customErrors</CODE>, <CODE>authentication</CODE>, <CODE>authorization</CODE>, etc. The way this works is pretty straightforward: you simply include your settings in the appropriate setting sections. If, for example, you wanted to use a different authentication mode for your Web application, you'd change that setting in the authentication section.</P>
<P>Apart from the standard system.web settings, you can define your own specific application settings, such as a database connection string, using the <CODE>&lt;appSettings&gt;</CODE> tag. Consequently, your most common Web.config outline would be: </P>
<P><CODE>&lt;configuration&gt; <BR>&nbsp;&lt;system.web&gt; <BR>&nbsp; &nbsp;&lt;!— sections--&gt; &nbsp; &nbsp;<BR>&nbsp;&lt;/system.web&gt; <BR>&nbsp;&lt;appSettings&gt; <BR>&nbsp; &nbsp;&lt;!— sections --&gt; &nbsp; &nbsp;<BR>&nbsp;&lt;/appSettings &gt; <BR>&lt;/configuration&gt;</CODE></P>
<P><CODE></CODE>Let's discuss the details of both section groups now.</P>
<H5>The <CODE>system.web</CODE> Section Group</H5>
<P>In this section group, you'll typically include configuration settings that, in the pre-.NET era, you'd have set up somewhere in the IIS administration console. At Microsoft's MSDN Library, you can find <A class=sublink href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/gngrfSystemwebElement.asp" target=_blank rel=external>an overview of all the tags that the system.web section group understands</A>, but, depending on the complexity of your site, you may not ever use even half of those options.</P>
<P>Let's have a look at the most valuable tweaks you can make within the system.web section group, in alphabetical order. </P>
<P><STRONG><CODE>&lt;authentication&gt;</CODE></STRONG></P>
<P>The authentication section controls the type of authentication used within your Web application, as contained in the attribute mode. You'll enter the value "None" if anyone may access your application. If authentication is required, you'll use "Windows", "Forms" or "Passport" to define the type of authentication. For example:</P>
<P><CODE>&nbsp; &nbsp;&lt;authentication mode="Windows" /&gt;</CODE></P>
<P><CODE><STRONG>&lt;authorization&gt;</STRONG></CODE></P>
<P>To allow or deny access to your web application to certain users or roles, use <CODE>&lt;allow&gt;</CODE> or <CODE>&lt;deny&gt;</CODE> child tags. </P>
<P><CODE>&nbsp; &nbsp;&lt;authorization&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp;&lt;allow roles="Administrators,Users" /&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp;&lt;deny users="*" /&gt; <BR>&nbsp; &nbsp;&lt;/authorization&gt;</CODE></P>
<P>It's important to understand that ASP.NET's authorization module iterates through the sections, applying the first rule that corresponds to the current user. In this example, users carrying the role Administrators or Users will be allowed access, while all others (indicated by the * wildcard) will encounter the second rule and will subsequently be denied access.</P>
<P><CODE><STRONG>&lt;compilation&gt;</STRONG></CODE></P>
<P>Here, you can configure the compiler settings for ASP.NET. You can use loads of attributes here, of which the most common are <CODE>debug</CODE> and <CODE>defaultLanguage</CODE>. Set debug to "true" only if you want the browser to display debugging information. Since turning on this option reduces performance, you'd normally want to set it to "false". The <CODE>defaultLanguage</CODE> attribute tells ASP.NET which language compiler to use, since you could use either Visual Basic .NET or C# for instance. It has value <CODE>vb</CODE> by default. </P>
<P><CODE><STRONG>&lt;customErrors&gt;</STRONG></CODE></P>
<P>To provide your end users with custom, user-friendly error messages, you can set the mode attribute of this section to <CODE>On</CODE>. If you set it to <CODE>RemoteOnly</CODE>, custom errors will be shown only to remote clients, while local host users will see the ugly but useful ASP.NET errors -- clearly, this is helpful when debugging. Setting the mode attribute to <CODE>Off</CODE> will show ASP.NET errors to all users.</P>
<P>If you supply a relative (for instance, /error404.html) or absolute address (http://yourdomain.com/error404.html) in the <CODE>defaultRedirect</CODE> attribute, the application will be automatically redirected to this address in case of an error. Note that the relative address is relative to the location of the Web.config file, not the page in which the error takes place. In addition you can use <CODE>&lt;error&gt;</CODE> tags to provide a <CODE>statusCode</CODE> and a <CODE>redirect</CODE> attribute:</P>
<P><CODE>&nbsp; &nbsp;&lt;customErrors mode="RemoteOnly" defaultRedirect="/error.html"&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp;&lt;error statusCode="403" redirect="/accessdenied.html" /&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp;&lt;error statusCode="404" redirect="/pagenotfound.html" /&gt; <BR>&nbsp; &nbsp;&lt;/customErrors&gt;</CODE></P>
<P><CODE><STRONG>&lt;globalization&gt;</STRONG></CODE></P>
<P>The globalization section is useful when you want to change the encoding or the culture of your application. Globalization is such an extensive subject that an entire article could be dedicated to the matter. In short, this section allows you to define which character set the server should use to send data to the client (for instance UTF-8, which is the default), and which settings the server should use to interpret and displaying culturally specific strings, such as numbers and dates.</P>
<P><CODE>&nbsp; &nbsp;&lt;globalization requestEncoding="utf-8" responseEncoding="utf-8" &nbsp;<BR>&nbsp; &nbsp; &nbsp; &nbsp;culture="nl-NL" /&gt;</CODE></P>
<P>Encoding is done through the attributes <CODE>requestEncoding</CODE> and <CODE>responseEncoding</CODE>. The values should be equal in all one-server environments. In this example, the application culture is set to Dutch. If you don't supply a culture, the application will use the server's regional settings.</P>
<P><STRONG><CODE>&lt;httpRuntime&gt;</CODE></STRONG></P>
<P>You can use the <CODE>httpRuntime</CODE> section to configure a number of general runtime settings, two of which are particularly convenient. </P>
<P><CODE>&nbsp; &nbsp;&lt;httpRuntime appRequestQueueLimit="100" executionTimeout="600" /&gt;</CODE></P>
<P>The first attribute specifies the number of requests the server may queue in memory at heavy-traffic times. In the example, if there are already 100 requests waiting to be processed, the next request will result in a 503 error ("Server too busy"). </P>
<P>The <CODE>executionTimeout</CODE> attribute indicates the number of seconds for which ASP.NET may process a request before it's timed out.</P>
<P><STRONG><CODE>&lt;sessionState&gt;</CODE></STRONG></P>
<P>In this section of the Web.config file, we tell ASP.NET where to store the session state. The default is in the process self:</P>
<P><CODE>&nbsp; &nbsp;&lt;sessionState mode="InProc" /&gt;</CODE></P>
<P>Session variables are very powerful, but they have a few downsides. Information is lost when the ASP.NET process crashes, and sessions are generally useless in the case of a Web farm (multiple Web servers). In that instance, a shared session server can solve your issues. It's beyond the scope of this article to expand on this topic, but it's worth a mention. <A class=sublink href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/gngrfSessionstateSection.asp" target=_blank rel=external>More information on sessionState</A> can be found in the MSDN Library online.</P>
<P><STRONG><CODE>&lt;trace&gt;</CODE></STRONG></P>
<P>Your application's trace log is located in the application root folder, under the name <CODE>trace.axd</CODE>. You can change the display of tracing information in the trace section. </P>
<P>The attributes you will look for initially are enabled: <CODE>localOnly</CODE>, and <CODE>pageOutput</CODE>.</P>
<P><CODE>&nbsp; &nbsp;&lt;trace enabled="true" localOnly="true" pageOutput="false" /&gt;</CODE></P>
<P>Set <CODE>localOnly</CODE> to "false" to access the trace log from any client. If you set the value of <CODE>pageOutput</CODE> to "true", tracing information will be added to the bottom of each Web page.</P>
<H5>The <CODE>appSettings</CODE> Section Group</H5>
<P>Apart from the Website configuration settings I've been talking about in the preceding paragraphs, you'll know that a programmer frequently likes to use custom application-wide constants to store information over multiple pages. The most appealing example of such a custom constant is a database connection string, but you can probably think of dozens more from your own experience.</P>
<P>The common denominator of these constants is that you want to retrieve their values programmatically from your code. The Web.config file provides the possibility to do so, but as a security measure, these constants have to be included in the <CODE>&lt;appSettings&gt;</CODE> section group. Just like <CODE>&lt;system.web&gt;</CODE>, <CODE>&lt;appSettings&gt;</CODE> is a direct child tag of the Web.config's configuration root.</P>
<P>A typical custom section group would look something like this:</P>
<P><CODE>&nbsp; &nbsp;&lt;appSettings&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp;&lt;add key="sqlConn" value="Server=myPc;Database=Northwind" /&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp;&lt;add key="smtpServer" value="smtp.mydomain.com" /&gt; <BR>&nbsp; &nbsp;&lt;/appSettings&gt;</CODE></P>
<P>The example shows that keys and values can be included in the custom application settings via an <CODE>&lt;add&gt;</CODE> tag. The way to access such a value in any of your Web pages is illustrated below:</P>
<P><CODE>&nbsp; &nbsp;ConfigurationSettings.AppSettings["sqlConn"]</CODE></P>
<P>Yes, it's as easy as that! Note that the value of these settings is always a String format.</P>
<H5>A Few Other Issues</H5>
<P>I won't go into them here, but the Web.config file can contain several other section groups besides the aforementioned <CODE>system.web</CODE> and <CODE>appSettings</CODE>, such as the <CODE>configSettings</CODE> group.</P>
<P mce_keep="true">&nbsp;</P>
<UL>
<LI>A Web application can contain more than one Web.config file. The settings in a file apply to the directory in which it's located, and all child directories. Web.config files in child directories take precedence over the settings that are specified in parent directories. 
<LI>Web.config files are protected by IIS, so clients cannot get to them. If you try to retrieve an existing http://mydomain.com/Web.config file, you'll be presented with an "Access denied" error message. 
<LI>IIS monitors the Web.config files for changes and caches the contents for performance reasons. There's no need to restart the Web server after you modify a Web.config file. </LI></UL>
<P mce_keep="true">&nbsp;</P>
<H5>Closing Remarks</H5>
<P>In this article, I've touched upon the possibilities that the Web.config file offers the ASP.NET programmer. You can use the easily <A class=glossary title='Accessibility deals with the issues of making online content available for experience, enjoyment, and use by all visitors, including those who do not fit the standard "Web user" mould.' href="http://www.sitepoint.com/glossary.php?q=A#term_61">accessible</A> XML file to define your application settings, without the hassle of using the IIS management console. With the Web.config file, ASP.NET lets you add, change and delete basic configuration settings like authentication and authorization, custom error displaying, and tracing in a straightforward manner.</P>
<P>Moreover, the Web.config file offers you room to define any custom key you require, such as database connection strings. What we've subsequently seen is that, with just one line of code, you can retrieve the information you need from any page in your application.</P><img src ="http://www.cnblogs.com/lsjwzh/aggbug/1238706.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42940/" target="_blank">[新闻]IBM花300万美元打造互联网三维虚拟紫禁城</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Web.config详解(转)</title><link>http://www.cnblogs.com/lsjwzh/archive/2008/07/09/1238703.html</link><dc:creator>lsjwzh</dc:creator><author>lsjwzh</author><pubDate>Wed, 09 Jul 2008 02:38:00 GMT</pubDate><guid>http://www.cnblogs.com/lsjwzh/archive/2008/07/09/1238703.html</guid><wfw:comment>http://www.cnblogs.com/lsjwzh/comments/1238703.html</wfw:comment><comments>http://www.cnblogs.com/lsjwzh/archive/2008/07/09/1238703.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/lsjwzh/comments/commentRss/1238703.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/lsjwzh/services/trackbacks/1238703.html</trackback:ping><description><![CDATA[<TABLE class="" style="TABLE-LAYOUT: fixed">
<TBODY>
<TR>
<TD class="">
<DIV class=cnt id=blog_text>一、认识Web.config文件<BR>Web.config 文件是一个xml文本文件，它用来储存 asp.NET Web 应用程序的配置信息（如最常用的设置asp.NET Web 应用程序的身份验证方式），它可以出现在应用程序的每一个目录中。当你通过.NET新建一个Web应用程序后，默认情况下会在根目录自动创建一个默认的Web.config文件，包括默认的配置设置，所有的子目录都继承它的配置设置。如果你想修改子目录的配置设置，你可以在该子目录下新建一个Web.config文件。它可以提供除从父目录继承的配置信息以外的配置信息，也可以重写或修改父目录中定义的设置。<BR>(一).Web.Config是以xml文件规范存储,配置文件分为以下格式<BR>1.配置节处理程序声明<BR>特点：位于配置文件的顶部，包含在&lt;configSections&gt;标志中。<BR>2.特定应用程序配置<BR>特点: 位于&lt;appSetting&gt;中。可以定义应用程序的全局常量设置等信息.<BR>3.配置节设置<BR>特点: 位于&lt;system.Web&gt;节中，控制asp.net运行时的行为.<BR>4.配置节组<BR>特点: 用&lt;sectionGroup&gt;标记，可以自定义分组，可以放到&lt;configSections&gt;内部或其它&lt;sectionGroup&gt;标记的内部.<BR>(二).配置节的每一节<BR>1.&lt;configuration&gt;节根元素，其它节都是在它的内部.<BR>2.&lt;appSetting&gt;节此节用于定义应用程序设置项。对一些不确定设置，还可以让用户根据自己实际情况自己设置<BR>用法:<BR>I.&lt;appSettings&gt;<BR>&lt;add key="Conntction" value="server=192.168.85.66;userid=sa;password=;database=Info;"/&gt;<BR>&lt;appSettings&gt;<BR>定义了一个连接字符串常量，并且在实际应用时可以修改连接字符串，不用修改程式代码.<BR>II.&lt;appSettings&gt;<BR>&lt;add key="ErrPage" value="Error.aspx"/&gt;&lt;appSettings&gt; 定义了一个错误重定向页面.<BR>3.&lt;compilation&gt;节<BR>格式:<BR>&lt;compilation <BR>defaultLanguage="c#"<BR>debug="true"<BR>/&gt;<BR>I.default language: 定义后台代码语言,可以选择c#和vb.net两种语言.<BR>IIdebug : 为true时，启动aspx调试；为false不启动aspx调试，因而可以提高应用程序运行时的性能。一般程序员在开发时设置为true,交给客户时设置为false.<BR>4.&lt;customErrors&gt;节<BR>格式:<BR>&lt;customErrors <BR>mode="RemoteOnly" <BR>defaultRedirect="error.aspx"<BR>&lt;error statusCode="440" redirect="err440page.aspx"/&gt;<BR>&lt;error statusCode="500" redirect="err500Page.aspx"/&gt;<BR>/&gt; <BR>I.mode : 具有On,Off,RemoteOnly 3种状态。On表示始终显示自定义的信息; Off表示始终显示详细的asp.net错误信息; RemoteOnly表示只对不在本地Web服务器上运行的用户显示自定义信息.<BR>II.defaultRedirect: 用于出现错误时重定向的URL地址. 是可选的<BR>III.statusCode: 指明错误状态码，表明一种特定的出错状态.<BR>IV. redirect:错误重定向的URL.<BR>5.&lt;globalization&gt;节<BR>格式:<BR>&lt;globalization <BR>requestEncoding="utf-8" <BR>responseEncoding="utf-8" <BR>fileEncoding="utf-8"<BR>/&gt; <BR>I.requestEncoding: 它用来检查每一个发来请求的编码. <BR>II.responseEncoding: 用于检查发回的响应内容编码.<BR>III.fileEncoding: 用于检查aspx,asax等文件解析的默认编码. <BR>6.&lt;sessionState&gt;节<BR>格式:<BR>&lt;sessionState <BR>mode="InProc"<BR>stateConnectionString="tcpip=127.0.0.1:42424"<BR>sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"<BR>cookieless="false" <BR>timeout="20" <BR>/&gt;<BR>I.mode: 分为off,Inproc,StateServer,SqlServer几种状态<BR>mode = InProc 存储在进程中特点：具有最佳的性能，速度最快,但不能跨多台服务器存储共享.mode = "StateServer" 存储在状态服务器中特点:&nbsp;&nbsp;&nbsp; 当需要跨服务器维护用户会话信息时，使用此方法。但是信息存储在状态服务器上，一旦状态服务器出现故障，信息将丢失. mode="SqlServer" 存储在sql server中特点:工作负载会变大，但信息不会丢失.<BR>II. stateConnectionString :指定asp.net应用程序存储远程会话状态的服务器名，默认为本机<BR>III.sqlConnectionString:当用会话状态数据库时，在这里设置连接字符串<BR>IV. Cookieless:设置为true时，表示不使用cookie会话状态来标识客户；否则，相反.<BR>V. TimeOut:用来定义会话状态存储的时间，超过期限，将自动终止会话.<BR>7.&lt;authentication&gt;节<BR>格式:<BR>&lt;authentication mode="Forms"&gt; <BR>&lt;forms name=".ASPXUSERDEMO" loginUrl="Login.aspx" protection="All" timeout="30"/&gt;<BR>&lt;/authentication&gt;<BR>&lt;authorization&gt;<BR>&lt;deny users="?"/&gt;<BR>&lt;/authorization&gt;<BR>I.Windows: 使用IIS验证方式<BR>II.Forms: 使用基于窗体的验证方式<BR>III.Passport: 采用Passport cookie验证模式<BR>IV.None: 不采用任何验证方式<BR>里面内嵌Forms节点的属性涵义:<BR>I.Name: 指定完成身份验证的Http cookie的名称.<BR>II.LoginUrl: 如果未通过验证或超时后重定向的页面URL，一般为登录页面，让用户重新登录<BR>III.Protection: 指定 cookie数据的保护方式.<BR>可设置为: All None Encryption Validation四种保护方式<BR>a. All表示加密数据，并进行有效性验证两种方式<BR>b. None表示不保护Cookie.<BR>c. Encryption表示对Cookie内容进行加密<BR>d. validation表示对Cookie内容进行有效性验证<BR>IV. TimeOut: 指定Cookie的失效时间. 超时后要重新登录.<BR>在运行时对Web.config文件的修改不需要重启服务就可以生效（注：&lt;processModel&gt; 节例外）。当然Web.config文件是可以扩展的。你可以自定义新配置参数并编写配置节处理程序以对它们进行处理。<BR>web.config配置文件（默认的配置设置）以下所有的代码都应该位于<BR>&lt;configuration&gt;<BR>&lt;system.web&gt;<BR>和<BR>&lt;/system.web&gt;<BR>&lt;/configuration&gt;<BR>之间，出于学习的目的下面的示例都省略了这段xml标记。<BR>1、&lt;authentication&gt; 节<BR>作用：配置 asp.NET 身份验证支持（为Windows、Forms、PassPort、None四种）。该元素只能在计算机、站点或应用程序级别声明。&lt; authentication&gt; 元素必需与&lt;authorization&gt; 节配合使用。<BR>示例：<BR>以下示例为基于窗体（Forms）的身份验证配置站点，当没有登陆的用户访问需要身份验证的网页，网页自动跳转到登陆网页。<BR>&lt;authentication mode="Forms" &gt;<BR>&lt;forms loginUrl="logon.aspx" name=".FormsAuthCookie"/&gt;<BR>&lt;/authentication&gt;<BR>其中元素loginUrl表示登陆网页的名称，name表示Cookie名称。<BR>2、&lt;authorization&gt; 节<BR>作用：控制对 URL 资源的客户端访问（如允许匿名用户访问）。此元素可以在任何级别（计算机、站点、应用程序、子目录或页）上声明。必需与&lt;authentication&gt; 节配合使用。<BR>示例：以下示例禁止匿名用户的访问<BR>&lt;authorization&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;deny users="?"/&gt;<BR>&lt;/authorization&gt;<BR>注：你可以使用user.identity.name来获取已经过验证的当前的用户名；可以使用web.Security.FormsAuthentication.RedirectFromLoginPage方法将已验证的用户重定向到用户刚才请求的页面.具体的<BR>3、&lt;compilation&gt;节<BR>作用：配置 asp.NET 使用的所有编译设置。默认的debug属性为“True”.在程序编译完成交付使用之后应将其设为False（Web.config文件中有详细说明，此处省略示例）<BR>4、&lt;customErrors&gt; <BR>作用：为 asp.NET 应用程序提供有关自定义错误信息的信息。它不适用于 xml Web services 中发生的错误。<BR>示例：当发生错误时，将网页跳转到自定义的错误页面。<BR>&lt;customErrors defaultRedirect="ErrorPage.aspx" mode="RemoteOnly"&gt;<BR>&lt;/customErrors&gt;<BR>其中元素defaultRedirect表示自定义的错误网页的名称。mode元素表示：对不在本地 Web 服务器上运行的用户显示自定义(友好的)信息。<BR>5、&lt;httpRuntime&gt;节<BR>作用：配置 asp.NET HTTP 运行库设置。该节可以在计算机、站点、应用程序和子目录级别声明。<BR>示例：控制用户上传文件最大为4M，最长时间为60秒，最多请求数为100<BR>&lt;httpRuntime maxRequestLength="4096" executionTimeout="60" appRequestQueueLimit="100"/&gt;<BR>6、 &lt;pages&gt; <BR>作用：标识特定于页的配置设置（如是否启用会话状态、视图状态，是否检测用户的输入等）。&lt;pages&gt;可以在计算机、站点、应用程序和子目录级别声明。<BR>示例：不检测用户在浏览器输入的内容中是否存在潜在的危险数据（注：该项默认是检测，如果你使用了不检测，一要对用户的输入进行编码或验证)，在从客户端回发页时将检查加密的视图状态，以验证视图状态是否已在客户端被篡改。(注：该项默认是不验证）<BR>&lt;pages buffer="true" enableViewStateMac="true" validateRequest="false"/&gt;<BR>7、&lt;sessionState&gt; <BR>作用：为当前应用程序配置会话状态设置（如设置是否启用会话状态，会话状态保存位置）。<BR>示例：<BR>&lt;sessionState mode="InProc" cookieless="true" timeout="20"/&gt;<BR>&lt;/sessionState&gt;<BR>注：<BR>mode="InProc"表示：在本地储存会话状态（你也可以选择储存在远程服务器或SAL服务器中或不启用会话状态）<BR>cookieless="true"表示：如果用户浏览器不支持Cookie时启用会话状态(默认为False）<BR>timeout="20"表示：会话可以处于空闲状态的分钟数<BR>8、&lt;trace&gt; <BR>作用：配置 asp.NET 跟踪服务，主要用来程序测试判断哪里出错。<BR>示例：以下为Web.config中的默认配置：<BR>&lt;trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" /&gt;<BR>注：<BR>enabled="false"表示不启用跟踪；<BR>requestLimit="10"表示指定在服务器上存储的跟踪请求的数目<BR>pageOutput="false"表示只能通过跟踪实用工具访问跟踪输出；<BR>traceMode="Sort