﻿<?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>博客园-licongjie的博客</title><link>http://www.cnblogs.com/licongjie/</link><description>专心、专注、专业</description><language>zh-cn</language><lastBuildDate>Mon, 06 Jul 2009 11:40:21 GMT</lastBuildDate><pubDate>Mon, 06 Jul 2009 11:40:21 GMT</pubDate><ttl>60</ttl><item><title>实战小技巧系列(4)：WinForm简单步骤制作</title><link>http://www.cnblogs.com/licongjie/archive/2008/05/07/1186291.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Wed, 07 May 2008 01:51:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2008/05/07/1186291.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/1186291.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2008/05/07/1186291.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/1186291.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/1186291.html</trackback:ping><description><![CDATA[<p>　　进行类似于上一步，下一步的操作，是比较常见的，在WebAppliction中自从２.０发布以后到是已经有类似控件可以操作了，不知道为什么在Winform中好象没有该控件（我没有确认过，不知道是否真的没有？）。所以没有办法，只好自己做了。</p>
<p>　　<strong style="color: #0000a0">问题：</strong></p>
<p>　　由于最近要做一个软件的升级程序，程序本身比较简单，无非是执行一些ＳＱＬ语句，覆盖一些文件而已，但我想模仿安装程序一样，可以进行步骤操作，基本要求如下：</p>
<p>　　１、具有上一步，下一步操作；</p>
<p>　　２、进行上一步和下一步操作时，能够保持原有状态，如我已经在这一步骤中录入了一些数据，点击下一步后，发现需要退回来修改，这时点击上一步返回前一步骤，那原来录入的数据必须还在；</p>
<p>　　其实需求很简单，这里主要是讲一下我的思路，从而希望大家能够提出自己的想法，进一步完善。</p>
<p>　　<strong style="color: #000080">解决方法：</strong></p>
<p>　　其实，对于winform来讲，没有多少经验，本人主要是从事webapplicatioin开发，这次为了做这个升级程序，也查询了一些资料，网上查到有一个，利用命令模式来操作步骤（忘记是看自哪里了）。本文里提到的解决方法根据这个演变而来，所有的步骤都是用用户控件来实现。好了不多说了，直接看代码吧：</p>
<p>　　１、创建步骤基类</p>
<p>　　namespace EcsPatch.PatchWizard<br />
　　{<br />
　　 public class BaseWizard : UserControl<br />
　　{<br />
<br />
<br />
　　}<br />
　　}</p>
<p>　　其实如果简单的话这个基类根本就不用创建，因为所有的用户控件，本身就继承自UserControl基类的。这里还要另写一个，主要是因为可能会有一些共用方法，为了便于重用，所以另外创建一个。</p>
<p>　　２、所有的用户控件都继承１中创建的基类</p>
<p>　　namespace EcsPatch.PatchWizard<br />
　　{<br />
　　　　public partial class TipModel : BaseWizard<br />
　　　　{<br />
　　　　　 public TipModel()<br />
　　　　　{<br />
　　　　　　 InitializeComponent();<br />
　　　　　}<br />
　　　　}<br />
　　}</p>
<p>　　其它步骤的用户控件也类似，不一一贴代码了。</p>
<p>　　３、创建辅助类</p>
<p>　　namespace EcsPatch.Component<br />
　　{<br />
　　　public class WizardUtil<br />
　　　{<br />
　　　　private static Dictionary&lt;WizardItem, BaseWizard&gt; wizardList;</p>
<p>　　　　 /// &lt;summary&gt;<br />
　　　　/// 初始化步骤列表<br />
　　　　/// &lt;/summary&gt;<br />
　　　　 public WizardUtil()<br />
　　　　{<br />
　　　　　wizardList = new Dictionary&lt;WizardItem, BaseWizard&gt;();<br />
　　　　　wizardList[WizardItem.Tip] = new TipModel();<br />
　　　　　wizardList[WizardItem.SelectPath] = new SelectPathModel();<br />
　　　　　wizardList[WizardItem.VersionTip] = new VersionTipModel();<br />
　　　　　wizardList[WizardItem.StartPatch] = new StartPatchModel();<br />
　　　　　wizardList[WizardItem.Complete] = new CompleteModel();<br />
　　　　}</p>
<p>　　　　 /// &lt;summary&gt;<br />
　　　　/// 更新步骤信息<br />
　　　　/// &lt;/summary&gt;<br />
　　　　 /// &lt;param name="key"&gt;&lt;/param&gt;<br />
　　　　/// &lt;param name="wizard"&gt;&lt;/param&gt;<br />
　　　　 public void SetWizard(WizardItem key, BaseWizard wizard)<br />
　　　　{<br />
　　　　　wizardList[key] = wizard;<br />
　　　　}</p>
<p>　　　　/// &lt;summary&gt;<br />
　　　　/// 获取步骤信息<br />
　　　　/// &lt;/summary&gt;<br />
　　　　/// &lt;param name="key"&gt;&lt;/param&gt;<br />
　　　　/// &lt;returns&gt;&lt;/returns&gt;<br />
　　　　public BaseWizard GetWizard(WizardItem key)<br />
　　　　{<br />
　　　　　BaseWizard wizard = wizardList[key];</p>
<p>　　　　　 return wizard;<br />
　　　　 }</p>
<p>　　　　/// &lt;summary&gt;<br />
　　　　/// 根据状态获取步骤信息<br />
　　　　/// &lt;/summary&gt;<br />
　　　　/// &lt;param name="key"&gt;&lt;/param&gt;<br />
　　　　 /// &lt;param name="state"&gt;&lt;/param&gt;<br />
　　　　/// &lt;returns&gt;&lt;/returns&gt;<br />
　　　　public BaseWizard GetWizard(ref WizardItem key, WizardState state)<br />
　　　　{<br />
　　　　　 int position = (int)key;<br />
　　　　　if (state == WizardState.Next)<br />
　　　　　{<br />
　　　　　　position++;<br />
　　　　　}<br />
　　　　　else<br />
　　　　　{<br />
　　　　　　position--;<br />
　　　　　}<br />
　　　　　WizardItem current = (WizardItem)position;<br />
　　　　　key = current;<br />
　　　　　return GetWizard(current);<br />
　　　　}<br />
<br />
　　}</p>
<p>　　public enum WizardItem<br />
　　 {<br />
　　　Tip = 1,<br />
　　　SelectPath,<br />
　　　VersionTip,<br />
　　　StartPatch,<br />
　　　Complete<br />
　　}<br />
　　public enum WizardState<br />
　　{<br />
　　　Next = 1,<br />
　　　Previous,<br />
　　}<br />
　}<br />
<br />
　　主要是把所有的用户控件先初始化放在列表中，再加上一些方法来获取和更新这些用户控件的实例。主要实现思路如下：</p>
<p>　　Ａ、利用枚举类型，来获取当前步骤的上一步骤用户控件实例和下一步骤用户控件实例；</p>
<p>　　Ｂ、当执行上一步或下一步操作时，通过public void SetWizard(WizardItem key, BaseWizard wizard)方法，保存当前步骤实例，其实也就保存了当前步骤的状态信息，当再执行上一步，下一步时，从中取现来的用户控件实例，也将保存有这些信息。</p>
<p>　　４、主界面ＣＳ</p>
<p>　　private WizardUtil wizardUtil;</p>
<p>　　private WizardItem currentWizardKey;</p>
<p>　　private BaseWizard currentWizard;</p>
<p>　　这三个变量，第一个是辅助类的实例，currentWizardKey保存当前步骤枚举，currentWizard保存当前步骤的用户控件实例。</p>
<p>　　初始化获取第一个步骤：</p>
<p>　　 wizardUtil = new WizardUtil();</p>
<p>　　currentWizardKey = WizardItem.Tip;</p>
<p>　　currentWizard = wizardUtil.GetWizard(currentWizardKey);</p>
<p>　　InitWizard();　　</p>
<p>　　InitWizard方法：</p>
<p>　　private void InitWizard()<br />
{<br />
　MiddleSplit.Panel2.Controls.Clear();<br />
　MiddleSplit.Panel2.Controls.Add(currentWizard);<br />
　if (currentWizardKey == WizardItem.Tip)<br />
　{<br />
　　btnPrev.Enabled = false;<br />
　}<br />
　else if (currentWizardKey == WizardItem.Complete)<br />
　{　<br />
　　btnPrev.Enabled = false;<br />
　　btnNext.Enabled = false;<br />
　}<br />
　else<br />
　{<br />
　　btnPrev.Enabled = true;<br />
　　btnNext.Enabled = true;<br />
　}<br />
}</p>
<p>　　点击上一步骤操作：</p>
<p>　　//保存当前步骤信息<br />
wizardUtil.SetWizard(currentWizardKey, currentWizard);<br />
//获取下一步骤信息<br />
currentWizard = wizardUtil.GetWizard(ref currentWizardKey, WizardState.Next);<br />
InitWizard();</p>
<br />
<p>　　点击下一步骤操作：</p>
<p>　　//保存当前步骤信息<br />
wizardUtil.SetWizard(currentWizardKey, currentWizard);<br />
//获取前一步骤信息<br />
currentWizard = wizardUtil.GetWizard(ref currentWizardKey, WizardState.Previous);<br />
InitWizard();</p>
<br />
<p>　　代码很简单，但也确实能够实现这些基本功能，只是粗略的做了一下基本的结构，也不确定这种做法能不能满足复杂操作，一切还得靠大家自己看待了。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 源码下载：<a href="/Files/licongjie/EcsPatch.rar">/Files/licongjie/EcsPatch.rar</a></p>
<img src ="http://www.cnblogs.com/licongjie/aggbug/1186291.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48008/" target="_blank">IBM发布全球首款开源智能编译器</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>实战小技巧系列(4)：URL中包含中文参数造成乱码的解决之道</title><link>http://www.cnblogs.com/licongjie/archive/2008/05/05/1182843.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Mon, 05 May 2008 02:07:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2008/05/05/1182843.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/1182843.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2008/05/05/1182843.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/1182843.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/1182843.html</trackback:ping><description><![CDATA[
<p>　　中文乱码一直以来是ＷＥＢ开发中比较常见的问题之一，对于初学者来说，各种各样的编码方式可能会有点不适应，本篇文章并不讲述这些编码，而是把自己遇到的一个小问题以及该问题的解决之法说明一下，希望对大家有用。</p>
<p>　　<strong style="COLOR: #000080">问题：</strong></p>
<p>　　前段时间，在系统中做了一个类似于友情链接的功能块，一直运行良好，直到有一天加了类似于以下的链接地址：<a href="http://www.****.com/user.aspx?id">http://www.****.com/user.aspx?id</a>=水天，就出现大问题了：</p>
<p>　　１、从ＩＥ地址栏中直接输入这个地址，访问没错；</p>
<p>　　２、做一个静态页，其中包括这个超链接，点击访问也没错；</p>
<p>　　３、就是把这个链接添加到这个功能块中，点击访问那边接收到的是乱码。</p>
<p>　　一开始，被这个问题也搞得头大，在google了一把后，总算是把问题给搞清楚了，其实只要这个链接地址不经过任何编码传递是不会有问题的。但就是加到了这个功能块后，再点击，虽然这个时候在ＩＥ地址栏里显示的还是"<a href="http://www.****.com/user.aspx?id">http://www.****.com/user.aspx?id</a>=水天"，但真正传递过去的参数"水天"其实已经经过类似于Server.UrlEncode的操作了，当然默认是utf-8编码，正是由于这个原因，如果对方系统不进行相应的解码，直接操作该参数，就产生了以上的错误。</p>
<p>　　<strong style="COLOR: #000080">解决方法：</strong></p>
<p>　　网上有很多解决之道，最常见的莫过于以下几点：</p>
<p>　　１、在web.config里配制<span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">globalization</span> <span style="COLOR: #ff0000">requestEncoding</span><span style="COLOR: #0000ff">="gb2312"</span> <span style="COLOR: #ff0000">responseEncoding</span><span style="COLOR: #0000ff">="gb2312"</span> <span style="COLOR: #0000ff">/&gt;，<span style="COLOR: #000000">这个方法确实可行，但我想很多人不想用这种方法来解决，把整个项目的请求和回应都定为gb2312，我觉得不是一个好办法，有点本末倒置了，毕竟这会导致很多其它问题的出现。</span></span></p>
<p><span style="COLOR: #0000ff"><span style="COLOR: #000000">　　２、把要包含该链接的aspx文档，修改其charset属性为gb2312。这个方法到也可以接受，不过对于该文中的问题还不是最好的方法，因为该功能块是可以动态添加到任何页面的，难道要去修改所有的页面？想想还是不太合适。</span></span></p>
<p><span style="COLOR: #0000ff"><span style="COLOR: #000000">　　３、直接用Server.UrlEncode和Server.Decode进行加码和解码操作，这种方法对于发送方和接收方都在一个项目中是可行的，现在的问题是，我们要随意去访问别人的系统，所以只能弃用此方法了。</span></span></p>
<p><span style="COLOR: #0000ff"><span style="COLOR: #000000">　　４、采用HttpUtility.UrlEncode(query, System.Text.Encoding.GetEncoding("GB2312"));对链接中的参数值进行gb2312的编码，这种方法，对方不用进行任何解码操作，直接接收参数则不会出现乱码。</span></span></p>
<p><span style="COLOR: #0000ff"><span style="COLOR: #000000">　　一般提到最多的也就上面４种方法，其它的也跟这些大同小异。仔细分析后，觉得还是第４种方法最适合解决当前问题，把中文参数进行如４中的操作。但又出现另外一个问题，由于这是一个用户可以自由输入链接地址的功能，所以首先要做的就是得先分析这些链接ＵＲＬ，解析出参数，再对这些参数进行４中操作，然后再合拼成原来的ＵＲＬ地址。</span></span></p>
<p><span style="COLOR: #0000ff"><span style="COLOR: #000000">　　幸亏，ＵＲＬ参数解析Ｃ#已经有类库的支持，不用再去写那些复杂的正则表达式来匹配了。这里我也不详细说了，直接贴出原码：</span></span></p>
<p><span style="COLOR: #0000ff"><span style="COLOR: #000000">public static string InitChineseUrl(string chineseUrl)<br/>{<br/>Uri url = new Uri(chineseUrl);<br/>System.Collections.Specialized.NameValueCollection nv = System.Web.HttpUtility.ParseQueryString(url.Query, System.Text.Encoding.GetEncoding("utf-8"));<br/>string query = "";<br/>for (int i = 0; i &lt; nv.Count; i++)<br/>{<br/>if (query.Trim() == string.Empty)<br/>{<br/>query = "?" + nv.Keys[i] + "=" + HttpUtility.UrlEncode(nv[i], System.Text.Encoding.GetEncoding("GB2312"));<br/>}<br/>else<br/>{<br/>query += "&amp;" + nv.Keys[i] + "=" + HttpUtility.UrlEncode(nv[i], System.Text.Encoding.GetEncoding("GB2312"));<br/>}<br/>}<br/>string u = chineseUrl.Split('?')[0] + query;<br/>return u;<br/>}</span></span></p>
<p><span style="COLOR: #0000ff"><span style="COLOR: #000000">　　这里我是把所有的参数都进行gb2312编码操作了，反正参数如果是英文或者是数字，经过这些操作后还是不变的。</span></span></p>
<img src ="http://www.cnblogs.com/licongjie/aggbug/1182843.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48007/" target="_blank">IE颓势不减 微软下月公布最新浏览器架构</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>实战小技巧系列(3)：服务器端数据初始化到客户端数组中</title><link>http://www.cnblogs.com/licongjie/archive/2008/05/01/1178441.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Thu, 01 May 2008 01:29:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2008/05/01/1178441.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/1178441.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2008/05/01/1178441.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/1178441.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/1178441.html</trackback:ping><description><![CDATA[
<p>　　为了增强用户体验，也为了减少服务器端的回发操作，使得服务器端与客户端之间的交互越来越被广泛使用，各种ＡＪＡＸ产品的出现也正是顺应了这股潮流。　</p>
<p>　　在这里，我也不讲什么深奥的东西，只是把自己在开发当中遇到的一些实用的东西拿出来跟大家共享，希望不会有重的东西在。</p>
<p>　　<strong style="COLOR: #000080">案例：</strong></p>
<p>　　现在我希望能够从数据库里读出一个数据列表，再把这个列表初始化到客户端的一个数组中去。这是一个典型的客户端与服务器端的交互，相信大家一看到这个就会有好多种方法来实现，在这里我就帮大家稍微整理一下。</p>
<p>　　<span style="COLOR: #000080"><strong>解决方法：</strong></span></p>
<p>　　１、通过ＡＪＡＸ实现</p>
<p>　　很多人可能会选择这种方法，确实用这种方法很方便，对asp.net 中的ajax来说，就可以直接从服务器端返回一个数组了。</p>
<p>　　２、在客户端用服务器端标记循环实现</p>
<p>　　这种方法，相信以前如果做过ＡＳＰ的朋友一定比较熟悉，类似于以下代码：</p>
<p>　　&lt;script&gt;</p>
<p>　　var list = [];</p>
<p>&lt;% 服务器端循环开始%&gt;<br/></p>
<p>　　list.push(&lt;%循环值%&gt;);</p>
<p>　　&lt;%服务器端循环结束%&gt;</p>
<p>　　&lt;/script&gt;</p>
<p>　　３、用Page.ClientScript中的方法实现</p>
<p>　　在客户端先定义以下方法：</p>
<p>　　&lt;script&gt;</p>
<p>　　var list = [];</p>
<p>　　function AddObject(object)</p>
<p>　　{</p>
<p>　　　list.push(object);</p>
<p>　　}<br/></p>
<p>　　&lt;/script&gt;</p>
<br/><p>　　在服务器端：</p>
<p>　　for循环</p>
<p>　　{</p>
<p>　　　Page.ClientScript.RegisterStartupScript(this.GetType(), "dd", "AddObject("+循环值+");", true);</p>
<p>　　}</p>
<p>　４、我觉得这一个方法比较巧妙，我也经常使用。</p>
<p>　　客户端：</p>
<p>　　&lt;script&gt;</p>
<p>　　var list = [];</p>
<p>　　function AddObject(object)</p>
<p>　　{</p>
<p>　　　list.push(object);</p>
<p>　　}</p>
<p>　　 &lt;asp:Literal ID="userObjectUtil" runat="server"&gt;&lt;/asp:Literal&gt;<br/></p>
<p>　　&lt;/script&gt;</p>
<p>　　注意，在&lt;script&gt;&lt;/script&gt;标记中加入了一个服务器控件， &lt;asp:Literal ID="userObjectUtil" runat="server"&gt;&lt;/asp:Literal&gt;，微软的解析是够强的，放在这里在服务器端照样能够使用。</p>
<p>　　服务器端：</p>
<p>　　StringBuilder sb = new StringBuilder(200);</p>
<p>　　for循环</p>
<p>　　{</p>
<p>　　　sb.AppendFormat("AddObject('{0}');\n", 循环值);</p>
<p>　　}</p>
<p>　　 userObjectUtil.Text = sb.ToString();</p>
<br/><p>　 本人比较常用的就这么几种，不知道大家还有哪些好的方法。因为像这种应用，应该是越简单越好，没有必要搞得比较复杂。</p>
<img src ="http://www.cnblogs.com/licongjie/aggbug/1178441.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48002/" target="_blank">竞争日趋激烈 微软欲借 Windows 7 扭转战局</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>实战小技巧系列(2)：关于IIS6.0中应用程序池圆设置的问题</title><link>http://www.cnblogs.com/licongjie/archive/2008/03/30/1129770.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Sun, 30 Mar 2008 05:33:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2008/03/30/1129770.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/1129770.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2008/03/30/1129770.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/1129770.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/1129770.html</trackback:ping><description><![CDATA[
<p><span style="COLOR: #000080"><strong>　　关于应用程序池：</strong></span>这是微软的一个全新概念：应用程序池是将一个或多个应用程序链接到一个或多个工作进程集合的配置。因为应用程序池中的应用程序与其他应用程序被工作进程边界分隔，所以某个应用程序池中的应用程序不会受到其他应用程序池中应用程序所产生的问题的影响。这个功能是IIS6.0里新增的，它可以使得不同的ＷＥＢ应用程序运行在同一个ＩＩＳ时，不被互相干扰，从而当其中一个ＷＥＢ应用发生异常时，而其它的ＷＥＢ应用程序还能够正常运行。</p>
<p>　　<strong style="COLOR: #000080">关于ＷＥＢ圆：</strong>默认情况下，创建一个应用程序池的时候，ＷＥＢ圆的最大工作进程数为１，也就是在任务管理器中只有一个w3wp进程。而只有一个进程，它所能提供的资源是有限的，可并发性访问量也只能维持在一定的程度上，所以我们有时候为了提高资源的利用率，提高并发访问量，可以自定义ＷＥＢ圆的最大工作进程数，这时候，会在任务管理器中发现对应的w3wp进程数。</p>
<p>　　<strong style="COLOR: #000080">其中涉及问题：</strong></p>
<p>　　１、应用程序池只有ＩＩＳ６.０及以上版本才有，从而也出现一个问题。那就是应用程序池会自动释放资源，也就是根据应用程序池设定的资源回收时间或超过设定空闲时间，把一些已经初始化的资源回收。</p>
<p>　　我们在开发项目的时候，其中有一个项目需要用到定时器，一天运行一次，在单元测试的时候，一切正常，可一旦集成测试发现该定时器根本就不起作用，经多次试验，才发现由于２４小时运行一次间隔太长，而集成测试时往往是今天设定一个值，然后第二天才来看最后的效果怎么样，这中间可能没有其它的人为的或其它行为触发，导致定时器启动后一段时间后，就又回收了，所以才不会再执行相应的功能。</p>
<p>　　<span style="COLOR: #000080">解决方法：</span></p>
<p>　　该问题涉及到了应用程序池的资源回收机制，当然我们可以设定应用程序池中的资源回收时间和空闲时间来临时性解决这个问题，但总不是一个好的解决方案。为此，我们也请教过微软的一些专家，而得到的回复是，如果定时器要运行在ＷＥＢ应用程序中，暂时没有好的解决方法。<span style="COLOR: #ff0000">他们的建议是，另外创建一个桌面程序或者windows服务，把定时功能放在此中，再去调用ＷＥＢ应用中的一些需要定时实现的功能。</span></p>
<p>　　２、ＷＥＢ应用程序一些常用数据的提取。</p>
<p>　　一般的ＷＥＢ应用程序，都会有一些配制性或系统级的数据，这些数据经常会应用到各个模块中，非常频繁。所以，我们都是在程序启动的时候就初始化好这些数据，保存在静态变量中，如下示意：</p>
<p>public class Config<br/>{<br/>public static string SiteName;<br/>public static bool AllowArticleComments;<br/>...........</p>
<p>public static void Init()<br/>{<br/>//从数据表中读取数据，初始化SiteName和AllowArticleComments变量<br/>}</p>
<p>}</p>
<p>　　然后在Global.asax中程序启动时执行Init()方法，预先把数据实始化到静态变量中。</p>
<p>protected void Application_Start(object sender, EventArgs e)<br/>{</p>
<p>　　Config.Init();</p>
<p>}</p>
<p>　　这样，在其它模块需要用到这些数据的时候，只要通过Config.SiteName类似这样取得数据。　</p>
<p>　　但我们发现程序运行一段时间后，会出现Config.SiteName的值为null，而有些整形的数据也变成了默认数据了，经过多次的试验最终发现也是由于资源的回收机制在搞鬼，资源回收后进行重新分配，程序不会自动去数据表中读取数据初始化了，所以导致这些数据变成了其本身的默认值了。</p>
<p>　　<span style="COLOR: #000080">解决方法：</span></p>
<p>　　由于资源的回收，我们不能阻止这些数据被重新分配初始默认值。所以我们就考虑当重新分配资源时，再去读数据表数据，重新赋值，这个可以用Cache缓存来实现，如下：</p>
<p>public static UnitInfoInfo GetUnitInfo()<br/>{<br/>if (!enableCaching)<br/>{<br/>return new UnitInfo().GetByPK(1);<br/>}</p>
<p>string key = "GetUnitInfo";<br/>UnitInfoInfo data = (UnitInfoInfo)HttpRuntime.Cache[key];</p>
<p>if (data == null)<br/>{<br/>data = new UnitInfo().GetByPK(1);<br/>if (data != null)<br/>{<br/>HttpRuntime.Cache.Add(key, data, null, DateTime.Now.AddHours(unitInfoTimeOut), Cache.NoSlidingExpiration, CacheItemPriority.High, null);<br/>}<br/><br/>}</p>
<p>return data;<br/>}</p>
<br/><p>public static string siteName<br/>{<br/>get<br/>{<br/>UnitInfoInfo unitInfo = GetUnitInfo();<br/>return unitInfo.SiteName;<br/>}<br/>}</p>
<p>　　这样同样可以通过Config.SiteName来访问这些数据，当资源回收时，缓存里的数据就为null，则会再次去读数据库，解决了由于资源回收导致的初始值丢失的问题。</p>
<p>　　３、由于２中所述的这些数据，我们一般都可以在管理后台中维护，当这些数据更改时，我们也希望这些缓存中的数据相应在的改变。这时我们或许可以通过以下方法来实现：</p>
<p>　　HttpRuntime.Cache.Remove( "GetUnitInfo");</p>
<p>　　当数据修改时，调用该方法，把缓存中的数据移掉，这样当重新调用Conifg.SiteName时，会再次去到数据库中读取数据。从而保持数据一致性。</p>
<p>　　很庆幸，程序能够正常运行。但当我们把ＷＥＢ圆的最大工作进程数改成大于１时，问题来了。当我们在后台修改SiteName数据后。发现，前台显示有时候是修改后的数据，有时候还是原来的数据。这是因当ＷＥＢ圆的最大工作进程数大于１，如为２时，则该应用程序池会生成二个w3wp进程，这二个进程是相互独立的，访问网站时，资源的读取是从这二个w3wp中轮循访问的，从而可以达到一定的负载均衡。正由于这二个进程的独立性，当执行HttpRuntime.Cache.Remove( "GetUnitInfo");语句后，或许当时访问的进程是其中一个w3wp进程，我们暂定为w3wp(1)，所以在w3wp(1)进程中该缓存是被移走了，当再次访问时，显示的数据就为修改后正确的数据。而w3wp(2)进程中的缓存还是没有改变，所以当轮循到该进程时，显示的数据为修改前非正确的数据。</p>
<p>　　<span style="COLOR: #000080">解决方法：</span></p>
<p>　　所以当ＷＥＢ圆的最大工作进程数大于１时，２中所提供的解决方法，有点不够用了。那用什么方法可以移除所有进程中的对应缓存呢？幸亏.net2.0中还提供了一种缓存，就是数据库依赖缓存。当数据表中某些数据变动后，会促使对应的缓存失效。为此，我们把２中的解决方法稍微做一修改：</p>
<p>public static UnitInfoInfo GetUnitInfo()<br/>{<br/>if (!enableCaching)<br/>{<br/>return new UnitInfo().GetByPK(1);<br/>}</p>
<p>string key = "GetUnitInfo";<br/>UnitInfoInfo data = (UnitInfoInfo)HttpRuntime.Cache[key];</p>
<p>if (data == null)<br/>{<br/>data = new UnitInfo().GetByPK(1);<br/><span style="COLOR: #ff0000">AggregateCacheDependency cd = DependencyFacade.GetUnitInfoDependency();</span><br/>if (data != null)<br/>{<br/>HttpRuntime.Cache.Add(key, data, <span style="COLOR: #ff0000">cd</span>, DateTime.Now.AddHours(unitInfoTimeOut), Cache.NoSlidingExpiration, CacheItemPriority.High, null);<br/>}<br/><br/>}</p>
<p>return data;<br/>}</p>
<p>　　其中红色部分为新增语句或修改过的地方。</p>
<p>　　４、关于ＷＥＢ圆中最大工作进程数大于１时，Session值如何在各进程之间的共享问题，这个微软到已经提供了解决方案。</p>
<p>　<span style="COLOR: #000080">　解决方法：</span>　　</p>
<p>　　在Web.Config中，有这样一行配制信息：</p>
<p>　　&lt;sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" stateNetworkTimeout="20"/&gt;</p>
<p>　　这里的mode属性值有InPorc和StateServer二种值，如果是InProc那么，Session的值是保存在进程中的，则无法在各个进程间共享了，我们可以设定值为StateServer，当然前提我们还必须到Windows服务中开启ASP.NET 状态服务，这样就可以解决进程间Session值共享问题了。</p>
<p>　　可能大家都有自己的解决方法来解决以上碰到的问题，欢迎在此讨论，以便我们可以在现有的基础上做进一步的改进。</p>
<p class="zoundry_bw_tags">
  <!-- Tag links generated by Zoundry Blog Writer. Do not manually edit. http://www.zoundry.com -->
  <span class="ztags"><span class="ztagspace">Technorati</span> : <a href="http://technorati.com/tag/IIS6.0" class="ztag" rel="tag">IIS6.0</a>, <a href="http://technorati.com/tag/WEB%E5%9C%86" class="ztag" rel="tag">WEB圆</a>, <a href="http://technorati.com/tag/%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%B1%A0" class="ztag" rel="tag">应用程序池</a></span> 
</p><img src ="http://www.cnblogs.com/licongjie/aggbug/1129770.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48001/" target="_blank">上海电信计划2012年80%用户实现100M带宽</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>实战小技巧系列(1)：使用索引器解决参数统一解析</title><link>http://www.cnblogs.com/licongjie/archive/2008/03/24/1120224.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Mon, 24 Mar 2008 12:42:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2008/03/24/1120224.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/1120224.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2008/03/24/1120224.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/1120224.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/1120224.html</trackback:ping><description><![CDATA[
<p>　　<span style="COLOR: #000080"><strong>MSDN中的名词解释：</strong></span>索引器允许类或结构的实例按照与数组相同的方式进行索引。索引器类似于属性，不同的是它们的访问器采用参数。</p>
<p>　　<strong style="COLOR: #000080">问题场景：</strong>模拟google可拖动模块，并且可以针对各自的模块设置不同的参数，从而使得各模块的显示方式或显示数据根据所设置的参数来呈现。这时问题就出来了，因为不同的模块对应不同的参数设置，这些参数并没有统一性，那怎么用统一的方法来处理这些不同模块参数呢？目前，为了共用性，我们特别设置了参数的解析方法：</p>
<p><br/>　　１、当设置好各个模块参数保存时，所有的模块参数都统一解析成特定的字符串格式：参数1名称=参数1值@参数2名称=参数2值，这样做的好处就是，不管你有多少模块，也不管以后各模块的参数是否需要再增加，都不影响这些参数的解析，便于扩展。</p>
<p>　　2、当在前台需要呈现这些模块时，把１中保存时的参数字符串传到入各自的模块中，再根据参数的格式进行反解析，从而得到原来的值，代码如下：</p>
<p>protected void InitParams(Dictionary&lt;string, string&gt;　param, string paramValue)<br/>{<br/>　　string[] aParams = paramValue.Split(<a href="mailto:'@'">'@'</a>);<br/>　　int length = aParams.Length;</p>
<p>　　for (int j = 0; j &lt; length; j++)<br/>　　{<br/>　　　　int i = aParams[j].IndexOf('=', 0);<br/>　　　　if (i != -1)<br/>　　　　{<br/>　　　　　　string[] aParam = new string[2];<br/>　　　　　　aParam[0] = aParams[j].Substring(0, i);<br/>　　　　　　aParam[1] = aParams[j].Substring(i + 1, aParams[j].Length - i - 1);<br/>　　　　　　param[aParam[0]] = aParam[1];<br/>　　　　}<br/>　　}<br/>}</p>
<p>　　这样，在模块加载时，我们可以通过param["参数名"]可以取得相应的值，从而来进行相应的操作，这样的确很方便。而且这样的操作，一开始并没有出现什么问题，一切运行正常。可随着模块的升级，由于需要会在以后的升级中不断的增加各自的参数项，当把这些更新到程序中时，则对于原有的模块参数解析则出现异常情况。这是由于新增了参数项，在程序中增加了对该参数项的判断，如param["PageSize"]，但原有已经在运行的模块中，并没有这个参数，这导致 param["PageSize"]并不存在，则会抛出异常。</p>
<p>　　<strong><span style="COLOR: #000080"><strong>解决方案：</strong></span></strong></p>
<p>　　１、针对这种情况，我想很多人一开始就会想到，来一个异常捕获就可以轻易解决。如：</p>
<p>private int PageSize<br/>{<br/>get<br/>{<br/>try<br/>{<br/>return Convert.ToInt32(param["PageSize"]);<br/>}<br/>catch<br/>{<br/>return 10;<br/>}<br/>}<br/>}</p>
<p>　　这样做，确实可以解决问题，但我想大家都不愿意这样来做，一来，通过异常捕获来设置默认值效率可想而知的；二来，这样做，就意味着我每增加一个参数项，针对老版本的兼容，我必须都得通过这样的方法去设置该参数的默认值，这样不仅不利于维护，也使得代码一团糟。显然这种方法不值得推荐的。</p>
<p>　　２、既然通过异常捕获方式行不通，怎么样即可以直接通过param["PageSize"]来获取参数值，而又不会因为是新增参数而抛异常呢。这里就可以通过索引器来实现了。</p>
<p>　　索引器类似于属性，可以用set和get属性设置，从而在赋值或者取值的同时对值进行一定的事先操作，这样，我们把上面提到的InitParams函数中param参数重新包装一下，通过索引器去读取Dictionary字典中的数据。</p>
<p>public class ParamModel<br/>{<br/>protected Dictionary&lt;string, string&gt; param;</p>
<p>public ParamModel()<br/>{<br/>this.param = new Dictionary&lt;string, string&gt;();<br/>}</p>
<p>public string this[string paramName]<br/>{<br/>get<br/>{<br/>if (this.param.ContainsKey(paramName))<br/>{<br/>return this.param[paramName];<br/>}<br/>else<br/>{<br/>if (paramName == "PageSize")<br/>{<br/>return "10";<br/>}<br/>else<br/>{<br/>return "0";// }<br/>}<br/>}<br/>set<br/>{<br/>this.param[paramName] = value;<br/>}<br/>}</p>
<p>public string GetParams()<br/>{<br/>string str = "";<br/>foreach (string s in param.Keys)<br/>{<br/>if (str == "")<br/>{<br/>str = s + "=" + param[s];<br/>}<br/>else<br/>{<br/>str += "@" + s + "=" + param[s];<br/>}<br/>}<br/>return str;<br/>}<br/>}</p>
<p>　　通过索引器来解决本例中的问题，再恰当不过了。以后不管参数项增加还是减少，都不影响模块参数的读取。</p>
<p>　　本文是针对实际工作中遇到的问题分析，从中找到本人认为最恰当的方法来解决，仅作参考。<br/><br/></p>
<img src ="http://www.cnblogs.com/licongjie/aggbug/1120224.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/48000/" target="_blank">数万名网友签名抗议星际争霸2取消局域网功能</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>关于Castle中AOP的一个问题，急!!</title><link>http://www.cnblogs.com/licongjie/archive/2007/04/27/729219.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Fri, 27 Apr 2007 01:30:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2007/04/27/729219.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/729219.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2007/04/27/729219.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/729219.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/729219.html</trackback:ping><description><![CDATA[<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: #008080">&nbsp;1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">facility&nbsp;id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">aspectsharp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;type</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Castle.Facilities.AspectSharp.AspectSharpFacility,&nbsp;Castle.Facilities.AspectSharp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;!</span><span style="COLOR: #000000">[CDATA[<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;import&nbsp;FWL.Component<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;import&nbsp;FWL.Service.Interface&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;FWL.Service<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interceptors&nbsp;[&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">logger</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;LoggerInterceptor&nbsp;]&nbsp;<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interceptors&nbsp;[&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">security</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;:&nbsp;SecurityCheckInterceptor&nbsp;]&nbsp;<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aspect&nbsp;InterfaceLogger&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;[&nbsp;assignableFrom(IUserService)&nbsp;]<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include&nbsp;SecurityMixin<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pointcut&nbsp;method(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)&nbsp;<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;advice(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">logger</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;<br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;<br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]]</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">facility</span><span style="COLOR: #000000">&gt;</span></div>
<br>可能通过以上的配置，可以对所有继承了IUserService接口的类，实现AOP的功能，但现实中，有很多类似IUserService这样的业务功能接口，难道要一个个的写吗？还有其它的方法吗？比如针对一个程序集来控制？<br>不知道哪位有这方面的经验 ？？<br><br>由于比较急，暂放首页一会。
<img src ="http://www.cnblogs.com/licongjie/aggbug/729219.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47999/" target="_blank">Silverlight打造杰克逊纪念专题</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>关于网站安全性的问题</title><link>http://www.cnblogs.com/licongjie/archive/2007/01/29/632967.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Mon, 29 Jan 2007 02:12:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2007/01/29/632967.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/632967.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2007/01/29/632967.html#Feedback</comments><slash:comments>35</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/632967.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/632967.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;由于问题比较紧迫，暂时在首页上放会儿，请dudu见谅。<br>&nbsp;&nbsp;&nbsp;最近网站频繁出现病毒，也就是在首页上会被插入一段恶意的js代码或iframe框架，在状态栏上出现一些莫名其妙的链接，该网站在允许用户上传图片，这些扩展名等都已经控制。我查了代码，也没有发现哪里有异常情况。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;情急之下，只好求救于园子里的各位大侠了。还有哪些情况，可以导致页面被修改？
<img src ="http://www.cnblogs.com/licongjie/aggbug/632967.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47998/" target="_blank">传诺基亚正在开发Android手机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>设计模式杂谈：创建型模式之生成器模式(Builder Pattern) </title><link>http://www.cnblogs.com/licongjie/archive/2006/12/14/590623.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Thu, 14 Dec 2006 02:26:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/12/14/590623.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/590623.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/12/14/590623.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/590623.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/590623.html</trackback:ping><description><![CDATA[摘要: 前几讲链接：1、设计模式杂谈：开头篇2、设计模式杂谈：创建型模式之工厂方法（Factory Method）3、设计模式杂谈：创建型模式之单件模式（Singleton）4、设计模式杂谈：创建型模式之抽象工厂模式(Abstract Factory)关于设计模式的杂谈，已经断断续续写了四篇了，但反应好象不怎么样，呵呵，大家都对设计模式不陌生了，再加上这几篇又是很简单的东西，所以没有多少价值，不过不管怎么&nbsp;&nbsp;<a href='http://www.cnblogs.com/licongjie/archive/2006/12/14/590623.html'>阅读全文</a><img src ="http://www.cnblogs.com/licongjie/aggbug/590623.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47996/" target="_blank">7月编程语言排行榜</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>设计模式杂谈：创建型模式之抽象工厂模式(Abstract Factory)</title><link>http://www.cnblogs.com/licongjie/archive/2006/12/12/589661.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Tue, 12 Dec 2006 03:20:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/12/12/589661.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/589661.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/12/12/589661.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/589661.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/589661.html</trackback:ping><description><![CDATA[摘要: 前几讲链接：1、设计模式杂谈：开头篇2、设计模式杂谈：创建型模式之工厂方法（Factory Method）3、设计模式杂谈：创建型模式之单件模式（Singleton）在上一讲中，对系统做了进一步的优化，使之更灵活，以适合需求的变化，也经过几位热心朋友的指点，对一些关键的细节进行了修正，自己也有了更进一步的理解，在此非常感谢他们。在这一讲，来看看抽象工厂模式的运用。抽象工厂模式目的是要解决&#822&nbsp;&nbsp;<a href='http://www.cnblogs.com/licongjie/archive/2006/12/12/589661.html'>阅读全文</a><img src ="http://www.cnblogs.com/licongjie/aggbug/589661.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>设计模式杂谈：创建型模式之单件模式（Singleton）</title><link>http://www.cnblogs.com/licongjie/archive/2006/12/11/588829.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Mon, 11 Dec 2006 06:18:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/12/11/588829.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/588829.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/12/11/588829.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/588829.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/588829.html</trackback:ping><description><![CDATA[摘要: 前几讲链接：1、设计模式杂谈：开头篇2、设计模式杂谈：创建型模式之工厂方法（Factory Method）在上一讲&#8220;设计模式杂谈：创建型模式之工厂方法（Factory Method）&#8221;中，已经通过一个案例对工厂方法进行了讲述。也有不少朋友看了提出了一些建议，确实，在上一讲中，只是简单的讲了工厂方法的用法，但有些地方并不适合于实际应用。主要是最后的创建工厂方法实例时，我把这个&nbsp;&nbsp;<a href='http://www.cnblogs.com/licongjie/archive/2006/12/11/588829.html'>阅读全文</a><img src ="http://www.cnblogs.com/licongjie/aggbug/588829.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47994/" target="_blank">Google号召社区力量为互联网加速</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>设计模式杂谈：创建型模式之工厂方法（Factory Method）</title><link>http://www.cnblogs.com/licongjie/archive/2006/12/10/587964.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Sun, 10 Dec 2006 07:17:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/12/10/587964.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/587964.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/12/10/587964.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/587964.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/587964.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 设计模式中，创建型模式是最常用的，也是最基础的设计模式。理解这些，对于理解别的复杂的模式有一定的帮助。一般来说，讲创建型模式都先会讲单件模式，这里，为了讲述方便，我先从工厂方法讲起。&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 下面先从一个案例分析开始这一讲吧： &nbsp; <br>&nbsp; &nbsp;&nbsp;&nbsp; <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; <br>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 中国企业奖金和个人所得税的计算规则是: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 奖金 = 基本工资(4000) * 10% &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 个人所得税 = (基本工资 + 奖金) * 40%&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; <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;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 美国企业奖金和个人所得税的计算规则是: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 奖金 = 基本工资 * 15 % &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 个人所得税 = (基本工资 * 5% + 奖金 * 25%) <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; （注：以上案例来自<a href="http://terrylee.cnblogs.com/">TerryLee</a> 设计模式系例文章《<a class=singleposttitle id=viewpost1_TitleUrl href="http://www.cnblogs.com/Terrylee/archive/2005/12/13/295965.html">NET设计模式（3）：抽象工厂模式（Abstract Factory）</a>》中的案例。）<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 在这里，假设我们需要为某一个跨国公司在美国和中国的企业设计这样一个员工工资计算系统。当然我们可以分别为美国的公司和中国的公司量身定做二套系统，但明显这种做法不明智的，浪费人力物力不说，碰到系统升级等行为，我们不得不为此而付出更多的代价。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 我们可以看到，不管是在美国的企业还是在中国的企业，我们要解决的都是同一个问题，那就是员工工资的计算，唯一不同的就是中国企业和美国企业奖金和个人所得税的计算方法不一样而已，这样的话，我们完全可以只设计一个软件系统，而根据不同的国家采取不同的部署即可以解决。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 在这里我们尽可能把这套系统想的最简单，因为我们不是要了解这个系统复杂的业务，而是在这个简单的系统里来运用设计模式解决方案，这样更明显一点，也更好理解一点，当然在这个杂谈的例子里，主要是为了讲述设计模式的用法，可能会导致设计过度，这个在这里不作讨论了，呵呵，这些在讲之前先声明一下，免得各位朋友误解。<br><br>&nbsp;&nbsp;&nbsp; &nbsp; 好了言归正传，既然我们决定只开发一个软件系统，接下来就是怎么来设计了。如果抛开面向对象方法的话，用面向过程的，那是最简单不过了，用IF、ELSE等判断一下，当前要用于哪一个国家公司的员工工资计算，再根据上面的计算方法就可以算出员工工资了，这些在这里就不再详细说明了，在<a href="http://terrylee.cnblogs.com/">TerryLee</a> 设计模式系例文章《<a class=singleposttitle id=viewpost1_TitleUrl href="http://www.cnblogs.com/Terrylee/archive/2005/12/13/295965.html">NET设计模式（3）：抽象工厂模式（Abstract Factory）</a>》中已经讲的很详细了，我们就直接切入正题。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 工厂方法模式，主要是用来解决某一个单一对象的创建问题。把变化部分封装在单独的对象里，然后在实际应用时，根据不同的情况来获取不同的对象，从而满足解决方案的需求，注意工厂方法是解决某个对象的创建问题的。根据这个我们再来看这个案例，对于程序的主干部分，我想比较明确了，就是要计算员工工资，至于计算工资的方法，则根据不同的国家有不同的规则，也就是说计算工资具体实现是变化的。好，既然我们已经找到了变化点在哪里，我们就把每个国家的计算工资实现封装在一个类里，当然，不管是美国公司还是中国公司，都只要实现一个计算工资方法即可，这样我们可以抽象出一个计算工资的接口来，代码如下：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;DesignPattern.IBLL<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;ISalary<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;Calculate(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;basicSalary);<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 接下来，我们定义分别对于美国公司和中国公司的具体实现类：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 中国公司：<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;DesignPattern.BLL<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ChineseSalary&nbsp;:&nbsp;IBLL.ISalary<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;Calculate(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;basicSalary)<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;bonus;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;tax;<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;salary;<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bonus&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;basicSalary&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0.1</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">奖金计算</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tax&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(basicSalary&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;bonus)&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0.4</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">个人所得税计算</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;salary&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;basicSalary&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;bonus&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;tax;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">最终所得工资计算</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;salary;<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 美国公司：<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;DesignPattern.BLL<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;AmericanSalary&nbsp;:&nbsp;IBLL.ISalary<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;Calculate(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;basicSalary)<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;bonus;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;tax;<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;salary;<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bonus&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;basicSalary&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0.15</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">奖金计算</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tax&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;basicSalary&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0.05</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;bonus&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0.25</span><span style="COLOR: #000000">;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">个人所得税计算</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;salary&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;basicSalary&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;bonus&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;tax;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">最终所得工资计算</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;salary;<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 好计算工资具体的实现类已经完成，接下来，我们就要创建专门的工厂，用它来创建实际用到的计算工资的对象。每个工厂要做的就是创建自己对应的计算工资方法的对象，同样我们可以抽象出一个接口，代码如下：<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;DesignPattern.IBLL<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;IFactory<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ISalary&nbsp;CreateSalary();<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 注意，这里CrateSalary方法返回的是ISalary接口，这个就是在开始篇里讲到的其中一个原则，要依赖于抽象，不要依赖于实现细节。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 接下来，分别创建对应于美国企业和中国企业的具体的工厂方法：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 中国企业：<br>&nbsp;&nbsp;
<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;DesignPattern.Factory<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ChineseFactory&nbsp;:&nbsp;IBLL.IFactory<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;IBLL.ISalary&nbsp;CreateSalary()<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;BLL.ChineseSalary();<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 美国企业：<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Collections.Generic;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;System.Text;<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;DesignPattern.Factory<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;AmericanFactory&nbsp;:&nbsp;IBLL.IFactory<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;IBLL.ISalary&nbsp;CreateSalary()<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;BLL.AmericanSalary();<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 到此为止，按照我们的当初设计，分离出变化点，封装在单独的对象里，再创建工厂，利用不同的工厂方法创建相应的对象，已经完成。在这里可能会有朋友会说，何必再多此一举创建工厂方法呢，直接根据不同的情况初始化不同的实现对象不就可以了，确实，如果单单要实现这个功能的话确实足够了，但在实际的应用中，这些对象可能在各个模块中会被频繁的创建，这样的话，如果要在美国公司和中国公司分别部署的话，则比较困难，而且很难适应将来的变化，而用工厂方法的话，我们则可以把具体工厂方法的创建统一来管理，在需要用到的模块里再根据该工厂方法创建相应的对象即可，这样的话，一旦要改变部署的话，我们只要改变具体工厂方法的创建即可，因为这个是统一来管理的，则可以把改变降到最低，当然我在下面的几篇里会讲到更好的方法来应对这种变化。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 下面我们就来看看最后的实现吧：<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;basicSalary;<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;result;<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;basicSalary&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Convert.ToDouble(txtBasicSalary.Text.Trim());<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IBLL.IFactory&nbsp;factory&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Factory.ChineseFactory();<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IBLL.ISalary&nbsp;salary&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;factory.CreateSalary();<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;salary.Calculate(basicSalary);<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbSalary.Text&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;result.ToString();</span></div>
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 如果要在美国公司用，则只要改变一个语句：<br>&nbsp;把
<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">IBLL.IFactory&nbsp;factory&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Factory.ChineseFactory();</span></div>
<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%; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">1</span>&nbsp;<span style="COLOR: #000000">IBLL.IFactory&nbsp;factory&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Factory.AmericanFactory();</span></div>
<br>即可。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 好了，工厂方法就讲到这里了，这里，我们看到，还是需要改变代码来实现不同的部署，这里可以有更好的方法来实现，我们只需要改变配置文件，不必修改代码就可以实现，这一点我就在下一篇中再改进。由于个人的理解有限，有些原理性的东西也讲不大清楚，这一点希望各位朋友能够一起讨论，一起进步。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<a title=工厂方法例子源码下载 href="http://www.cnblogs.com/Files/licongjie/FactoryMethod.rar">工厂方法例子源码下载</a><br><a title=源码下载 href="http://www.cnblogs.com/Files/licongjie/FactoryMethod.rar"></a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下一篇：<a class=titlelink id=Editor_Results_rprSelectionList_ctl03_LinkTitle href="http://www.cnblogs.com/licongjie/archive/2006/12/11/588829.html">设计模式杂谈：创建型模式之单件模式（Singleton）</a><br>
<img src ="http://www.cnblogs.com/licongjie/aggbug/587964.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47989/" target="_blank">Twitter无处不在 魔兽世界Twitter发送器插件发布</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>设计模式杂谈：开头篇</title><link>http://www.cnblogs.com/licongjie/archive/2006/12/10/587661.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Sat, 09 Dec 2006 16:24:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/12/10/587661.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/587661.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/12/10/587661.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/587661.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/587661.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 设计模式，我想对于园子里的朋友来说已经是老生常谈了。特别是园子里象<a id=TeamBloggerList1_Bloggers_ctl02_Hyperlink1 href="http://www.cnblogs.com/wayfarer">Bruce Zhang</a>、<a id=TeamBloggerList1_Bloggers_ctl01_Hyperlink1 href="http://www.cnblogs.com/Terrylee">TerryLee</a>、<a id=TeamBloggerList1_Bloggers_ctl04_Hyperlink1 href="http://www.cnblogs.com/zhenyulu">吕震宇</a> 等几位的作品，想必各位已经都拜读过了吧，本人也是，并且受益非浅。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 但即使如此，我还是想在此谈谈自己对于设计模式的看法和见解，一来对自己学习设计模式的一个总结，二来也希望园子里的各位朋友能够指正错误，也使得自己少走些弯路。如果能够帮助到一些人，那是再最好不过了。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 对于设计模式的定义，每本书都有它的写法，每个人都有个人的见解，在此引用李建忠老师教程上面的一句话&#8220;设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案。&#8221;，确实，每一种设计模式都有其解决的特定问题，需求的变化，导致解决问题的变化，从而我们要用到的解决该问题的模式也将随之改变。也就是说，&#8220;变化&#8221;是使用设计模式的前提，如果软件设计一但编码完成就不再变化的话，那么设计模式也就没有必要在此讨论了，也没有其存在的必要了。可能有很多人在刚刚学习设计模式的时候会想，既然设计模式是解决某一类常见问题的，那么我们只要把每一种设计模式的使用代码背熟了，就可以使用了，我也一样这样想过，这也让我想起一篇文章，上面写着一个人去面试，他对面试官说，他曾经开发过一个软件，在这个软件中，他用到了GOF中提到的23种设计模式，结果他没能被录用。我想如果一个软件中要用到所有的23种设计模式的话，就应该要想到是否设计过渡过了（或许有些大型软件确实需要，这个我就不得而知了（:）。软件开发时，需求的变化是复杂的，也是不可预测的，如果我们记熟这些设计模式的用法，或许也可以照搬照抄的用到项目中，可一旦如果需求变化了，那么就无法应对。这是因为软件开发更是变幻莫测，目前还没有一种模式能够应付任何的变化，或者可以说，现在的这23种设计模式根本满足不了这些变化，在这种情况下，只有把这些设计模式的根本点理解透了，才可以活用，这需要经验的积累。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 设计模式的基础是面向对象，离开面向对象也无从谈论设计模式。所以，在学习设计模式之前，我觉得首先要理解的是面向对象的三大机制，即&#8220;封闭&#8221;、&#8220;继承&#8221;、&#8220;多态&#8221;。也只有理解这些了，才能去更好的理解设计模式的精髓。当然，反过来，理解了设计模式，就能更好的运用面向对象原理。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 当然，设计模式也有其一定的设计原则可遵循，下面就照抄一下书本的东西：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 1、单一职责原则。<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 我们要把功能尽可能的细分，每一个类应该只负责一块内容或只执行一个任务。那么怎么样才算达到单一职责了呢，那就是当一个类仅有一个引起它变化的原因时。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 2、开放封闭原则<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 我们应该要做到，尽量不要去修改原有的类，但却可以扩展现有的功能。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 3、替换原则<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 子类必须能够替换它们的基类。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 4、依赖倒置原则<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 这只归决于二句经典的老话：高层模块不应该依赖于低层模块，二者都应该依赖于抽象；抽象不应依赖于实现细节，实现细节应该依赖于抽象。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 5、接口隔离原则<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 每一个接口都要有明确的定义，不应该强迫客户程序依赖于它们不用的方法。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 可以说以上五点是设计中可以遵循的原则，当我们的程序实现了这些原则时，那么我们就已经使用了设计模式了。在听完李建忠老师的设计模式纵横谈系列课程时，个人认为最经典的，也是最能概括设计模式用法的话就是&#8220;哪里有变化，就封装哪里&#8221;。当然，我们必须得先知道，变化点在哪里，这就需要我们不断的去实践，去领悟了。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 开头篇就讲到这里了，感觉全部都是些泛泛之谈，呵呵，经验有限，见谅了。在下面的几篇里，我会通过一个实际的例子来描述我所理解的几个设计模式。<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 注：本文参考了李建忠老师的讲座以及<a id=TeamBloggerList1_Bloggers_ctl02_Hyperlink1 href="http://www.cnblogs.com/wayfarer">Bruce Zhang</a>、<a id=TeamBloggerList1_Bloggers_ctl01_Hyperlink1 href="http://www.cnblogs.com/Terrylee">TerryLee</a>、<a id=TeamBloggerList1_Bloggers_ctl04_Hyperlink1 href="http://www.cnblogs.com/zhenyulu">吕震宇</a> 等几位的关于设计模式的文章。在接下来的几篇文章里用到的例子，我也取自<a id=TeamBloggerList1_Bloggers_ctl01_Hyperlink1 href="http://www.cnblogs.com/Terrylee">TerryLee</a> 的文章《<a class=singleposttitle id=viewpost1_TitleUrl style="FONT-SIZE: 12pt" href="http://www.cnblogs.com/Terrylee/archive/2005/12/13/295965.html">.NET设计模式（3）：抽象工厂模式（Abstract Factory）</a>》中的虚拟案例，因为，我觉得这个案例对于我的理解来说能够很好的表达，也不用再费事去想一个案例，况且对于园子里的朋友来说能够更好的理解，希望<a id=TeamBloggerList1_Bloggers_ctl01_Hyperlink1 href="http://www.cnblogs.com/Terrylee">TerryLee</a>不会介意。（当然在涉及到别人版权的，我会标明）&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下一篇：<a class=titlelink id=Editor_Results_rprSelectionList_ctl04_Hyperlink1 href="http://www.cnblogs.com/licongjie/archive/2006/12/10/587964.html">设计模式杂谈：创建型模式之工厂方法（Factory Method）</a>
<img src ="http://www.cnblogs.com/licongjie/aggbug/587661.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47989/" target="_blank">Twitter无处不在 魔兽世界Twitter发送器插件发布</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Socket网络编程学习笔记（6）：使用线程池提高性能</title><link>http://www.cnblogs.com/licongjie/archive/2006/10/30/544638.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Mon, 30 Oct 2006 09:10:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/10/30/544638.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/544638.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/10/30/544638.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/544638.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/544638.html</trackback:ping><description><![CDATA[摘要:  在前几篇介绍中，不论是服务端的侦听还是客户端的连接都是通过新建一个线程去执行特定功能的。在这种情况下，一量有一个新客户端需要连接，则又得创建新的线程，而当程序创建新线程时，往往需要大量的内部开销，这对程序的性能有一定的影响。在.NET库中提供了一种方法，可以避免一些开销。而在Socket通讯中还有另一种访求那就是异步Socket，我不知道用这种方式的性能如何，在这里且不管这种形式，主要来看一下用线程池解决问题。<br>&nbsp;&nbsp;<a href='http://www.cnblogs.com/licongjie/archive/2006/10/30/544638.html'>阅读全文</a><img src ="http://www.cnblogs.com/licongjie/aggbug/544638.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47988/" target="_blank">Firefox 3.5匆忙推出漏洞多 Mozilla本月将更新</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Socket网络编程学习笔记（5）：发送和接收实体类数据</title><link>http://www.cnblogs.com/licongjie/archive/2006/10/27/542024.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Fri, 27 Oct 2006 08:59:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/10/27/542024.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/542024.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/10/27/542024.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/542024.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/542024.html</trackback:ping><description><![CDATA[摘要: 在前面讲述的篇幅中，发送的都是文本信息，我们只要通过Encoding中的几个方法把文本转化成二进制数组就可以利用Socket来传输了，这对于一些基本的信息传输能够得到满足，但对于一些复杂的消息交流，则有些&#8220;吃力&#8221;。我们有时候会把一些信息封闭在一个类中，如果Socket能够传送类对象，那么一些复杂的问题能够通过面向对象来解决了，即方便又安全。大家都知道，要想在网络上传输信息，&nbsp;&nbsp;<a href='http://www.cnblogs.com/licongjie/archive/2006/10/27/542024.html'>阅读全文</a><img src ="http://www.cnblogs.com/licongjie/aggbug/542024.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47987/" target="_blank">预测：Twitter最可能收购的十家公司</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Socket网络编程学习笔记（4）：TCP消息边界处理</title><link>http://www.cnblogs.com/licongjie/archive/2006/10/27/541607.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Fri, 27 Oct 2006 03:17:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/10/27/541607.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/541607.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/10/27/541607.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/541607.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/541607.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在前面的几篇中，讲了关于套接字Socket以及利用套接字助手类来进行服务端和客户端之间的通信，在此中间并没有对发送的信息进行任何的处理。在本篇中将会讲一下TCP通信时的信息边界问题。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过套接字或其助手类来接收信息时，是从缓存区里一次性把全部的缘存都读取出来，只要你设置的缓存够大，它就能读取这么多，这样就会导致这样的情况出现。如果服务端连续发送信息到客户端，如我连续发送字符串&#8220;message 1&#8221;、&#8220;message 2&#8221;、&#8220;message 3&#8221;、&#8220;message 4&#8221;、&#8220;message 5&#8221;，我预想的是在客户端也是能够收到这样的五个完整的字符串，如果用前二篇中讲的方法，在同台机子上测试的话，是正常的，因为同台机子上网络信息传送出现的异常会比较少，但如果把客户端与服务端部署在不同的机器上，则会出现一些异想不到的现象。你会发现接收到的字符都被打乱了，会出现如&#8220;3message 4&#8221;的字符串，这样的话，我们就不能把服务端发送的信息正常的还原。这个就是消息的边界问题，要解决这个问题，方法有很多，现抽取其中几个来讲一下：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、固定尺寸的消息<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这是最简单但也是最昂贵的解决TCP消息问题的方案。就是要设计一种协议，永远以固定的长度传递消息，通过将所有的消息都设置为固定的尺寸，在从远程设备中接收到完整的消息时，TCP接收程序就能够了解发送的情况了。用这各地意味着必须将短消息加长，造成网络带宽资源的浪费。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、使用消息尺寸信息<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个方案允许使用可变长度的消息，惟一的不足就是接收端的远程设置必须了解每一个变长消息的确切长度。具体的方法是，在发送消息的时候，一起发送该消息的长度。那么在客户端接收的时候就能知道该消息的长度是多少，再来读取消息。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、使用消息标记<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;该方案使用预先确定的一个字符（或多个字符）来指定消息的结束，通过这种方式来分隔不同的消息。但用这种方法必须对所接收到的每一个字符进行检查以便确定为结束标记，这对于大型消息来说，可能导致系统性能的下降，不过对于C＃语言来说，提供了一些类，能够用于简化这个过程，那就是System.IO命名空间流类，下面我们也着重来讲一下这各方法。至于第二种方法，将在下一篇中与在消息中传送实体类信息相结合来讲述。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在上一篇中，我们已经提到NetworkStream类，利用该类来传送和接收消息。在这里，再提一下另外的二个流类，那就是StreamReader和StreamWriter，这二个类也可用于TCP协议发送和接收文本消息。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当我们得到Socket连接的一个NetworkStream对象时，可以通过下面的方法得到StreamWriter和StreamReader对象。<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">NetworkStream&nbsp;ns&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;s.GetStream();<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StreamReader&nbsp;sr&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;StreamReader(ns);<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StreamWriter&nbsp;sw&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;StreamWriter(ns);</span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这样我们就可以通过StreamWriter来发送消息，通过StreamReader来接收消息：<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">//</span><span style="COLOR: #008000">发送消息</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">2</span><span style="COLOR: #008000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;welcome&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Welcome&nbsp;to&nbsp;my&nbsp;test&nbsp;sever&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sw.WriteLine(welcome);<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sw.Flush();</span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;接收消息：<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">//</span><span style="COLOR: #008000">接收消息</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">2</span><span style="COLOR: #008000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;data&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>data&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;sr.ReadLine();</span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这样是不是比以前的做法更简单了，而且同时也解决了TCP消息边界问题了。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;但是用这各方法必须得注意以下二点：<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、这种方法其实就是利用消息标记来解决边界问题的，这里的标记就是换行符，也就是说，StreamWriter中的WriteLine()和StreamReader中的ReadLine()一定要成对使用，不然如果发送的信息中没有换行符，则客户机中用ReadLine()读取信息时，将无法结束，将堵塞程序的执行，一直等待换行符。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、另外还要保证在发送的消息本身不应该带有换行符，如果消息本身带有换行符，则这些换行符将被ReadLine()方法错误地作为标记，影响数据的完整性。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;关于TCP消息边界处理就暂时讲到这里了，由于自己的理解也不够深，难免会出现错误，请各位及时纠正。在下一篇中，将讲述传送实体类方面的问题。
<img src ="http://www.cnblogs.com/licongjie/aggbug/541607.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47987/" target="_blank">预测：Twitter最可能收购的十家公司</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Socket网络编程学习笔记（3）：利用套接字助手类</title><link>http://www.cnblogs.com/licongjie/archive/2006/10/26/540770.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Thu, 26 Oct 2006 07:36:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/10/26/540770.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/540770.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/10/26/540770.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/540770.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/540770.html</trackback:ping><description><![CDATA[摘要: 在上一篇中已经介绍了利用Socket建立服务端和客户端进行通信，如果需要的朋友可访问《Socket网络编程学习笔记（2）：面向连接的Socket》。在本篇中，将利用C＃套接字的助手类来简化Socket编程，使得刚刚接触到网络编程的朋友们更容易上手。跟上篇一样，通过C＃套接字的助手类来编程同样分服务端和客户端。一、服务端侦听模式1、创建套接字与IPEndPoint绑定，并设置为侦听模式。1//创建I&nbsp;&nbsp;<a href='http://www.cnblogs.com/licongjie/archive/2006/10/26/540770.html'>阅读全文</a><img src ="http://www.cnblogs.com/licongjie/aggbug/540770.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47986/" target="_blank">网易澄清:与暴雪合资公司仅提供技术支持</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Socket网络编程学习笔记（2）：面向连接的Socket</title><link>http://www.cnblogs.com/licongjie/archive/2006/10/26/540640.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Thu, 26 Oct 2006 06:01:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/10/26/540640.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/540640.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/10/26/540640.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/540640.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/540640.html</trackback:ping><description><![CDATA[摘要: 在上一篇中，我列了一些常用的方法，可以说这些方法是一些辅助性的方法，对于分析网络中的主机属性非常有用。在这篇中，我将会介绍一下面向连接（TCP）socket编程，其中辅以实例，代码可供下载。对于TCP的Socket编程，主要分二部分：一、服务端Socket侦听：服务端Socket侦听主要分以下几个步骤，按照以下几个步骤我们可以很方便的建立起一个Socket侦听服务，来侦听尝试连接到该服务器的客户S&nbsp;&nbsp;<a href='http://www.cnblogs.com/licongjie/archive/2006/10/26/540640.html'>阅读全文</a><img src ="http://www.cnblogs.com/licongjie/aggbug/540640.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47986/" target="_blank">网易澄清:与暴雪合资公司仅提供技术支持</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>Socket网络编程学习笔记（1）：常用方法介绍</title><link>http://www.cnblogs.com/licongjie/archive/2006/10/26/540356.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Thu, 26 Oct 2006 03:31:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/10/26/540356.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/540356.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/10/26/540356.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/540356.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/540356.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;虽然天天上博客园欣赏各位&#8220;大侠&#8221;的杰作，偶然回首，突然发现自己已成&#8220;潜水者&#8221;久矣。本来对于自己有限的水平，有点不好意思在此发贴，不过潜伏久了，才慢慢意识到老是通过浏览他人的文章虽然能够提高自己能力，能够及时的获取新技术新思想，但却只能停留在他人的思想上。通过学习，加上自己的想法，再写出来，让大家来指证错误，不仅能够巩固自己的知识，也可以让一些跟我一样迷惘的朋友们不用再去走一些弯路，岂不是两全其美，本着这样的想法，打算把自己平时的所学所想都写下来，欢迎各路朋友批评指证，因为你的批评和建议能够让我更迅速的得到提高。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;好了，讲了这么多废话，也该言归正传了。由于工作上需要，最近恶补了一下socket网络编程，整理了一下资料，把它放上来，希望能够对一些朋友有帮助。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在讲Socket编程前，我们先来看一下几个最常用的类和方法，相信这些东西能让你事半功倍。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一、IP地址操作类<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、IPAddress类<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a、在该类中有一个&nbsp;<span>Parse()方法，可以把点分的十进制IP表示转化成IPAddress类，方法如下：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>IPAddress address = IPAddress.Parse(&#8220;192.168.0.1&#8221;);</span></p>
</span>
<div v:shape="_x0000_s1026"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b、<span>IPAddress</span><span>提供</span><span>4</span><span>个只读字段<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
<div v:shape="_x0000_s1026">
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Any<span>&nbsp;&nbsp; </span></span><span>用于代表本地系统可用的任何</span><span>IP</span><span>地址 </span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Broadcase </span><span>用于代表本地网络的</span><span>IP</span><span>广播地址 </span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loopback </span><span>用于代表系统的回送地址&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;None </span><span>用于代表系统上没有网络接口<br></span></div>
</div>
</span></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中IPAddress.Any最常用可以用来表示本机上所有的IP地址，这对于socket服务进行侦听时，最方便使用，不用对每个IP进行侦听了。而IPAddress.Broadcase可用来UDP的IP广播，这些具体讲socket时再详细介绍。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、<span>IPEndPoint</span><span>类</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们可以通过二种构造方法来创建IPEndPoint类：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a、<span>IPEndPoint(long address, int port)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b、<span>IPEndPoint(IPAddress address, int port)<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;四个属性：<br>&nbsp;&nbsp;&nbsp;
<div v:shape="_x0000_s1026">
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Address </span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddressFamily </span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Port </span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MaxPort <br></span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MinPort <br></span></div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这些应该从名字上就很好理解，不再一一介绍。IPEndPoint其实就是一个IP地址和端口的绑定，可以代表一个服务，用来Socket通讯。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;二、DNS相关类<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DNS类有四个静态方法，来获取主机DNS相关信息，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、<span>GetHostName()&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过Dns.GetHostName()可以获得本地计算机的主机名<br>&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、<span>GetHostByName()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据主机名称，返回一个<span>IPHostEntry 对象：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<div v:shape="_x0000_s1026">
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPHostEntry GetHostByName(string hostName) <br></span></div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中<span>IPHostEntry</span><span>把一个</span><span>DNS</span><span>主机名与一个别名和</span><span>IP</span><span>地址</span><span>的数组相关联，包含三个属性： </span>
<div v:shape="_x0000_s1026">
<div><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img alt=* src="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/15/clip_image001.gif"></span></span><span>AddressList</span><span>：一个</span><span>IPAddress</span><span>对象的数组 </span></div>
<div><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img alt=* src="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/15/clip_image001.gif"></span></span><span>Aliases</span><span>：一个字符串对象数组 </span></div>
<div><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img alt=* src="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/15/clip_image001.gif"></span></span><span>HostName</span><span>：一个用于主机名的字符串对象<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、<span>GetHostByAddress()<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;类似于GetHostByName()，只不过这里的参数是IP地址，而不是主机名，也返回一个IPHostEntry对象。<br><br>
<div v:shape="_x0000_s1026">
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPHostEntry GetHostByAddress(IPAddress </span><span>address) </span></div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPHostEntry GetHostByAddress(string address) </span></div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4、<span>Resolve() <br></span>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当我们不知道输入的远程主机的地址是哪种格式时（主机名或IP地址），用以上的二种方法来实现，我们可能还要通过判断客户输入的格式，才能正确使用，但Dns类提供一更简单的方法Resolve()，该方法可以接受或者是主机名格式或者是IP地址格式的任何一种地址，并返回IPHostEntry对象。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;常用方法就写到这里了，当然针对网络编程不可能只有这么几个类和方法，只不过这几个我们最常用，也非常的简单。不过因为本人比较懒惰，没有放一些具体的实例上去，请见谅，：）。如果有兴趣的朋友，请接着看&#8220;<a href="http://www.cnblogs.com/licongjie/archive/2006/10/26/540640.html">Socket网络编程学习笔记（2）：面向连接的Socket</a>&#8221;</div>
</div>
</div>
</span></span></div>
</div>
</div>
</div>
</span></span></span></div>
</div>
</span></span></div>
<img src ="http://www.cnblogs.com/licongjie/aggbug/540356.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47986/" target="_blank">网易澄清:与暴雪合资公司仅提供技术支持</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>关于asp.net2.0中添加引用的问题</title><link>http://www.cnblogs.com/licongjie/archive/2006/08/09/471894.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Wed, 09 Aug 2006 02:26:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/08/09/471894.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/471894.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/08/09/471894.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/471894.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/471894.html</trackback:ping><description><![CDATA[用.net 2.0有一段日子了，以前一直没有发现添加引用跟以前的1.0有什么不同，今天在突然发现一个问题。　比如在一个解决方案中有三个项目，分别是BLL(业务逻辑层)，DAL（数据层），Web（WET应用程序）。现在信赖关系是，BLL层引用DAL层，而WEB应用引用BLL层。在以前的1.X版本中，我在Web应用中要引用BLL层，只要添加引用该项目即可，我在web应用程序里只能访问BLL层的方法，不能访问DAL层，而BLL层引用DAL也是如此，但在2.0我发现不一样了。我在WEB应用里只是添加了对BLL项目的引用　，但DAL项目也会自动加进来，并且　我在WEB应用的时候能够直接访问。我试了多次都是如此，而且不用添加引用，只要把一个dll文件直接copy到bin文件夹下，就可以直接访问了。我不知道是不是哪里可以设置，还是2.0的机制就是这个样子了。我觉得这样的机制不好，本来我WEB应用只能访问业务层，但现在却连数据层也能直接访问了。<br>？？？？？？迷惑中
<img src ="http://www.cnblogs.com/licongjie/aggbug/471894.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47985/" target="_blank">杰克逊悼念仪式或成史上最大规模Web活动</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>何时用静态方法</title><link>http://www.cnblogs.com/licongjie/archive/2006/08/08/471071.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Tue, 08 Aug 2006 06:25:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/08/08/471071.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/471071.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/08/08/471071.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/471071.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/471071.html</trackback:ping><description><![CDATA[最近一直困挠于这个问题，看了Petshop4.0 ，有一个sqlhelper里面的方法全部为静态方法，用起来确实是方便。在业务层，也通过<br>private static readonly IItem dal = PetShop.DALFactory.DataAccess.CreateItem();使得在使用的时候，不用再new。<br>而你同时会发现，在.net的其它好多地方，都用到了静态方法，特别是2.0新增加的特性，membership里，不管是新建用户，修改，获取等等都是通过静态方法来实现的。如果这样的话，那我在业务层里，进行数据操作的时候，也全部都可以用静态方法来实现，对于数据的更新，创建，获取来说，应该问题也不大吧。<br>可这个也让我非常困惑，如果这些可以用静态方法的话，那使用的时候不用new一个新实例，不是更省力？<br>到底在这里能用静态方法吗？还是......<br>真的是好困惑，大家如果对这个有比较清晰的概念，希望能指点迷津。
<img src ="http://www.cnblogs.com/licongjie/aggbug/471071.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47984/" target="_blank">《商业周刊》:Mozilla的志愿者开发模式被复制</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>利用Enterprise Library中的DAAB构造的数据库访问架构</title><link>http://www.cnblogs.com/licongjie/archive/2006/08/02/465928.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Wed, 02 Aug 2006 07:19:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/08/02/465928.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/465928.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/08/02/465928.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/465928.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/465928.html</trackback:ping><description><![CDATA[初学Enterprise Library中的DAAB部分，为了练练，一边学一边参照petshop 4.0写了一个数据库访问的架构，现把代码放上来，希望各位多指点，也可以使自己多学点<br><a href="/Files/licongjie/EnterpriseLibraryTest.rar">/Files/licongjie/EnterpriseLibraryTest.rar</a>
<img src ="http://www.cnblogs.com/licongjie/aggbug/465928.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47977/" target="_blank">Mono 的Virtual PC 虚拟机</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>初学nhibernate碰到的问题</title><link>http://www.cnblogs.com/licongjie/archive/2006/07/28/461964.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Fri, 28 Jul 2006 03:10:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/07/28/461964.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/461964.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/07/28/461964.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/461964.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/461964.html</trackback:ping><description><![CDATA[初次接触nhibernate，照着园子里某位大侠的例子做了一下，可是就是出现下面的这个错误，不知道是什么原因，代码太乱就不帖出来了，我打包了放在下面可以下载，哪位大侠有空，帮助指点指点。错误提示如下图所示：<br><br><img height=248 alt="" src="http://www.cnblogs.com/images/cnblogs_com/licongjie/11.JPG" width=404 border=0><br>其中数据库创建脚本如下：<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">USE&nbsp;[NHibernate]<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>GO<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>SET&nbsp;ANSI_NULLS&nbsp;ON<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>GO<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>SET&nbsp;QUOTED_IDENTIFIER&nbsp;ON<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>GO<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>SET&nbsp;ANSI_PADDING&nbsp;ON<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>GO<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>CREATE&nbsp;TABLE&nbsp;[dbo].[Person](<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;[id]&nbsp;[</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">]&nbsp;IDENTITY(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;NOT&nbsp;NULL,<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;[name]&nbsp;[varchar](</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">)&nbsp;COLLATE&nbsp;Chinese_PRC_CI_AS&nbsp;NOT&nbsp;NULL,<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;CONSTRAINT&nbsp;[PK_Person]&nbsp;PRIMARY&nbsp;KEY&nbsp;CLUSTERED&nbsp;<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>(<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;[id]&nbsp;ASC<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>)WITH&nbsp;(IGNORE_DUP_KEY&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;OFF)&nbsp;ON&nbsp;[PRIMARY]<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>)&nbsp;ON&nbsp;[PRIMARY]<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>GO<br><img src="http://abluedog.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>SET&nbsp;ANSI_PADDING&nbsp;OFF</span><br><br>例子：<a href="/Files/licongjie/test.rar">/Files/licongjie/test.rar</a> 
<img src ="http://www.cnblogs.com/licongjie/aggbug/461964.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47970/" target="_blank">19岁天才黑客发布首个iPhone 3GS破解软件</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>关于远程调用或调用web service的一个问题</title><link>http://www.cnblogs.com/licongjie/archive/2006/07/26/460185.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Wed, 26 Jul 2006 07:40:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/07/26/460185.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/460185.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/07/26/460185.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/460185.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/460185.html</trackback:ping><description><![CDATA[在实际开发中发现这样的一个问题。我用C＃开发的平台需要调用一个java写的web service，我要把调用的信息封装在一个类的实例里，并把该类的实例当做参数，再调用web service的一个方法。如：<br>在web service里有一个方法void endsync(result re) 其中result 类用来封装信息 ，该类是在java里描述的。我用C＃写了一个一样的类result，在本地进行初始化后，调用web service 里的endsync(result re)方法，发现在会出现错误，提示，二个result不能互相转换。<br><br>由这个问题也想到，如果要进行远程调用，而在调用　的时候会返回一个实体类数据，或传送一些实体类数据，那么这些数据在客户端和服务器端是怎么来实现转换的？有哪些措施可以传递这些实体类数据。<br>这个问题困惑我好久，希望各位能够指点迷津。 
<img src ="http://www.cnblogs.com/licongjie/aggbug/460185.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47969/" target="_blank">新浪邮箱大本营粉墨登场！Sina.cn开放注册</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>关于asp.net 1.0升级到asp.net 2.0时发现的一个有趣的问题</title><link>http://www.cnblogs.com/licongjie/archive/2006/05/25/409227.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Thu, 25 May 2006 10:08:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/05/25/409227.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/409227.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/05/25/409227.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/409227.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/409227.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 今天终于把原来的asp.net 1.0程序升级到asp.net 2.0了，vs 2005带有转换向导，一切自动化，操作比较方便。等它自动转换后，突然发现在App_Code文件夹里多了几个比较奇怪的文件都是stub开头的，并在一个mi开头的文件夹中（具体名称因为删除了，忘记了），因为原来根本就没有这些.cs文件，打开一看，原来都是抽象类，有几个还有抽象方法和共有字段。经过查看，才发现，原来在asp.net 1.0中有几个页面后置文件即.aspx.cs文件，里面有public方法和public 字段，所有的这些类都被抽象出一个类来，原来的类名被更改并继续该抽象类，而所有的public 方法和public 字段也被提取到抽象类中去了，原来类中的public字段被删除，而原来类中的public方法都被改成override抽象类中的抽象方法。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果要把这些抽象类删除，也方便，但要把原来的类改回原状，就可以了。<br>　&nbsp;&nbsp;&nbsp; 因为在网上查看asp.net 1.0转换到asp.net 2.0时注意事项，并没有看到这一项，在这里发一下，希望能够给一些朋友一些帮助。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<img src ="http://www.cnblogs.com/licongjie/aggbug/409227.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47968/" target="_blank">IE市场份额首次跌破60%</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>利用asp.net 2.0的客户端回调功能制作下拉框无限级联动</title><link>http://www.cnblogs.com/licongjie/archive/2006/05/25/408766.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Thu, 25 May 2006 03:38:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/05/25/408766.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/408766.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/05/25/408766.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/408766.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/408766.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 记得以前做asp的时候，常会碰到下拉框多级联动，比如说在注册的时候，需要选择省和城市，这就需要二级联动，那个时候一个普遍的做法就是利用javascript脚本来实现，先把数据从数据库中读取出来，放到javascript的数组中，在下拉框的onchange事件触发时，就可以直接从javascript的数组中读取想要的数据。后来在asp.net 1.0中开发时，这种方法也通用，但如果要多级的话，有一个很大的缺点，就是它需要把数据一次性全部读到javascript的数组中，如果数据非常庞大的话，这部分开销是很大的，有时候不把数据放到数据中中，而是直接写在javascript中，这样不易于维护，而且代码也太长，如果要开发可以无限级联的话，那更是比较头痛。自从asp,net 2.0问世后，开始学习新技术，发现asp,net2.0不仅在控件上，功能上都产生了大变化，而且在对javascript客户脚本的调用功能也更加强大了，特别是出现了ajax功能，即客户端回调功能（当然这只是一个小小的ajax功能，如果要实现功能更强大的无刷新可看atlas），利用这个特性可以很方便的开发现无限级联动的下拉框效果。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、先在数据库里建立相应的数据表如下：<br>
<div align=left src_cetemp="/images/cnblogs_com/licongjie/df.jpg"><img height=291 alt="" src="http://www.cnblogs.com/images/cnblogs_com/licongjie/df.jpg" width=305 border=0><br>　2、建立读取数据表的函数，这里就不写出来了，我想每个人都会有不同的方法去实现这一功能。<br>&nbsp;&nbsp;&nbsp; 3、接下来，我们就可以进行页面设置了，我们先做一个二级联动的效果，在页面上放置二个下拉框控件，上面一个为TestDropDownList，下面一个为Item1，再加入一个objectdatasource控件，用来读取parentId为0的所有记录绑定到TestDropDownList下拉框中，如下图：<br><img height=206 alt="" src="http://www.cnblogs.com/images/cnblogs_com/licongjie/2.jpg" width=235 border=0><br>　　如果要使用客户端回调，必须要实现System.Web.UI.ICallbackEventHandler接口。<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;partial&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Test&nbsp;:&nbsp;System.Web.UI.Page&nbsp;,&nbsp;System.Web.UI.ICallbackEventHandler<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img id=Codehighlighter1_85_86_Open_Image onclick="this.style.display='none'; Codehighlighter1_85_86_Open_Text.style.display='none'; Codehighlighter1_85_86_Closed_Image.style.display='inline'; Codehighlighter1_85_86_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_85_86_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_85_86_Closed_Text.style.display='none'; Codehighlighter1_85_86_Open_Image.style.display='inline'; Codehighlighter1_85_86_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_85_86_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_85_86_Open_Text><span style="COLOR: #000000">{</span></div>
</span></div>
　　该接口下面，有二个方法：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a)、void System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string eventArguent)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;　该方法接收客户端传过来的参数enentArguent，这个参数好象只能是string型，并且没有返回值，我们可以根据传过来的参数，来执行相应的功能，在这里我们不能对页面进行重新绑定等操作，但能够跟数据库进行交互操作，如读取、删除、插入等操作，在本文的例子中，这里从客户端传过来的是parentId的值，再从数据库中读取parentId为相应值的所有记录，具体代码如下：<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: #008080">&nbsp;1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;eventArguent)<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img id=Codehighlighter1_85_515_Open_Image onclick="this.style.display='none'; Codehighlighter1_85_515_Open_Text.style.display='none'; Codehighlighter1_85_515_Closed_Image.style.display='inline'; Codehighlighter1_85_515_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_85_515_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_85_515_Closed_Text.style.display='none'; Codehighlighter1_85_515_Open_Image.style.display='inline'; Codehighlighter1_85_515_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_85_515_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_85_515_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataSet&nbsp;ds&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;GetData().TestByParentId(Convert.ToInt32(eventArguent));<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">foreach</span><span style="COLOR: #000000">(DataRow&nbsp;row&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;ds.Tables[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">].Rows)<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img id=Codehighlighter1_227_509_Open_Image onclick="this.style.display='none'; Codehighlighter1_227_509_Open_Text.style.display='none'; Codehighlighter1_227_509_Closed_Image.style.display='inline'; Codehighlighter1_227_509_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_227_509_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_227_509_Closed_Text.style.display='none'; Codehighlighter1_227_509_Open_Image.style.display='inline'; Codehighlighter1_227_509_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_227_509_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_227_509_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(result.Equals(</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">.Empty))<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img id=Codehighlighter1_286_369_Open_Image onclick="this.style.display='none'; Codehighlighter1_286_369_Open_Text.style.display='none'; Codehighlighter1_286_369_Closed_Image.style.display='inline'; Codehighlighter1_286_369_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_286_369_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_286_369_Closed_Text.style.display='none'; Codehighlighter1_286_369_Open_Image.style.display='inline'; Codehighlighter1_286_369_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_286_369_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_286_369_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;row[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pkId</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">@</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;row[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">name</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">].ToString();<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img id=Codehighlighter1_401_499_Open_Image onclick="this.style.display='none'; Codehighlighter1_401_499_Open_Text.style.display='none'; Codehighlighter1_401_499_Closed_Image.style.display='inline'; Codehighlighter1_401_499_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_401_499_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_401_499_Closed_Text.style.display='none'; Codehighlighter1_401_499_Open_Image.style.display='inline'; Codehighlighter1_401_499_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_401_499_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_401_499_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;result&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;row[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pkId</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">@</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;row[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">name</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">].ToString();<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>　　在这里，通过TestByParentId(Convert.ToInt32(enentArguent))函数读到相应数据，并把得到的数据作了一些处理，这个为什么要这样做，请继续往下看。这里的result为string型变量。<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b)、string System.Web.UI.ICallbackEventHandler.GetCallbackResult()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这是第二个方法，该方法没有参数，返回只能返回string型。这个方法是用来数据回调的，上面那个方法接收客户端传过来的参数，进行处理后，还要把处理后的我们想要的数据传回到客户端去执行，才会有用。这里我们也看到了，由于该方法只能返回string型，而在下拉框必须有二个值，一个是DataValue,另一个是DataText，所以在上面的方法中，通过＠符号，把这二个值合在一起，便于在客户端程序中进行分离。这个方法功能很简单，就是把result返回即可，如下：<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;System.Web.UI.ICallbackEventHandler.GetCallbackResult()<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img id=Codehighlighter1_67_96_Open_Image onclick="this.style.display='none'; Codehighlighter1_67_96_Open_Text.style.display='none'; Codehighlighter1_67_96_Closed_Image.style.display='inline'; Codehighlighter1_67_96_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_67_96_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_67_96_Closed_Text.style.display='none'; Codehighlighter1_67_96_Open_Image.style.display='inline'; Codehighlighter1_67_96_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_67_96_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_67_96_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;result;<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>　　现在我们实现了System.Web.UI.ICallbackEventHandler接口下的全部方法，接下来我们就可以来写客户端的程序了，用javascript来实现。这里主要也有二个方法，第一个方法用来接受下拉框控件的onchange事件触发响应，另一个用来接收string System.Web.UI.ICallbackEventHandler.GetCallbackResult()方法传递过来的result值，并做相应处理，把数据绑定到第二个下拉框中去，实现 二级联动。主要代码如下<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a)、第一个方法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;CallServer(input,&nbsp;context)<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img id=Codehighlighter1_41_200_Open_Image onclick="this.style.display='none'; Codehighlighter1_41_200_Open_Text.style.display='none'; Codehighlighter1_41_200_Closed_Image.style.display='inline'; Codehighlighter1_41_200_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_41_200_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_41_200_Closed_Text.style.display='none'; Codehighlighter1_41_200_Open_Image.style.display='inline'; Codehighlighter1_41_200_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_41_200_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_41_200_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.length</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.options[context.length]</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Option(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">数据读取中<img src="http://www.cnblogs.com/Images/dot.gif"></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;input.value;<br></span><span style="COLOR: #008080">7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">&lt;%=</span><span style="COLOR: #000000">callback&nbsp;</span><span style="COLOR: #000000">%&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">8</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>　　这里有二个参数，input是用来触发onchange的下拉框控件名称，context是要级联的下拉框名称，这里在数据还没有绑定之前，级联下拉框显示&#8220;数据读取中...&#8221;字样。arg接收input下拉框的值，这个值以后是传递到上面的eventArguent参数中去，其中的&lt;%=callback%&gt;我们下面再介绍。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b)、第二个方法<br>&nbsp;&nbsp;&nbsp;
<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: #008080">&nbsp;1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000">&nbsp;ReceiveServerData(result,&nbsp;context)<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img id=Codehighlighter1_49_318_Open_Image onclick="this.style.display='none'; Codehighlighter1_49_318_Open_Text.style.display='none'; Codehighlighter1_49_318_Closed_Image.style.display='inline'; Codehighlighter1_49_318_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_49_318_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_49_318_Closed_Text.style.display='none'; Codehighlighter1_49_318_Open_Image.style.display='inline'; Codehighlighter1_49_318_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_49_318_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_49_318_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.length</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;arrData&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;result.split(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;arrData.length;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img id=Codehighlighter1_175_304_Open_Image onclick="this.style.display='none'; Codehighlighter1_175_304_Open_Text.style.display='none'; Codehighlighter1_175_304_Closed_Image.style.display='inline'; Codehighlighter1_175_304_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_175_304_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_175_304_Closed_Text.style.display='none'; Codehighlighter1_175_304_Open_Image.style.display='inline'; Codehighlighter1_175_304_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_175_304_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_175_304_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">&nbsp;data&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;arrData[i].split(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">@</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context.options[context.length]</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Option(data[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">],data[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">]);<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里也有二个参数，其中result，就是接收上面讲到的result值，而context同第一个方法的context。这里通过js的split方法，把数据进行处理，再绑定到context控件中去，通过这个就可以在第二个下拉框中出现相应的值了。<br>　　做到这里基本上已经大功告成了，不过还有最后一步，这也是最重要的一步，我们现在做的只是客户端归客户端，服务器方法归服务器方法，那么怎么样把这二个联系起来呢，这也是实现客户端回调的关键部分，这里需要使用Page.ClientScript.GetCallbackEventReference方法，下面是摘自MSDN2上的对ClientScript.GetCallbackEventReference(&#8230;&#8230;)的详细说明。 <br>&nbsp;&nbsp; <br>&nbsp;&nbsp;public string GetCallbackEventReference (Control control,string argument,string clientCallback,string context) <br>&nbsp;&nbsp; <br>&nbsp;&nbsp;　　参数： <br>&nbsp;&nbsp; <br>&nbsp;&nbsp;参数 作用 <br>&nbsp;&nbsp;control 处理客户端回调的服务器 Control。该控件必须实现 ICallbackEventHandler 接口并提供 RaiseCallbackEvent 方法。 <br>&nbsp;&nbsp;argument 从客户端脚本传递一个参数到服务器端的RaiseCallbackEvent 方法。 <br>&nbsp;&nbsp;clientCallback 一个客户端事件处理程序的名称，该处理程序接收服务器端事件返回的结果。 <br>&nbsp;&nbsp;context 启动回调之前在客户端的客户端脚本信息。脚本的结果传回给客户端事件处理程序。 <br>&nbsp;&nbsp;返回值 调用客户端回调的客户端函数的名称。 <br>&nbsp;&nbsp; <br>&nbsp;&nbsp;　　下面是ClientScriptManager.GetCallbackEventReference 方法的重载列表 <br>&nbsp;&nbsp; <br>&nbsp;&nbsp;名称 说明 <br>&nbsp;&nbsp;ClientScriptManager.GetCallbackEventReference (Control, String, String, String) 获取一个对客户端函数的引用；调用该函数时，将启动一个对服务器端事件的客户端回调。此重载方法的客户端函数包含指定的控件、参数、客户端脚本和上下文。 <br>&nbsp;&nbsp;ClientScriptManager.GetCallbackEventReference (Control, String, String, String, Boolean) 获取一个对客户端函数的引用；调用该函数时，将启动一个对服务器端事件的客户端回调。此重载方法的客户端函数包含指定的控件、参数、客户端脚本、上下文和布尔值。 <br>&nbsp;&nbsp;ClientScriptManager.GetCallbackEventReference (Control, String, String, String, String, Boolean) 获取一个对客户端函数的引用；调用该函数时，将启动一个对服务器端事件的客户端回调。此重载方法的客户端函数包含指定的控件、参数、客户端脚本、上下文、错误处理程序和布尔值。 <br>&nbsp;&nbsp;ClientScriptManager.GetCallbackEventReference (String, String, String, String, String, Boolean) 获取一个对客户端函数的引用；调用该函数时，将启动一个对服务器端事件的客户端回调。此重载方法的客户端函数包含指定的目标、参数、客户端脚本、上下文、错误处理程序和布尔值。&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 主要实现如下：<br>&nbsp;&nbsp;&nbsp; 在page_load里加入下面语句<br>&nbsp;&nbsp;&nbsp;
<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">callback&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Page.ClientScript.GetCallbackEventReference(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">arg</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ReceiveServerData</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">context</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>
<br>&nbsp;&nbsp;&nbsp; 其中，arg就是用来从客户端传递参数，最终传到enentArguent中，ReceiveServerData是一个客户端方法，用来接收服务器端回调过来的数据。<br><br>&nbsp;&nbsp;&nbsp; 再把callback这个字符串放在第一个客户端方法下面（请看上面的第一个客户端方法）<br><br>&nbsp;&nbsp;&nbsp; 这个完成后，我们只要把第一个下拉框的onchange客户端事件加入就可以了<br>&nbsp;&nbsp;&nbsp; 在page_load里加入<br>&nbsp;&nbsp;&nbsp;
<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">TestDropDownList.Attributes[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">onchange</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">javascript:CallServer(TestDropDownList&nbsp;,&nbsp;Item1)</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;</span></div>
<p><br><br>&nbsp;&nbsp;&nbsp; 做完所有这些，程序应该能够正常动行了<br><img alt="" src="http://www.cnblogs.com/images/cnblogs_com/licongjie/3.jpg" border=0></p>
<p>　　现在二级联动已经成功，那怎么能够实现多级的呢，其实大家只要仔细的看一下，就不难发现，当我触到一个下拉框的onchange事件，通过callServer读取值，再通过&lt;%callback%&gt;来启动 void System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string eventArguent)这个方法，把数据处理后，通过string System.Web.UI.ICallbackEventHandler.GetCallbackResult()方法返回，再由ReceiveServerData客户端来把数据绑定到相应原下拉框中，而这里的二个互动的下拉框都是通过参数来传递的， TestDropDownList.Attributes["onchange"] = "javascript:CallServer(TestDropDownList , Item1)";　这样的话，我们可以改变这里传递的控件参数名，就可以重复利用这四个方法，也就是这样就可以实现，无限级联动。我们再加入一个下拉框，取名Item2，我们只要在page_load中加入如下语句即可：<br></p>
<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">Item1.Attributes[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">onchange</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">javascript:CallServer(Item1&nbsp;,&nbsp;Item2)</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;</span></div>
<br>就就可以三级联动了，如果要四级，五级，只要加入下应的下拉框，并在page_load中加入相应的onchange事件触发，就可以实现了<br><br>不过这种方法目前还有一个很大的二个缺点：<br>&nbsp;&nbsp;&nbsp; 1、那就是当第一个选择后，第二个下拉框会出现相应的值，而第三个以及下面的几个不会变，只有再选择第二个下拉框的值后，第三个才会改变<br>&nbsp;&nbsp;&nbsp; 2、由于1的问题，导致如果第二个下拉框中只有一个值，那么第三个以及以下几个都不能发生改变了<br>不知道大家有没有好的解决方法，我相信应该有解决的方法的。<br>&nbsp;&nbsp;&nbsp; 由于本人水平有限，可能有不当之处，希望大家能够指正，谢谢！ 
<img src ="http://www.cnblogs.com/licongjie/aggbug/408766.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47968/" target="_blank">IE市场份额首次跌破60%</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>关于httpcontext实际使用时出现的一个问题</title><link>http://www.cnblogs.com/licongjie/archive/2006/05/24/408232.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Wed, 24 May 2006 09:52:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/05/24/408232.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/408232.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/05/24/408232.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/408232.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/408232.html</trackback:ping><description><![CDATA[<p>　　在一次实际开发过程中，需要同步服务器上的用户，用户同步是通过XML文件来获取，当时还有一个配置文件也是xml文件放在本地，这个时候就需要使用到Server.MapPath功能或HttpContext.current.server.mappath功能，把相对路径转变成绝对路径，以用来对XML文件的读取、删除操作。本来这个功能非常简单，但是由于用户同步需要在规定间隔内自动同步，这个时候我用了timer时间触发器，在Global.asax.cs里代码如下：<br></p>
<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: #008080">&nbsp;1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Application_Start(Object&nbsp;sender,&nbsp;EventArgs&nbsp;e)<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img id=Codehighlighter1_63_229_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_229_Open_Text.style.display='none'; Codehighlighter1_63_229_Closed_Image.style.display='inline'; Codehighlighter1_63_229_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_229_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_229_Closed_Text.style.display='none'; Codehighlighter1_63_229_Open_Image.style.display='inline'; Codehighlighter1_63_229_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_63_229_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_63_229_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Timer&nbsp;time&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Timer(</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">60</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.Elapsed&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ElapsedEventHandler(time_Elapsed);<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.AutoReset&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.Enabled&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top><br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>&nbsp;&nbsp;&nbsp; 时间间隔处理事件如下：<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;time_Elapsed(</span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">&nbsp;sender,&nbsp;ElapsedEventArgs&nbsp;e)<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img id=Codehighlighter1_63_173_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_173_Open_Text.style.display='none'; Codehighlighter1_63_173_Closed_Image.style.display='inline'; Codehighlighter1_63_173_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_173_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_173_Closed_Text.style.display='none'; Codehighlighter1_63_173_Open_Image.style.display='inline'; Codehighlighter1_63_173_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_63_173_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_63_173_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;web.User.SSOUtility&nbsp;su&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;web.User.SSOUtility();<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;su.SynUser();<br></span><span style="COLOR: #008080">6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>&nbsp;&nbsp;&nbsp; 而此时在SSOUtility.cs文件里设置读取配制文件和下载到本地的同步用户文件<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;UserXmlFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;HttpContext.Current.Server.MapPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SBWLogin/user.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;SSOConfigFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;HttpContext.Current.Server.MapPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SBWLogin/SSOConfig.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>
<br>　通过一个Button来触发SynUser()事件，一切运行正常，但到通过Timer来控制时，发现数据不能同步，通过调试发现，原来程序一运行到<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;UserXmlFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;HttpContext.Current.Server.MapPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SBWLogin/user.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;SSOConfigFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;HttpContext.Current.Server.MapPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SBWLogin/SSOConfig.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>
就出错，查了半天才发现原来是httpcontext这个上下文HTTP请求信息在时间间隔触发时，根本就不起作用，也就是说不能获取上下文HTTP请求对象，后来把这二句读取文件和语句放到Global.asax.cs上来，并修改SSOUtility&nbsp; 构造函数用来实例化对象时，传入二个文件的绝对地址。如下：<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: #008080">1</span><img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;time_Elapsed(</span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">&nbsp;sender,&nbsp;ElapsedEventArgs&nbsp;e)<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img id=Codehighlighter1_63_173_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_173_Open_Text.style.display='none'; Codehighlighter1_63_173_Closed_Image.style.display='inline'; Codehighlighter1_63_173_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_173_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_173_Closed_Text.style.display='none'; Codehighlighter1_63_173_Open_Image.style.display='inline'; Codehighlighter1_63_173_Open_Text.style.display='inline';" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_63_173_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_63_173_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;web.User.SSOUtility&nbsp;su&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;web.User.SSOUtility(UserXmlFile,&nbsp;SSOConfigFile);<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;su.SynUser();<br></span><span style="COLOR: #008080">6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>这时再运行程序，一切OK。<br>以前总以为只要我在vs.net 2003里能出现httpcontext.current这些提示，并且编译通过就应该没有问题了，经过这次的经历，才发现httpcontext通过页面触发没有问题，直接从Global.asax.cs调用也行，但只能执行一次，但从Global.asax.cs的timer时间间隔事件中触发时，其实例化对象获取失败。<br><br>&nbsp;&nbsp;&nbsp; 终于写完了，这可是我的处女作啊，本人经验有限，可能会出现一些不当之处，敬请谅解，还希望高手能够指正我的错误，多给点意见，也能让自己多学点东西 
<img src ="http://www.cnblogs.com/licongjie/aggbug/408232.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47965/" target="_blank">Google App Engine宕机6小时——云的安全在哪里？</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>关于httpcontext存在时期</title><link>http://www.cnblogs.com/licongjie/archive/2006/05/24/408223.html</link><dc:creator>李.net</dc:creator><author>李.net</author><pubDate>Wed, 24 May 2006 09:47:00 GMT</pubDate><guid>http://www.cnblogs.com/licongjie/archive/2006/05/24/408223.html</guid><wfw:comment>http://www.cnblogs.com/licongjie/comments/408223.html</wfw:comment><comments>http://www.cnblogs.com/licongjie/archive/2006/05/24/408223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/licongjie/comments/commentRss/408223.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/licongjie/services/trackbacks/408223.html</trackback:ping><description><![CDATA[<p>　　在一次实际开发过程中，需要同步服务器上的用户，用户同步是通过XML文件来获取，当时还有一个配置文件也是xml文件放在本地，这个时候就需要使用到Server.MapPath功能或HttpContext.current.server.mappath功能，把相对路径转变成绝对路径，以用来对XML文件的读取、删除操作。本来这个功能非常简单，但是由于用户同步需要在规定间隔内自动同步，这个时候我用了timer时间触发器，在Global.asax.cs里代码如下：<br></p>
<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: #008080">&nbsp;1</span><img src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">protected</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Application_Start(Object&nbsp;sender,&nbsp;EventArgs&nbsp;e)<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img id=Codehighlighter1_63_229_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_229_Open_Text.style.display='none'; Codehighlighter1_63_229_Closed_Image.style.display='inline'; Codehighlighter1_63_229_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_229_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_229_Closed_Text.style.display='none'; Codehighlighter1_63_229_Open_Image.style.display='inline'; Codehighlighter1_63_229_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_63_229_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_63_229_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Timer&nbsp;time&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Timer(</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">60</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.Elapsed&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ElapsedEventHandler(time_Elapsed);<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.AutoReset&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time.Enabled&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top><br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>&nbsp;&nbsp;&nbsp; 时间间隔处理事件如下：<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: #008080">1</span><img src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;time_Elapsed(</span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">&nbsp;sender,&nbsp;ElapsedEventArgs&nbsp;e)<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img id=Codehighlighter1_63_173_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_173_Open_Text.style.display='none'; Codehighlighter1_63_173_Closed_Image.style.display='inline'; Codehighlighter1_63_173_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_173_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_173_Closed_Text.style.display='none'; Codehighlighter1_63_173_Open_Image.style.display='inline'; Codehighlighter1_63_173_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_63_173_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_63_173_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;web.User.SSOUtility&nbsp;su&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;web.User.SSOUtility();<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;su.SynUser();<br></span><span style="COLOR: #008080">6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>&nbsp;&nbsp;&nbsp; 而此时在SSOUtility.cs文件里设置读取配制文件和下载到本地的同步用户文件<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: #008080">1</span><img src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;UserXmlFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;HttpContext.Current.Server.MapPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SBWLogin/user.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;SSOConfigFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;HttpContext.Current.Server.MapPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SBWLogin/SSOConfig.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>
<br>　通过一个Button来触发SynUser()事件，一切运行正常，但到通过Timer来控制时，发现数据不能同步，通过调试发现，原来程序一运行到<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: #008080">1</span><img src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;UserXmlFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;HttpContext.Current.Server.MapPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SBWLogin/user.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">&nbsp;SSOConfigFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;HttpContext.Current.Server.MapPath(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">SBWLogin/SSOConfig.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div>
就出错，查了半天才发现原来是httpcontext这个上下文HTTP请求信息在时间间隔触发时，根本就不起作用，也就是说不能获取上下文HTTP请求对象，后来把这二句读取文件和语句放到Global.asax.cs上来，并修改SSOUtility&nbsp; 构造函数用来实例化对象时，传入二个文件的绝对地址。如下：<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: #008080">1</span><img src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;time_Elapsed(</span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">&nbsp;sender,&nbsp;ElapsedEventArgs&nbsp;e)<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img id=Codehighlighter1_63_173_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_173_Open_Text.style.display='none'; Codehighlighter1_63_173_Closed_Image.style.display='inline'; Codehighlighter1_63_173_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_173_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_173_Closed_Text.style.display='none'; Codehighlighter1_63_173_Open_Image.style.display='inline'; Codehighlighter1_63_173_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_63_173_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnblogs.com/Images/dot.gif"></span><span id=Codehighlighter1_63_173_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;web.User.SSOUtility&nbsp;su&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;web.User.SSOUtility(UserXmlFile,&nbsp;SSOConfigFile);<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;su.SynUser();<br></span><span style="COLOR: #008080">6</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">7</span><span style="COLOR: #000000"><img src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br>这时再运行程序，一切OK。<br>以前总以为只要我在vs.net 2003里能出现httpcontext.current这些提示，并且编译通过就应该没有问题了，经过这次的经历，才发现httpcontext通过页面触发没有问题，直接从Global.asax.cs调用也行，但只能执行一次，但从Global.asax.cs的timer时间间隔事件中触发时，其实例化对象获取失败。<br><br>&nbsp;&nbsp;&nbsp; 终于写完了，这可是我的处女作啊，本人经验有限，可能会出现一些不当之处，敬请谅解，还希望高手能够指正我的错误，多给点意见，也能让自己多学点东西 
 <img src ="http://www.cnblogs.com/licongjie/aggbug/408223.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47965/" target="_blank">Google App Engine宕机6小时——云的安全在哪里？</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item></channel></rss>