<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[friend365 - .NET开发]]></title>
<link>http://www.friend365.cn/</link>
<description><![CDATA[敬业是对渴望成功的人对待工作的基本要求，思想决定行为，行为形成习惯，习惯决定性格，性格决定命运。永久域名www.friend365.cn]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005-2009 friend365.cn]]></copyright>
<webMaster><![CDATA[friend365@163.com(美丽人生)]]></webMaster>
<generator>friend365.cn</generator> 
<image>
	<title>friend365</title> 
	<url>http://www.friend365.cn/images/logomy.gif</url> 
	<link>http://www.friend365.cn/</link> 
	<description>friend365</description> 
</image>

			<item>
			<link>http://www.friend365.cn/default.asp?id=1084</link>
			<title><![CDATA[C#2008 水晶报表]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Thu,19 Mar 2009 12:53:00 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=1084</guid>	
		<description><![CDATA[C#2008 水晶报表怎么动态修改 TextObject 文本对象的值<br /><br />this.CrystalReportSource1.ReportDocument.SetParameterValue(&quot;AreaName&quot;, &quot;&quot;); <br />  <br /> 给水晶报表添加一个参数AreaName <br /> 画面中一个textbox 一个 button <br />  <br /> button的click中加 <br />  <br /> this.CrystalReportSource1.ReportDocument.SetParameterValue(&quot;AreaName&quot;, textbox.text);]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=1082</link>
			<title><![CDATA[ASP.net工作线程池]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Thu,19 Mar 2009 12:48:08 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=1082</guid>	
		<description><![CDATA[<p>当 ASP.NET 接收针对页的请求时，它从线程池中提取一个线程并将请求分配给该线程。 </p>
<p>一个普通的（或同步的）页在该请求 期间保留线程，从而防止该线程用于处理其他请求。如果一个同步请求成为 I/O bound（例如，如果它调用一个远程 Web 服务或查询一个远程数据库，并等待调用返回），那么分配给该请求的线程在调用返回之前处于挂起状态。 这影响了可伸缩性，原因是线程池的可用线程是有限的。 </p>
<p>这个数字的设置是在 machine.config 的 下述节点的 maxWorkerThreads 属性</p>
<pre><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">system.web</span><span style="color: rgb(0, 0, 255);">&gt;</span><br />	<span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">processModel</span> <span style="color: rgb(255, 0, 0);">requestQueueLimit</span>=<span style="color: rgb(0, 0, 255);">&quot;num|Infinite&quot;</span> <span style="color: rgb(255, 0, 0);">maxWorkerThreads</span>=<span style="color: rgb(0, 0, 255);">&quot;num&quot;</span>  <span style="color: rgb(0, 0, 255);">/&gt;</span><br /><span style="color: rgb(0, 0, 255);"><!--</span--><span style="color: rgb(128, 0, 0);">system.web</span><span style="color: rgb(0, 0, 255);">&gt;</span></span></pre>
<p><strong>maxWorkerThreads      <br /></strong>按 CPU 配置用于进程的辅助线程的最大数目。例如，如果单处理器服务器上的该值为 25，ASP.NET 使用运行时 API 将进程限制设置为 25。在双处理器服务器上，该限制设置为 50。该属性的值必须等于或大于 httpRuntime 配置节中的 minFreeThread 属性设置。 <br />该属性的范围是从 5 到 100。     <br /></p>
<h2><strong>ASP.net请求队列</strong></h2>
<p>上述设置中，还有一个队列设置，如下：</p>
<p>   <br /><strong>requestQueueLimit </strong>    <br />指定队列中允许的请求数，超过此数目后，ASP.NET 将开始向新请求返回&ldquo;503 - 服务器太忙&rdquo;消息。     <br /></p>
<p>&nbsp;</p>
<p>默认情况下,这个可用分线程数为1000。下图为IIS6和IIS7中这个参数的设置地方。</p>
<p>IIS 7 的可用线程数设置</p>
<p><img src="http://blog.joycode.com/images/blog.joycode.com/ghj/1362/o_0001.jpg" alt="" /></p>
<p>IIS 6 的可用线程数设置</p>
<p><img src="http://blog.joycode.com/images/blog.joycode.com/ghj/1362/o_0002.jpg" alt="" /></p>
<p>&nbsp;</p>
<p>如果所有请求处理线程全部阻塞以等待 I/O 操作完成，则其他请求排入队列等待线程释放。 </p>
<p>最好的情况是吞吐量减少，因为请求等待较长的时间才能得到处理。 </p>
<p>最坏的情况则是该队列填满，并且 ASP.NET 因 503&ldquo;Server Unavailable&rdquo;错误使后续请求失败。</p>
<p>&nbsp;</p>
<p><strong>参考资料:</strong></p>
<p>在服务器端 Web 代码中使用线程和生成异步处理程序    <br /><a href="http://msdn.microsoft.com/zh-cn/library/aa686076.aspx" title="http://msdn.microsoft.com/zh-cn/library/aa686076.aspx">http://msdn.microsoft.com/zh-cn/library/aa686076.aspx</a></p>
<p>ASP.NET 2.0 中的异步页    <br /><a href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/issuesWickedCodetoc.mspx" title="http://www.microsoft.com/china/msdn/library/webservices/asp.net/issuesWickedCodetoc.mspx">http://www.microsoft.com/china/msdn/library/webservices/asp.net/issuesWickedCodetoc.mspx</a></p>
<p>IIS 6.0 架构    <br /><a href="http://blog.csdn.net/heaven_pl/archive/2008/02/19/2106572.aspx" title="http://blog.csdn.net/heaven_pl/archive/2008/02/19/2106572.aspx">http://blog.csdn.net/heaven_pl/archive/2008/02/19/2106572.aspx</a>     <br /><a href="http://blog.csdn.net/heaven_pl/archive/2008/02/19/2106579.aspx" title="http://blog.csdn.net/heaven_pl/archive/2008/02/19/2106579.aspx">http://blog.csdn.net/heaven_pl/archive/2008/02/19/2106579.aspx</a></p>
<br />
<p>IIS 7.0 架构    <br /><a href="http://blog.csdn.net/SKY_VID/archive/2008/03/04/2147732.aspx" title="http://blog.csdn.net/SKY_VID/archive/2008/03/04/2147732.aspx">http://blog.csdn.net/SKY_VID/archive/2008/03/04/2147732.aspx</a></p>
<p>&nbsp;</p>
<p>了解ASP.NET底层架构    <br /><a href="http://blog.csdn.net/fanweiwei/archive/2007/04/10/1558912.aspx" title="http://blog.csdn.net/fanweiwei/archive/2007/04/10/1558912.aspx">http://blog.csdn.net/fanweiwei/archive/2007/04/10/1558912.aspx</a></p>]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=1075</link>
			<title><![CDATA[优化ASP.NET应用性能]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Tue,17 Mar 2009 12:09:03 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=1075</guid>	
		<description><![CDATA[如果你有在IE中查看当前浏览页面HTML源代码的习惯，你也许常会看到类似以下的代码片断： <br/>　　&lt;input type=&#34;hidden&#34; name=&#34;__VIEWSTATE&#34; value=&#34;dDwtMzU5NzUyMTQ1O3Q8O2w8aTwwPjs+O2w8dDw7bDxpPDA+Oz47bDx0PDtsPG <br/>　　…… <br/><br/>　　 聪明的你一定会问，这是什么？有什么作用？它与本篇文章有何转折亲关系？各位看官，且听我慢慢道来。 <br/>　　 其实，这就是MS在Asp.net应用ViewState技术的特征表现。为了页面能在PostBack后依然能读取服务器控件原有的状态数据，Asp.net中使用了ViewState技术，而ViewState技术本质上是用一个默认名称为&#34;__VIEWSTATE的 Hidden类型表单域来保存和传递数据（这些数据是经过了序列化后Base64编码的字符串值，且是在方法 Page.SavePageStateToPersistenceMedium输出前保存、并由 Page.LoadPageStateFromPersistenceMedium加载）。虽然我们可以通过三种级别来轻松禁用掉这些数据的往返传递： <br/><br/>　　Machine级 在machine.config中设置&lt;pages enableViewStateMac=&#39;false&#39; /&gt; <br/>　　Application级 在Web Applicatin的web.config中设置&lt;pages enableViewStateMac=&#39;false&#39; /&gt; <br/>　　单页面级 在该页面中设置&lt;%@Page enableViewStateMac=&#39;false&#39; %&gt;或通过代码设置Page.EnableViewStateMac = false; <br/>　　 <br/>　　 可是，如果我们完全能通过禁用ViewState来解决数据传输负担而且不产生副作用的话，那MS的架构师们也不会傻到如此可爱的地步（可有可无的东东留它何用？），正因我们往往不能通过简单的禁用来解决这个传输负担问题，所以我们只能另辟路径使之在网络往返中传输量尽可能地小，于是，压缩成了我们的首选。只要我们重载Page类的SavePageStateToPersistenceMedium（）方法与 LoadPageStateFromPersistenceMedium（）方法，并在重载方法中对数据进行压缩与解压的处理即可。开源项目 SharpZipLib提供的类GZipInputStream与GZipOutputStream进入了我们的视野，为了方便，不妨写个类 CompressionHelper，代码如下： <br/><br/>using System.IO; <br/>　　using ICSharpCode.SharpZipLib.GZip; <br/>　　 <br/>　　namespace Ycweb.Components <br/>　　{ <br/>　　 /**//// &lt;summary&gt; <br/>　　 /// Summary description for CompressionHelper. <br/>　　 /// &lt;/summary&gt; <br/>　　 public class CompressionHelper <br/>　　 { <br/>　　 public CompressionHelper() <br/>　　 { <br/>　　 // <br/>　　 // TODO: Add constructor logic here <br/>　　 // <br/>　　 } <br/>　　 <br/>　　 /**//// &lt;summary&gt; <br/>　　 /// 压缩数据 <br/>　　 /// &lt;/summary&gt; <br/>　　 /// &lt;param name=&#34;data&#34;&gt;待压缩的字节数组&lt;/param&gt; <br/>　　 /// &lt;returns&gt;压缩后的字节数组&lt;/returns&gt; <br/>　　 public static byte[] CompressByte(byte[] data) <br/>　　 { <br/>　　 MemoryStream ms = new MemoryStream(); <br/>　　 Stream s=new GZipOutputStream(ms); <br/>　　 s.Write( data, 0, data.Length ); <br/>　　 s.Close(); <br/>　　 return ms.ToArray(); <br/>　　 } <br/>　　 <br/>　　 /**//// &lt;summary&gt; <br/>　　 /// 解压数据 <br/>　　 /// &lt;/summary&gt; <br/>　　 /// &lt;param name=&#34;data&#34;&gt;待解压的字节数组&lt;/param&gt; <br/>　　 /// &lt;returns&gt;解压出的字节数组&lt;/returns&gt; <br/>　　 public static byte[] DeCompressByte(byte[] data) <br/>　　 { <br/>　　 byte[] writeData = new byte[2048]; <br/>　　 MemoryStream ms= new MemoryStream( data ); <br/>　　 Stream sm = new GZipInputStream(ms) as Stream; <br/>　　 MemoryStream outStream = new MemoryStream(); <br/>　　 while (true) <br/>　　 { <br/>　　 int size = sm.Read(writeData,0, writeData.Length ); <br/>　　 if (size &gt;0) <br/>　　 { <br/>　　 outStream.Write(writeData,0,size); <br/>　　 } <br/>　　 else <br/>　　 { <br/>　　 break; <br/>　　 } <br/>　　 } <br/>　　 sm.Close(); <br/>　　 byte[] outArr = outStream.ToArray(); <br/>　　 outStream.Close(); <br/>　　 return outArr; <br/>　　 } <br/>　　 } <br/>　　} <br/><br/>　　 然后我们在派生于类Page的页面控制基类中 <br/><br/>重载方法LoadPageStateFromPersistenceMedium()与SavePageStateToPersistenceMedium(Object viewState),代码如下: <br/>#region Load &amp; Save ViewState Data <br/>protected override object LoadPageStateFromPersistenceMedium() <br/>{ <br/>//从自己注册的隐藏域__SmartViewState中读取数据 <br/>string viewState = Request.Form[&#34;__SmartViewState&#34;]; <br/>byte[] bytes = Convert.FromBase64String(viewState); <br/>//调用上面提供的静态方法CompressionHelper.DeCompressByte()来解压数据 <br/>bytes = CompressionHelper.DeCompressByte(bytes); <br/>LosFormatter formatter = new LosFormatter(); <br/>return formatter.Deserialize(Convert.ToBase64String(bytes)); <br/><br/>} <br/><br/>protected override void SavePageStateToPersistenceMedium(Object viewState) <br/>{ <br/>LosFormatter formatter = new LosFormatter(); <br/>StringWriter writer = new StringWriter(); <br/>formatter.Serialize(writer, viewState); <br/>string viewStateString = writer.ToString(); <br/>byte[] bytes = Convert.FromBase64String(viewStateString); <br/>//调用上面提供的静态方法CompressionHelper.CompressByte()来压缩数据 <br/>bytes = CompressionHelper.CompressByte(bytes); <br/><br/>//注册一个新的隐藏域__SmartViewState，你也可以自己定义 <br/>this.RegisterHiddenField(&#34;__SmartViewState&#34;, Convert.ToBase64String(bytes)); <br/>} <br/>#endregion <br/>　　 经过以上处理，web输出页面中的源代码就是型如： ]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=1074</link>
			<title><![CDATA[.net 3.5版本上的Socket开发]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Tue,17 Mar 2009 12:08:21 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=1074</guid>	
		<description><![CDATA[<table cellspacing="0" cellpadding="0" align="left" border="0" class="xfad">
    <tbody>
        <tr>
            <td>
            <script src="/JS/wz300.js" type="text/javascript"></script>
            </td>
        </tr>
    </tbody>
</table>
<p>在之前的文章中，我们讲了如何在.NET 2.0下面开发Socket项目。其中的异步Socket让我们得以很轻松的在.NET中开发高性能服务端应用。 <br /><br />但是，在实际应用中我们还是发现了一些问题的存在，如：我们在每一次操作的过程中都要创建一个IAsyncResult上下文对象，如果数据通讯很频繁的话，会导致大量的IAsyncResult对象被创建，大大的增加了垃圾回收器的工作量，从而降低了整个应用的效率。 <br /><br />在.NET 3.5中，这个麻烦已经被解决了，在3.5 版本中，Socket定义了一些新的方法。这些方法不要求每一次操作都创建一个新的上下文对象。 <br /><br />如，在2.0中我们采用下面的方式在Socket上启动一次接收操作。3.5中我们可以用新的方法完成一次接收操作。 <br /><br />Code <br />void ReceiveCallBack(IAsyncResult ar){} <br />IAsyncResult result=socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, ReceiveCallBack, info);//在这里有一个IAsyncResult对象被创建。 <br />在 <br /><br />Code <br />void OnReceiveCompleted(object sender,SocketAsyncEventArgs e){} <br />SocketAsyncEventArgs receive=new SocketAnyncEventArgs(); <br />receive.Completed+= OnReceiveCompleted; <br />receive.SetBuffer(buffer,0,buffer.Length); <br />socket.ReceiveAsync(receive); <br /><br /><br />在这里我们可以看出3.5 和 2.0 的一个明显区别，那就是不是使用IAsyncResult而是用SocketAsyncEventArgs作为上下文对象。应用程序创建并管理（并且可以重复使用）SocketAsyncEventArgs 对象。套接字操作的所有参数都由 SocketAsyncEventArgs 对象的属性和方法指定。完成状态也由 SocketAsyncEventArgs 对象的属性提供。最后，需要使用事件处理程序回调完成方法。 <br /><br />让我们来看看代码： <br /><br />首先我们创建一个用户类，用来存储和客户端有关的数据： <br /><br />Code <br />public class UserObject <br />{ <br />/**//// &lt;summary&gt; <br />/// 接收数据的缓冲区 <br />/// &lt;/summary&gt; <br />public byte[] ReceiveBuffer { get; private set; } <br />/**//// &lt;summary&gt; <br />/// 发送数据的缓冲区 <br />/// &lt;/summary&gt; <br />public byte[] SendBuffer { get; private set; } <br />/**//// &lt;summary&gt; <br />/// 客户端Socket对象 <br />/// &lt;/summary&gt; <br />public Socket Socket { get; private set; } <br />/**//// &lt;summary&gt; <br />/// 发送数据上下文对象 <br />/// &lt;/summary&gt; <br />public SocketAsyncEventArgs SendEventArgs { get; private set; } <br />/**//// &lt;summary&gt; <br />/// 接收数据上下文对象 <br />/// &lt;/summary&gt; <br />public SocketAsyncEventArgs ReceiveEventArgs { get; private set; } <br /><br />public UserObject(Socket socket) <br />{ <br />ReceiveBuffer = new byte[1024];//定义接收缓冲区 <br />SendBuffer = new byte[1024];//定义发送缓冲区 <br />this.Socket = socket; <br />SendEventArgs = new SocketAsyncEventArgs(); <br />SendEventArgs.UserToken = this; <br />ReceiveEventArgs = new SocketAsyncEventArgs(); <br />ReceiveEventArgs.UserToken = this; <br />ReceiveEventArgs.SetBuffer(ReceiveBuffer, 0, ReceiveBuffer.Length);//设置接收缓冲区 <br />SendEventArgs.SetBuffer(SendBuffer, 0, SendBuffer.Length);//设置发送缓冲区 <br />} <br />} <br />接下来我们开始接入客户端连接： <br /><br />Code <br />1socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); <br />2socket.Bind(localEP); <br />3socket.Listen(100); <br />4Console.WriteLine(&quot;Server is bind on {0}&quot;,socket.LocalEndPoint); <br />5acceptEventArgs = new SocketAsyncEventArgs();//创建接入Socket上下文对象 <br />6acceptEventArgs.Completed += acceptCompleted;//注册接入完成事件处理程序 <br />7socket.AcceptAsync(acceptEventArgs);//投递接入操作 <br />8Console.WriteLine(&quot;Server is started&quot;); <br />9 <br />10//接入事件处理程序 <br />11void acceptCompleted(object sender, SocketAsyncEventArgs e) <br />12{ <br />13 var client = new UserObject( e.AcceptSocket);//创建用户对象实例 <br />14 client.ReceiveEventArgs.Completed += Receives_Completed;//注册接收数据完成事件处理程序 <br />15 client.SendEventArgs.Completed += Send_Completed;//注册发送数据完成事件处理程序 <br />16 client.Socket.ReceiveAsync(client.ReceiveEventArgs);//投递接收数据操作 <br />17} <br />好了，我们开始接收数据： <br /><br />Code <br />1//接收数据完成事件处理程序 <br />2void Receives_Completed(object sender, SocketAsyncEventArgs e) <br />3{ <br />4 var client = e.UserToken as UserObject; <br />5 if (e.BytesTransferred == 0)//如果传输的数据量为0，则表示链接已经断开 <br />6 { <br />7 Console.WriteLine(&quot;Socket:{0} is closed&quot;,client.Socket.Handle); <br />8 client.Socket.Close(); <br />9 } <br />10 else <br />11 { <br />12 string message = Encoding.Unicode.GetString(e.Buffer, 0, e.BytesTransferred);//获取接收到的数据 <br />13 Console.WriteLine(&quot;Socket:{0} send message:{1}&quot;,client.Socket.Handle,message); <br />14 string sent=string.Format(&quot;{0} bytes has been received&quot;,e.BytesTransferred); <br />15 int length = Encoding.Unicode.GetBytes(sent,0,sent.Length,client.SendBuffer,0);//将数据写入发送缓冲区 <br />16 client.SendEventArgs.SetBuffer(0, length);//设置缓冲区中有效数据的偏移量和长度 <br />17 client.Socket.SendAsync(client.SendEventArgs);//投递发送数据操作 <br />18 client.Socket.ReceiveAsync(client.ReceiveEventArgs);//投递接收数据操作 <br />19 } <br />20} <br />21 <br />22//发送数据完成事件处理程序 <br />23void Send_Completed(object sender, SocketAsyncEventArgs e) </p>
<p>24{ <br />25 var client = e.UserToken as UserObject; <br />26 if (e.BytesTransferred==0)//如果传输的数据量为0，则表示链接已经断开 <br />27 { <br />28 Console.WriteLine(&quot;Socket:{0} is closed&quot;, client.Socket.Handle); <br />29 client.Socket.Close(); <br />30 } <br />31 else <br />32 { <br />33 Console.WriteLine(&quot;Sent {0} bytes data to socket:{1}&quot;,e.BytesTransferred, client.Socket.Handle); <br />34 } <br />35} </p>]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=1073</link>
			<title><![CDATA[C#正则表达式(RegEx)高级应用]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Tue,17 Mar 2009 12:07:24 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=1073</guid>	
		<description><![CDATA[<table cellspacing="0" cellpadding="0" align="left" border="0" class="xfad">
    <tbody>
        <tr>
            <td>
            <script src="/JS/wz300.js" type="text/javascript"></script>
            </td>
        </tr>
    </tbody>
</table>
对于复杂的、符合一定规则的字符串替换来说，正则表达式无疑是强悍和高效的选择 <br /><br />对于正则表达式的使用，我也写过几篇帖子了，具体可以见下面的地址 <br /><br />http://zu14.cn/tag/regex/ <br /><br />今天，说一下 .NET 里面 正则 使用的稍微高级一些的技巧：分组替换 ，下面我们举两个实例来说明这个问题： <br /><br />一段字符串，把其中出现的 Ax,Ay 形式的内容，替换为 Ax 的形式(也就是 ,和Ay 都不要了)，其中x 和y是数字，位长是 1～2，并且不会出现连排的形式 <br /><br />对于上面的需求，我们进行分析后，可以得出：上面的匹配规则，分为2组，(Ax) 一组，(,Ay) 一组 匹配后，直接返回第一组就OK了 <br /><br />对于.NET来说，分组替换的实现，有多种方式，我这里展示其中的2种，对于上面的例子，我使用 MatchEvaluator 方式 <br /><br />static string CustomReplace(System.Text.RegularExpressions.Match m) <br />{ <br />return m.Groups[1].Value; //直接返回分组1 <br />} <br /><br />string sourceString = &quot;.....&quot;; <br />string pattern = @&quot;(A\d{1,2})(,A\d{1,2})&quot;; <br />System.Text.RegularExpressions.MatchEvaluator myEvaluator = new System.Text.RegularExpressions.MatchEvaluator(CustomReplace); <br />System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase| System.Text.RegularExpressions.RegexOptions.Multiline); <br /><br />string resultString = reg.Replace(sourceString, myEvaluator); <br />一段HTML代码，是用来插入FLASH的，形式如： &lt;embed width=&rdquo;1000&rdquo; src=&rdquo;&hellip;&rdquo; &hellip;&gt;&lt;/embed&gt; <br /><br />需求是需要对这个FLASH的代码进行自定义，将 宽度 替换为自定义的值 <br /><br />对于这个例子，我们使用分组号 $# 的方式来实现，#代表数字，经过分析，可以得出，将上面的内容，分为3组 <br /><br />string sourceString = &quot;......&quot;; <br />string toWidth = &quot;300&quot;; //自定义的宽度 <br />string pattern = &quot;(&lt;embed .+? width\\s{0,}=\\s{0,}\&quot;{0,1})(\\d+)(\&quot;{0,1})&quot;; <br />System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline); <br />string resultString = reg.Replace(sourceString, &quot;${1}&quot; + toWidth + &quot;${3}&quot;); <br />为了区分分组编号和普通字符，可以用{}标注分组号]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=1072</link>
			<title><![CDATA[学习C#中数据库循环插入问题]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Tue,17 Mar 2009 12:06:41 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=1072</guid>	
		<description><![CDATA[由于迎新系统的原始数据是高校招生系统中的数据，里面的数据库是vfp格式的，我做的迎新系统使用sqlserver2000的，再加上招生系统中的数据大部分数据字段是没有用的，所以只能从招生系统中的数据库筛选出一部分的数据字段插入到sqlserver2000中，但有一个问题，学校招生数据最少也有几千条数据，要从vfp中读取 一次性插入到sql2000中去，这样执行那么多条插入时肯定要用到事务使得但插入出错时前面的插入无效，查了许多资料，终于找到解决的方法。 <br /><br /><br /><br />TransactionScope 事务 <br /><br />在通过 new 语句实例化 TransactionScope 时，事务管理器将确定要参与哪个事务。一经确定，此范围将始终参与该事务。 <br /><br />　　如果在事务范围中（即从初始化 TransactionScope 对象到调用其 Dispose方法之间）未发生异常，则允许该范围所参与的事务继续。如果事务范围中的确发生了异常，它所参与的事务将回滚。 <br /><br />当应用程序完成它要在一个事务中执行的所有工作以后，您应当只调用Complete方法一次，以通知事务管理器可以接受提交事务。未能调用此方法将中止该事务。 <br /><br />　　对 Dispose 方法的调用标志着该事务范围的结束。在调用此方法之后发生的异常不会影响该事务。 <br /><br />如果在范围中修改 Current 的值，则会在调用 Dispose 时引发异常。但是，在该范围结束时，先前的值将被还原。此外，如果在创建事务的事务范围内对 Current 调用 Dispose，则该事务将在相应范围末尾处中止。 <br /><br />即不需要為每個connection指定一个transaction。 <br /><br />实例 <br /><br />using (TransactionScope ts = new TransactionScope()) <br />{ <br />string connstr = @&quot;Data Source=.\SQLEXPRESS;AttachDbFilename=D:\ta.mdf;Integrated Security=True;User Instance=True&quot;; <br />using (SqlConnection conn = new SqlConnection(connstr)) <br />{ <br />conn.Open(); <br />try <br />{ <br />SqlCommand cmd = new SqlCommand(&quot;delete table1, conn); <br />cmd.ExecuteNonQuery(); <br />using (SqlConnection conn1 = new SqlConnection(connstr)) <br />{ <br />conn1.Open(); <br />SqlCommand cmd1 = new SqlCommand(&quot;insert into tableTXL(Name,Sex) values('ARC3','FeMale')&quot;, conn1); <br />cmd1.ExecuteNonQuery(); <br />SqlCommand cmd2 = new SqlCommand(&quot;insert into tableTXL(Name,Sex) values('ARC4','FeMale')&quot;, conn1); <br />cmd2.ExecuteNonQuery(); <br />ts.Complete(); <br />MessageBox.Show(&quot;Transaction completed!&quot;); <br />conn1.Close(); <br />} <br />} <br />catch (SqlException ex) <br />{ <br />MessageBox.Show(&quot;Transaction RollBack!&quot;+ex.Message); <br />} <br />conn.Close(); <br />} <br />]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=1026</link>
			<title><![CDATA[理解ASP.NET 2.0中的单点登录]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Tue,18 Nov 2008 10:28:14 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=1026</guid>	
		<description><![CDATA[<p align="left"><span><strong><span>Published:</span></strong><span> 16 Jan 2008</span></span></p>
<p align="left"><br /><span>摘要</span></p>
<p align="left"><br />目录</p>
<ul type="square"><u><span><span>
    <ul type="square">
        <li><u><span>简介</span></u> </li>
        <li><u><span>什么是</span></u><u><span>SSO</span></u><u><span>？它是怎样工作的？</span></u> </li>
        <li><u><span>系统条件</span></u> </li>
        <li><u><span>工作</span></u> </li>
        <li><u><span>下载</span></u> </li>
        <li><u><span>结论</span></u> </li>
    </ul>
    </span></span></u><strong><span>
    <li><span>简介</span> </li>
    </span></strong></ul>
    <p align="left"><span><span><span>通常在你要实现</span><span>ASP.NET web</span><span>应用程序的身份验证时，你需要为你的每一个应用程序创建一个登录页面。想象一下，如果你有两个或者更多的互相关联的</span><span>web</span><span>应用程序，你可能希望通过某种机制为你的所有带关联的应用程序实现仅出现一次登录页面。这样，一旦你登录了一次，你就可以浏览所有的关联程序，而不再需要额外的登录了。单点登录（</span><span>SSO</span><span>）就是这样的访问控制机制，它允许一个用户通过一次验证就可以访问所有软件系统资源。</span></span></span></p>
    <p align="left"><span><span><span>试想你在你的服务器上创建了两个或者更多的</span><span>web</span><span>站点。就像其他的</span><span>web</span><span>站点一样，你只是使用</span><span>ASP.NET</span><span>权限验证机制来验证你的用户。那么，你的这些站点可能需要一个或更多的登录页面。现在你正试图证明怎么样通过更改你的配置来实现跨程序登录。换句话说，我们只想给我们的程序配置一个登录页面，并且一旦用户通过了验证，他就可以浏览其他所有的站点，而不需要另外的登录。在这篇文章的附录中，你也可以看到如何加密你的配置文件</span><span>。</span></span></span></p>
    <p align="left"><strong><span>什么是单点登录？它是怎样工作的？</span></strong></p>
    <p align="left"><span><span>在许多的公司里，他们有一些以</span><span>web</span><span>站点或</span><span>web</span><span>应用程序为表现层的系统。自然，由于安全议题他们将需要通过基于</span><span>ASP.NET 2.0</span><span>，通过</span><span>Membership Provider </span><span>和</span><span> Role Provider </span><span>或者</span><span>定制实现权限验证和权限验证系统。不论怎样，所有的站点都会默认有一个确定用户的</span><span>ID</span><span>和密码在数据库中是否有效的</span><span>&rdquo;login.aspx&rdquo; web</span><span>窗体</span><span>.</span><span>当你只有一个站点或者这些站点都是独立运行时，这样做是没有问题的。但是当你有两个或多个站点，而且站点间是关联在一起或链接在一起的，你没准就会问：为什么每个应用程序你都必须登录一次？为什么你不可以只有一个</span><span>&rdquo;login.aspx&rdquo;</span><span>来实现验证，并让所有不关联程序真正统一起来。幸运的是，在</span><span>ASP.NET 2.0</span><span>中你可以通过同样的配置来实现跨应用程序访问，不论是你的新的站点还是已经存在的站点。</span></span></p>
    <p align="left"><span><span>在</span><span>ASP.NET</span><span>配置文件</span><span>(web.config)</span><span>中有一个配置节（在</span><span>&lt;system.web</span><span>中）命名为</span><span>&lt;machineKey&gt;</span><span>，负责加密和解密窗体（这些窗体可以读窗体权限验证</span><span>cookies</span><span>）权限认证的</span><span>cookie</span><span>数据和</span><span>view-state</span><span>数据，也负责校验进程外（</span><span>out-of-process</span><span>）</span><span>session </span><span>状态标识。所以当用户一旦被验证通过并且有一个</span><span>cookie</span><span>保存到了本地计算机，其他拥有同样</span><span>&lt;machineKey&gt;</span><span>配置的应用程序也可以识别此</span><span>cookie</span><span>为有效的权限票据。所以在其他拥有同样</span><span>&lt;machineKey&gt;</span><span>配置的应用程序中就不再需要第二次登陆了。</span></span></p>
    <p align="left"><span><span>由于</span><span>&lt;machineKey&gt;</span><span>信息是敏感的，你需要加密配置文件中的此节信息。为了实现这个目标，我将使用</span><span>ConfigurationManager</span><span>类和他的方法。这里还有一个类</span><span>SectionInformation</span><span>，包含有配置中单个配置节的元数据。此类中有个方法</span><span>ProtectSection()</span><span>，用来解密你的配置文件的配置节。</span></span></p>
    <p align="left"><strong><span>系统条件</span></strong></p>
    <p align="left"><span>&middot;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>A web server running on Windows 2000 or later</span></p>
    <p align="left"><span>&middot;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>.NET Framework 2.0</span></p>
    <p align="left"><span>&middot;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Visual Studio 2005</span></p>
    <p align="left"><span>&middot;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>Microsoft SQL Server 2005 Express Edition</span></p>
    <p align="left"><span>现在让我们来看看在我们的项目中发生了什么。我有一个站点</span><span>(</span><strong><span>Aspalliance1</span></strong><span>)</span><span>站点中包含一个登录页面</span><span>&rdquo;Login.aspx&rdquo;.</span><span>用户可以通过此页来进行权限验证。在这个站点里还有一个页面叫做</span><span>&rdquo;Default.aspx&rdquo;,</span><span>它有一个</span><span>header</span><span>和一些文本另外还有一个到</span><strong><span>Aspalliance2</span></strong><span>站点的链接。你将会看到一旦这个用户登录了，他可以导航到其他站点而不需要第二次登陆。这里还有一个安置有两个加密和解密的按钮的页面</span><span>&rdquo;Encryption.aspx&rdquo;</span><span>，用来加密和解密配置文件。</span></p>
    <p align="left"><span>就像我之前所说的那样，你可以通过在你的</span><span>web</span><span>配置文件中一点点小小的配置实现跨应用程序访问。在</span><span>web.config</span><span>文件中，有一个名为</span><span>&lt;system.web&gt;</span><span>的配置节。我们将对</span><span>&lt;system.web&gt;</span><span>做相同的配置，只需要将配置节</span><span>&lt;machineKey&gt;</span><span>和它的值放到</span><span>&lt;system.web&gt;</span><span>配置节中。</span><span>&lt;machineKey&gt;</span><span>有一些属性，我将要去配置他们。首先，就是指定用来验证的加密类型。</span><span>validationKey </span><span>定义了用来验证解密数据的</span><span>key</span><span>，</span><span>decryptionKey</span><span>定义了用来加密和解密的数据的</span><span>key</span><span>，抑或是</span><span>key</span><span>生成的过程。</span></p>
    <p align="left"><strong><u><span>清单</span></u></strong><strong><u><span> 1: </span></u></strong><strong><u><span>配置</span></u></strong><strong><u><span>web.config</span></u></strong><strong><u><span>中的</span></u></strong><strong><u><span>machineKey</span></u></strong></p>
    <p align="left"><span>&lt;</span><span>machineKey</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p>
    <p align="left"><span>validationKey</span><span>=&quot;282487E295028E59B8F411ACB689CCD6F39DDD21E6055A3EE480424315994760ADF</span></p>
    <p align="left"><span>21B580D8587DB675FA02F79167413044E25309CCCDB647174D5B3D0DD9141&quot;</span></p>
    <p align="left"><span>decryptionKey</span><span>=&quot;8B6697227CBCA902B1A0925D40FAA00B353F2DF4359D2099&quot;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
    <p align="left"><span>validation</span><span>=&quot;SHA1&quot;/&gt;</span></p>
    <p align="left"><span>这个样例代码并没有被加密，并且它不会被发布到服务器上。因为处于安全考虑，发布到服务器的</span><span>&lt;machineKey&gt;</span><span>的加密是非常重要的。你可以在清单</span><span>2</span><span>中看到加密后的</span><span>&lt;machineKey&gt;</span><span>。</span></p>
    <p align="left"><strong><u><span>清单</span></u></strong><strong><u><span> 2: web.config </span></u></strong><strong><u><span>中加密后的</span></u></strong><strong><u><span>machineKey </span></u></strong></p>
    <p align="left"><span>&lt;</span><span>machineKey</span><span>configProtectionProvider</span><span>=&quot;RsaProtectedConfigurationProvider&quot;&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>EncryptedData</span><span>Type</span><span>=&quot;http://www.w3.org/2001/04/xmlenc#Element&quot;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>xmlns</span><span>=&quot;http://www.w3.org/2001/04/xmlenc#&quot;&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>EncryptionMethod</span><span>Algorithm</span><span>=&quot;http://www.w3.org/2001/04/xmlenc#tripledes-cbc&quot;</span>&nbsp;<span>/&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>KeyInfo</span><span>xmlns</span><span>=&quot;http://www.w3.org/2000/09/xmldsig#&quot;&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>EncryptedKey</span><span>xmlns</span><span>=&quot;http://www.w3.org/2001/04/xmlenc#&quot;&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>EncryptionMethod</span><span>Algorithm</span><span>=&quot;http://www.w3.org/2001/04/xmlenc#rsa-1_5&quot;</span>&nbsp;<span>/&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>KeyInfo</span><span>xmlns</span><span>=&quot;http://www.w3.org/2000/09/xmldsig#&quot;&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>KeyName</span><span>&gt;</span><span>Rsa&nbsp;Key</span><span>&lt;/</span><span>KeyName</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;/</span><span>KeyInfo</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>CipherData</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>CipherValue</span><span>&gt;</span></p>
    <p align="left"><span>lm3mfPX/94Zm3HgdbsmKiIxbrWM14t3/ugxs40BFOAHbIaCtwQ3gVQusFtOFVUoNVny01kgBCeh10rVEId</span></p>
    <p align="left"><span>djNZ/8luBNoCbHm8OLjgPLHVrT+G0c/LRpESJk2ni/Jy2sWKXlgejgSQ1W5NE53GZtG3s9hu+nk4OWxntS</span></p>
    <p align="left"><span>6z3v7AM=</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;/</span><span>CipherValue</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;/</span><span>CipherData</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;/</span><span>EncryptedKey</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;/</span><span>KeyInfo</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>CipherData</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;</span><span>CipherValue</span><span>&gt;</span></p>
    <p align="left"><span>BCEGUV/dh1Imbcm5vn0Kn8NrD+EX+KemenR7x+VekwT1ZO6y5+jRyF4RDWMJCfJ1jHC36+MAfCdHuXN0rP</span></p>
    <p align="left"><span>B6hu5YUtX9VA5q5N0NGrs9AIpG+0ihuuS3HDzQe3P6nlI30m1h0pmL1yJBovY0i6fbCA6++GT2MdwCLERk</span></p>
    <p align="left"><span>+PVWmoq7p1q97n5pNzNqhVKCX45lhS5ySVS+MjJXVeTrcatftpvaUcjLsNcL2kMerzf5w/SU3AbLEuY04w</span></p>
    <p align="left"><span>dgYWX5tWzxqeUcghdlWLD0tQi8qyyfVfzXPYozR5sspWHdgqmAycrACHN2dcONWPjT4BanRWb1ouKuP8K+</span></p>
    <p align="left"><span>0CEFE/Hj2ChpYw==</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;/</span><span>CipherValue</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;/</span><span>CipherData</span><span>&gt;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&lt;/</span><span>EncryptedData</span><span>&gt;</span></p>
    <p align="left"><span>&lt;/</span><span>machineKey</span><span>&gt;</span></p>
    <p align="left"><span>你可以通过</span><span>Configuration</span><span>、</span><span>SectionInformation</span><span>两个类来加密你的配置文件。为了加密和解密你的</span><span>&lt;machineKey&gt;</span><span>让我们来写一些代码吧。</span><span>SectionInformation</span><span>类有一个方法</span><span>ProtectSection()</span><span>，可以得到一个描绘</span><span>Protection Provider</span><span>的字符串比如</span><span>&quot;RSAProctedConfigurationProvider&quot;</span><span>，并且加密这个配置节。这里还有一个</span><span>Boolean</span><span>类型的属性</span><span>ForceSave</span><span>，当需要配置类的</span><span>save</span><span>方法保存配置文件时需要将它设置为</span><span>true</span><span>。这里有</span><span>&quot;Encryption.aspx&quot;</span><span>页面的代码，页面中包含有两个按钮来加密和解密配置文件。</span></p>
    <p align="left"><strong><u><span>清单</span></u></strong><strong><u><span> 3:web</span></u></strong><strong><u><span>配置文件的加密代码</span></u></strong></p>
    <p align="left"><span>protected</span>&nbsp;<span>void</span><span>&nbsp;btnEncrypt_Click(</span><span>object</span><span>&nbsp;sender, EventArgs&nbsp;e)</span></p>
    <p align="left"><span>{</span></p>
    <p align="left"><span>&nbsp;&nbsp;</span><span>try</span></p>
    <p align="left"><span>&nbsp;&nbsp;{</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;Configuration&nbsp;config&nbsp;</span><span>=</span><span> WebConfigurationManager.OpenWebConfiguration(</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&quot;/Aspalliance1&nbsp;&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;ConfigurationSection&nbsp;machineKeySection&nbsp;</span><span>=</span><span> config.GetSection(</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&quot;system.web/machineKey&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp; machineKeySection.SectionInformation.ProtectSection(</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&quot;RSAProtectedConfigurationProvider&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp; machineKeySection.SectionInformation.ForceSave&nbsp;</span><span>=</span>&nbsp;<span>true</span><span>;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;config.Save();</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;Response.Write(</span><span>&quot;&lt;h2 style='color:red'&gt;Encryption&nbsp;Succeed&lt;/h2&gt;&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;}</span></p>
    <p align="left"><span>&nbsp;&nbsp;</span><span>catch</span><span>&nbsp;(Exception&nbsp;ex)</span></p>
    <p align="left"><span>&nbsp;&nbsp;{</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;Response.Write(</span><span>&quot;&lt;h2&nbsp;style='color:red'&gt;Error while&nbsp;encrypting&lt;/h2&gt;&lt;br/&gt;&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;Response.Write(ex.Message);</span></p>
    <p align="left"><span>&nbsp;&nbsp;}</span></p>
    <p align="left"><span>}</span></p>
    <p align="left"><strong><u><span>清单</span></u></strong><strong><u><span> 4: web</span></u></strong><strong><u><span>配置文件的解密代码</span></u></strong></p>
    <p align="left"><span>protected</span>&nbsp;<span>void</span><span>&nbsp;btnDecrypt_Click(</span><span>object</span><span>&nbsp;sender, EventArgs&nbsp;e)</span></p>
    <p align="left"><span>{</span></p>
    <p align="left"><span>&nbsp;&nbsp;</span><span>try</span></p>
    <p align="left"><span>&nbsp;&nbsp;{</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;Configuration&nbsp;config&nbsp;</span><span>=</span><span>&nbsp;WebConfigurationManager.OpenWebConfiguration(</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&quot;/Aspalliance1&nbsp;&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;ConfigurationSection&nbsp;machineKeySection&nbsp;</span><span>=</span><span> config.GetSection(</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&quot;system.web/machineKey&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp; machineKeySection.SectionInformation.UnprotectSection();</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;machineKeySection.SectionInformation.ForceSave </span><span>=</span>&nbsp;<span>true</span><span>;</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;config.Save();</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;Response.Write(</span><span>&quot;&lt;h2 style='color:red'&gt;Decryption&nbsp;Succeed&lt;/h2&gt;&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;}</span></p>
    <p align="left"><span>&nbsp;&nbsp;</span><span>catch</span><span>&nbsp;(Exception&nbsp;ex)</span></p>
    <p align="left"><span>&nbsp;&nbsp;{</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;Response.Write(</span><span>&quot;&lt;h2 style='color:red'&gt;Error&nbsp;while&nbsp;decrypting&lt;/h2&gt;&lt;br/&gt;&quot;</span><span>);</span></p>
    <p align="left"><span>&nbsp;&nbsp;&nbsp;&nbsp;Response.Write(ex.Message);</span></p>
    <p align="left"><span>&nbsp;&nbsp;}</span></p>
    <p align="left"><span>}</span></p>
    <p align="left"><span>现在你必须在这个站点中设置相同的配置。首先你需要更改你的窗体验证部分的</span><span>loginUrl</span><span>，这个窗体将被用来将匿名用户跳转到</span><span>&rdquo;Login.aspx&rdquo;</span><span>页。只是，现在它将把用户重定向到</span><span>Aspalliance1</span><span>站点中的</span><span>&rdquo;Login.aspx&rdquo;</span><span>页。</span></p>
    <p align="left"><strong><u><span>清单</span></u></strong><strong><u><span> 5: </span></u></strong><strong><u><span>设置</span></u></strong><strong><u><span> web.config</span></u></strong><strong><u><span>中的验证节</span></u></strong></p>
    <p align="left"><span>&lt;</span><span>authentication</span>&nbsp;<span>mode</span><span>=&quot;Forms&quot;&gt;</span></p>
    <p align="left"><span>&lt;</span><span>forms</span>&nbsp;<span>loginUrl</span><span>=&quot;http://localhost/Aspalliance1/login.aspx&quot;</span><span>name</span><span>=&quot;.ASPXAUTH&quot;/&gt;</span></p>
    <p align="left"><span>&lt;/</span><span>authentication</span><span>&gt;</span></p>
    <p align="left"><span>如果你想实现跨程序登录你的好多站点时，最重要的一点就是你必须把你的两个或更多的站点配置为相同的</span><span>&lt;machineKey&gt;</span><span>。所以我只需要拷贝并粘贴</span><span>Aspalliance1 </span><span>站点中的</span><span>&lt;machineKey&gt;</span><span>配置节到</span><span>Aspalliance2</span><span>站点。现在都已经准备好了，你可以测试你的站点了。</span></p>
    <p align="left"><strong><u><span>清单</span></u></strong><strong><u><span> 6: </span></u></strong><strong><u><span>设置</span></u></strong><strong><u><span>web.config </span></u></strong><strong><u><span>中的</span></u></strong><strong><u><span> machineKey </span></u></strong></p>
    <p align="left"><span>&lt;</span><span>machineKey</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></p>
    <p align="left"><span>validationKey</span><span>=&quot;282487E295028E59B8F411ACB689CCD6F39DDD21E6055A3EE480424315994760ADF</span></p>
    <p align="left"><span>21B580D8587DB675FA02F79167413044E25309CCCDB647174D5B3D0DD9141&quot;</span></p>
    <p align="left"><span>decryptionKey</span><span>=&quot;8B6697227CBCA902B1A0925D40FAA00B353F2DF4359D2099&quot;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
    <p align="left"><span>validation</span><span>=&quot;SHA1&quot;/&gt;</span></p>
    <span>
    <p align="left"><span>测试这个站点的话，可以使用用户名：</span><strong><span>Admin</span></strong><span>密码：</span><strong><span>123456&amp;</span></strong><span>来登录。</span></p>
    <p align="left"><span>这个下载附件中有一个</span><span>VS 2005</span><span>项目，其中包含有两个站点：</span><span>aspalliance1 and aspalliance2.</span></p>
    <p align="left"><span>要安装这个实例的话，你需要创建两个</span><span>IIS</span><span>虚拟目录命名为：</span><span>aspalliance1 </span><span>和</span><span> aspalliance2</span><span>，并将地址指向相应的文件夹。你也可以通过</span><span>Visual Studio 2005</span><span>打开站点。</span></p>
    <p align="left"><span>当用户要交叉访问你的多个站点时，他必须重复登陆实在是麻烦。所以，如果只让用户登录一次，那会是非常棒的。实现这些，你只需要给你的</span><span>&quot;web.config&quot; </span><span>文件增加具有相同值的</span><span>&lt;machineKey&gt;</span><span>配置。并且处于安全考虑，我建议你加密这个配置节。这个加密方法在</span><span>SectionInformation</span><span>类中通过</span><span>ProtectSection()</span><span>方法被重写了。</span></p>
    <span><span>
    <p align="left"><br /><span><span><span>在这篇文章中，</span><span>Masoud</span><span>讨论了应用</span><span>ASP.NET</span><span>中统一身份验证模型进行跨应用程序验证的问题，包括：</span><span>Membership Providers, web.config</span><span>配置</span><span>,</span><span>配置文件的加密解密等。在文章的最后，作者提供了通过</span><span>ASP.NET login controls</span><span>来验证的程序。</span></span></span></p>
    </span>
    <p align="left"><span><span><span>下载源码:</span></span></span></p>
    <p align="left"><span><span><span><a href="http://authors.aspalliance.com/MTabatabaei/sso.zip">http://authors.aspalliance.com/MTabatabaei/sso.zip</a></span></span></span></p>
    </span></span>]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=993</link>
			<title><![CDATA[C# 编程规范 【转】]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Mon,25 Aug 2008 16:13:51 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=993</guid>	
		<description><![CDATA[　一、命名 <br/>　　1.用pascal规则来命名方法和类型。<br/><br/>　　public class TextBox<br/><br/>　　{<br/><br/>　　public void DataBind（）<br/><br/>　　{<br/><br/>　　}<br/><br/>　　}<br/><br/>　　2.用camel规则来命名局部变量和方法的参数。<br/><br/>　　string userName；<br/><br/>　　public AddUser（string userId， byte[] password）；<br/><br/>　　3.所有的成员变量前加前缀 _<br/><br/>　　public class Database<br/><br/>　　{<br/><br/>　　private string _connectionString；<br/><br/>　　}<br/><br/>　　4.接口的名称加前缀 I.<br/><br/>　　interface ICompare<br/><br/>　　{<br/><br/>　　int compare（）；<br/><br/>　　}<br/><br/>　　5.自定义的属性以Attribute结尾<br/><br/>　　public class AuthorAttribute ： Attribute<br/><br/>　　{<br/><br/>　　}<br/><br/>　　6.自定义的异常以Exception结尾<br/><br/>　　public class AppException ： Exception<br/><br/>　　{<br/><br/>　　}<br/><br/>　　7.方法的命名。一般将其命名为动宾短语。<br/><br/>　　ShowDialog（）<br/><br/>　　Cr&#101;ateFile（）<br/><br/>　　GetPath（）<br/><br/>　　8.代码的缩进。要用Tab，而不要用space.<br/><br/>　　9.局部变量的名称要有意义。不要用x，y，z等等（除用于For循环变量中可使用i，j，k，l，m，n）。<br/><br/>　　string userName<br/><br/>　　10.所有的成员变量声明在类的顶端，用一个换行把它和方法分开。<br/><br/>　　11.用有意义的名字命名namespace，如：产品名、公司名。<br/><br/>　　12.建议局部变量在最接近使用它时再声明。<br/><br/>　　13.使用某个控件的值时，尽量命名局部变量。<br/><br/>　　14.把引用的系统的namespace和自定义或第三方的用一个换行把它们分开。<br/><br/>　　15.文件名要能反应类的内容，最好是和类同名，一个文件中一个类或一组关连类。<br/><br/>　　16.目录结构中要反应出namespace的层次。<br/><br/>　　17.大括号&#34;{&#34;要新起一行。<br/><br/>　　public class AuthorAttribute ： Attribute<br/><br/>　　{<br/><br/>　　}<br/><br/>二、编码习惯。<br/><br/>　　1.用C#预定义的类名，而不要用别名。<br/><br/>　　string userName；&nbsp;&nbsp; 而不是 System.String userName；<br/><br/>　　int number；&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;而不是 System.Int32；<br/><br/>　　2.一行不要超过80个字符。<br/><br/>　　3.尽量不要手工更改机器生成的代码，若必须更改，一定要改成和机器生成的代码风格一样。<br/><br/>　　4.关键的语句（包括声明关键的变量）必须要写注释。<br/><br/>　　5.文字常量和数字常量不要硬编码，应该用常量类或枚举代替。<br/><br/>　　6.不准使用goto系列语句。<br/><br/>　　7.不要声明public和protected的成员变量，应用property.<br/><br/>　　8.不要声明public的event，应用事件访问器。<br/><br/>　　public class Source<br/><br/>　　{<br/><br/>　　private EventHandler m_NumberChangeEvent；<br/><br/>　　public event EventHandler NumberChangeEvent<br/><br/>　　{<br/><br/>　　add<br/><br/>　　{<br/><br/>　　m_NumberChangeEvent += value；<br/><br/>　　}<br/><br/>　　remove<br/><br/>　　{<br/><br/>　　m_NumberChangeEvent -= value；<br/><br/>　　}<br/><br/>　　}<br/><br/>　　}<br/><br/>　　9.类型转换的使用规则。<br/><br/>　　Animal animal = new Dog（）；<br/><br/>　　Dog dog = animal as Dog；<br/><br/>　　if （dog ！= null）<br/><br/>　　{<br/><br/>　　}<br/><br/>　　10.生成和构建一个长的字符串时，一定要使用StringBuilder，而不用string.<br/><br/>　　11.始终使用&#34;{ }&#34;包含if下的语句，即使只有一条语句。<br/><br/>　　12.switch语句一定要有default来处理意外情况。<br/><br/>　　13.尽量少使用三目运算符 ？ ： ，而要使用if语句。<br/><br/>　　14.尽量不用使用this引用，除非是要调用类中的另一个Constructor.<br/><br/>　　public class Person<br/><br/>　　{<br/><br/>　　public Person（string name）<br/><br/>　　{<br/><br/>　　}<br/><br/>　　public Person（） ： this（&#34;Jim&#34;）<br/><br/>　　{<br/><br/>　　}<br/><br/>　　}<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=960</link>
			<title><![CDATA[ASP.NET缓存：方法分析和实践示例]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Mon,21 Jul 2008 12:27:23 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=960</guid>	
		<description><![CDATA[尽早缓存；经常缓存 您应该在应用程序的每一层都实现缓存。向数据层、业务逻辑层、UI 或输出层添加缓存支持。内存现在非常便宜 — 因此，通过以智能的方式在整个应用程序中实现缓存，可以获得很大的性能提高。 缓存可以掩盖许多过失 缓存是一种无需大量时间和分析就可以获得“足够良好的”性能的方法。这里再次强调，内存现在非常便宜，因此，如果您能通过将输出缓存 30 秒，而不是花上一整天甚至一周的时间尝试优化代码或数据库就可以获得所需的性能，您肯定会选择缓存解决方案（假设可以接受 30 秒的旧数据）。缓存正是那些利用 20% 付出获得 80% 回报的特性之一，因此，要提高性能，应该首先想到缓存。不过，如果设计很糟糕，最终却有可能带来不良的后果，因此，您当然也应该尽量正确地设计应用程序。但如果您只是需要立即获得足够高的性能，缓存就是您的最佳选择，您可以在以后有时间的时候再尽快重新设计应用程序。 页面级输出缓存 作为最简单的缓存形式，输出缓存只是在内存中保留为响应请求而发送的 HTML 的副本。其后再有请求时将提供缓存的输出，直到缓存到期，这样，性能有可能得到很大的提高（取决于需要多少开销来创建原始页面输出 - 发送缓存的输出总是很快，并且比较稳定）。 实现 要实现页面输出缓存，只要将一条 OutputCache 指令添加到页面即可。 <br/><br/>＜%@ OutputCache Duration=&#34;60&#34; VaryByParam=&#34;*&#34; %＞<br/><br/>如同其他页面指令一样，该指令应该出现在 ASPX 页面的顶部，即在任何输出之前。它支持五个属性（或参数），其中两个是必需的。　 Duration 必需属性。页面应该被缓存的时间，以秒为单位。必须是正整数。　 Location 指定应该对输出进行缓存的位置。如果要指定该参数，则必须是下列选项之一：Any、Client、Downstream、None、Server 或 ServerAndClient。　 VaryByParam 必需属性。Request 中变量的名称，这些变量名应该产生单独的缓存条目。&#34;none&#34; 表示没有变动。&#34;*&#34; 可用于为每个不同的变量数组创建新的缓存条目。变量之间用 &#34;;&#34; 进行分隔。 VaryByHeader 基于指定的标头中的变动改变缓存条目。<br/><br/>VaryByCustom 允许在 global.asax 中指定自定义变动（例如，&#34;Browser&#34;）。 利用必需的 Duration 和 VaryByParam 选项的组合可以处理大多数情况。例如，如果您的产品目录允许用户基于 categoryID 和页变量查看目录页，您可以用参数值为 &#34;categoryID;page&#34; 的 VaryByParam 将产品目录缓存一段时间（如果产品不是随时都在改变，一小时还是可以接受的，因此，持续时间是 3600 秒）。这将为每个种类的每个目录页创建单独的缓存条目。每个条目从其第一个请求算起将维持一个小时。　 VaryByHeader 和 VaryByCustom 主要用于根据访问页面的客户端对页面的外观或内容进行自定义。同一个 URL 可能需要同时为浏览器和移动电话客户端呈现输出，因此，需要针对不同的客户端缓存不同的内容版本。或者，页面有可能已经针对 IE 进行了优化，但需要能针对 Netscape 或 Opera 完全降低优化（而不仅仅是破坏页面）。后一个例子非常普遍，我们将提供一个说明如何实现此目标的示例：　 示例：VaryByCustom 用于支持浏览器自定义 为了使每个浏览器都具有单独的缓存条目，VaryByCustom 的值可以设置为 &#34;browser&#34;。此功能已经内置在缓存模块中，并且将针对每个浏览器名称和主要版本插入单独的页面缓存版本。<br/><br/>＜%@ OutputCache Duration=&#34;60&#34; VaryByParam=&#34;None&#34; VaryByCustom=&#34;browser&#34; %＞<br/><br/>片段缓存，用户控件输出缓存 缓存整个页面通常并不可行，因为页面的某些部分是针对用户定制的。不过，页面的其他部分是整个应用程序共有的。这些部分最适合使用片段缓存和用户控件进行缓存。菜单和其他布局元素，尤其是那些从数据源动态生成的元素，也应该用这种方法进行缓存。如果需要，可以将缓存的控件配置为基于对其控件（或其他属性）的更改或由页面级输出缓存支持的任何其他变动进行改变。使用同一组控件的几百个页面还可以共享那些控件的缓存条目，而不是为每个页面保留单独的缓存版本。　 实现 片段缓存使用的语法与页面级输出缓存一样，但其应用于用户控件（.ascx 文件）而不是 Web 窗体（.aspx 文件）。除了 Location 属性，对于 OutputCache 在 Web 窗体上支持的所有属性，用户控件也同样支持。用户控件还支持名为 VaryByControl 的 OutputCache 属性，该属性将根据用户控件（通常是页面上的控件，例如，Dro&#112;DownList）的成员的值改变该控件的缓存。如果指定了 VaryByControl，可以省略 VaryByParam。最后，在默认情况下，对每个页面上的每个用户控件都单独进行缓存。不过，如果一个用户控件不随应用程序中的页面改变，并且在所有页面都使用相同的名称，则可以应用 Shared=&#34;true&#34; 参数，该参数将使用户控件的缓存版本供所有引用该控件的页面使用。 示例<br/><br/>＜%@ OutputCache Duration=&#34;60&#34; VaryByParam=&#34;*&#34; %＞ 该示例将缓存用户控件 60 秒，并且将针对查询字符串的每个变动、针对此控件所在的每个页面创建单独的缓存条目。<br/><br/>＜%@ OutputCache Duration=&#34;60&#34; VaryByParam=&#34;none&#34; VaryByControl=&#34;CategoryDro&#112;DownList&#34; %＞<br/><br/>该示例将缓存用户控件 60 秒，并且将针对 CategoryDro&#112;DownList 控件的每个不同的值、针对此控件所在的每个页面创建单独的缓存条目。<br/><br/>＜%@ OutputCache Duration=&#34;60&#34; VaryByParam=&#34;none&#34; VaryByCustom=&#34;browser&#34; Shared=&#34;true %＞<br/><br/>最后，该示例将缓存用户控件 60 秒，并且将针对每个浏览器名称和主要版本创建一个缓存条目。然后，每个浏览器的缓存条目将由引用此用户控件的所有页面共享（只要所有页面都用相同的 ID 引用该控件即可）。 页面级和用户控件级输出缓存的确是一种可以迅速而简便地提高站点性能的方法，但是在 ASP.NET 中，缓存的真正灵活性和强大功能是通过 Cache 对象提供的。使用 Cache 对象，您可以存储任何可序列化的数据对象，基于一个或多个依赖项的组合来控制缓存条目到期的方式。这些依赖项可以包括自从项被缓存后经过的时间、自从项上次被访问后经过的时间、对文件和/或文件夹的更改以及对其他缓存项的更改，在略作处理后还可以包括对数据库中特定表的更改。]]></description>
		</item>
		
			<item>
			<link>http://www.friend365.cn/default.asp?id=941</link>
			<title><![CDATA[近期的几个ASP.NET开发经验总结和收集]]></title>
			<author>friend365@163.com(51itcn)</author>
			<category><![CDATA[.NET开发]]></category>
			<pubDate>Fri,20 Jun 2008 11:46:55 +0800</pubDate>
			<guid>http://www.friend365.cn/default.asp?id=941</guid>	
		<description><![CDATA[一：页面中Page_Load事件　和 Page.IsPostBack执行两次的原因.<br/>原因一：<br/>当&lt;%@Page....中没有AutoEventWireup定义时会导致Page_Load执行两次，如果有定义，且值为true时，在IsPostBack中动态绑定控件等情况也会导致页面Load事件发生两次..因此，个人推荐不要忽视AutoEventWireup,且建议设置其值为 false;<br/>原因二：<br/>当页面中有&lt;img src=&#34;&#34;&gt;时，也可能会导致Page_Load执行两次，解决方法：我也唔知.<br/><br/>二：OnInit与OnLoad<br/>个人理解：如果页面禁用了视图或者逻辑过程中没有用到视图或者没有必要回发数据的话，可以直接重写OnLoad方法，而不用再写OnInit方法，因为OnInit()之后还有进行一些视图方法的操作及回发数据的处理.因此直接OnLoad效率会高一些.<br/><br/>三：远程服务器返回500错误<br/>过程中需要从远程服务器下载文件到本地.可一直报远程服务器返回５００错误.检查来检查去，结果错误发生在本地：<br/>原因：页面以ANSI编码保存，而本地完全路径中有中文字符，导致路径不能被程序有效识别.<br/>解决方法：将页面编码更换成utf-8即可.VS系列中可通过高级保存选项更改．<br/><br/>四：Response.End,Response.Redirect等导致＂正在中止线程＂的问题<br/>如果是Response.End(),可用HttpContext.Current.ApplicationInstance.CompleteRequest()来代替（据个人测试，貌似使用这句后，后边不能再有程序执行，否则仍然会继续执行下去？）<br/>对于Response.Redirect()可用其重载方法：Response.Redirect(string,bool)<br/>当然，Server.Execute(),Server.Transfer()情况也类似.<br/><br/>附上ＡＳＰ.ＮＥＴ页面的生存周期（看明白了就知道为何有时只需要OnLoad,而不需要OnInit了）<br/>＿＿＿＿<br/>一：初始化Init:初始化对象－－Init事件(OnInit方法）<br/>二：加载视图状态：LoadViewState方法<br/>三：处理回发数据：LoadPostData方法－－－实际上这一步只是加载，并没有做其它的处理．<br/>－－－实现该方法的控件要继承自IPostBackDataHandler接口,该接口有LoadPostData和RaisePostBackDataChangedEvent两个方法<br/>四：加载Load:---Load事件（OnLoad方法）---该过程中所有对象都已经被实例化了..<br/>五：发送回发更改通知：RaisePostBackDataChangedEvent方法<br/>六：处理回发事件：IPostBackEventHandler接口的RaisePostBackEvent方法.<br/>七：预呈现：OnPreRender方法(PreRender事件）<br/>八：保存视图状态：SaveViewState方法<br/>九：呈现：Render方法（－－不再有对应事件）<br/>十：处置，回收资源:Dispose方法<br/>十一：卸载：UnLoad事件（OnUnLoad方法）..<br/>－－－－－－－－－Page是从Control继承的，因此它也是一种特殊的控件！]]></description>
		</item>
		
</channel>
</rss>