﻿<?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>博客园-笨笨的熊窝</title><link>http://www.cnblogs.com/benbenkoala/</link><description>度尽劫波兄弟在，相逢一笑泯恩仇</description><language>zh-cn</language><lastBuildDate>Mon, 06 Oct 2008 22:08:05 GMT</lastBuildDate><pubDate>Mon, 06 Oct 2008 22:08:05 GMT</pubDate><ttl>60</ttl><item><title>从一个巨简陋的破解程序想到的</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/09/27/1300104.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Sat, 27 Sep 2008 03:26:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/09/27/1300104.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1300104.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/09/27/1300104.html#Feedback</comments><slash:comments>32</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1300104.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1300104.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 前几天整理资料，发现了一段小程序，是用来破解某软件用户密码的。回想一下，感慨很深。 <br />
&nbsp;&nbsp;&nbsp; 先说一下计算原理。此软件允许业务主管控制主管部门和下属子公司的用户对软件的的使用权（添加、删除用户，修改密码，赋予用户各种操作权限，但无权访问用户数据）。如果知道了此软件的某一业务主管（非系统管理员，只是业务上具有高权限的用户）的密码，那么就可以查询该主管所管理的部门及所有下级子公司的用户名和加密后的密码内容。密码的加密并没有使用通用的MD5算法进行hash加密，而是使用了简单的字母替换方法。这样通过后面的小程序，根据加密后的密文就能迅速计算出密码明文。这样，破解者能轻而易举地得到此业务主管下辖的所有业务数据（通常以市为一个基本单位）。而业务主管如果知道了这种方法，则能查询下属用户的所有保密数据，这在制度上是绝对不允许的。<br />
&nbsp;&nbsp;&nbsp; 当然，这套系统并没有在Internet上，而只是在专用网上运行，所以很难从外部入侵。当然，业务主管安全意识较差，只是把密码设设成了简单的几位数字，使破解者得到了最破解密码的先决条件，如果密码设得复杂一些，那么就很难破解了。当然，这套系统的用户都是普通的操作员，基本上不可能计算出密码的算法。但是，我想说的是，难道软件的设计者把所有的安全性问题都寄托在用户的身上了么？希望所有的用户都具有安全专家一般的水平！希望整个系统从来不会进入入侵者！希望软件的使用者永远会循规蹈矩而不会窃取设置破坏其中数据！一个软件的安全体系，难道能架构在这些非技术性的东西上么？这就是我国软件业的真实平么？<br />
&nbsp;&nbsp;&nbsp; 这套耗资数千万元（可能上亿）的软件，由中国&#215;学院（不明说了，免得告我诽谤，呵呵）和北京&#215;&#215;软件公司（做过单机游戏，失败后转了型，大家可以猜猜看，非常有名的一个）设计，加密系统竟然如此简单。是水平不足？还是态度问题？我们的软件人，难道不应该反思么！米卢的那句话，太适合中国人了：态度决定一切！<br />
&nbsp;&nbsp;&nbsp; 不多说什么了，还是踏踏实实地走好自己的路吧。</p>
<p>&nbsp;&nbsp;&nbsp; 附：破解源程序（简陋之极，请勿见笑）</p>
<div class="cnblogs_code"><img id="Code_Closed_Image_111638" onclick="this.style.display='none'; document.getElementById('Code_Closed_Text_111638').style.display='none'; document.getElementById('Code_Open_Image_111638').style.display='inline'; document.getElementById('Code_Open_Text_111638').style.display='inline';" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" width="11" height="16"><img style="display: none" id="Code_Open_Image_111638" onclick="this.style.display='none'; document.getElementById('Code_Open_Text_111638').style.display='none'; getElementById('Code_Closed_Image_111638').style.display='inline'; getElementById('Code_Closed_Text_111638').style.display='inline';" align="top" src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width="11" height="16"><span id="Code_Closed_Text_111638" class="cnblogs_code_Collapse">Code</span><span style="display: none" id="Code_Open_Text_111638"><br />
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">用于&#215;&#215;系统2003年&#215;&#215;新程序，已知管理者密码，通过查询界面得到其他用户的加密密码后解密。</span><span style="color: #008000"><br />
/*</span><span style="color: #008000"><br />
加密原理：<br />
首先输入一个数字密码，最高为8位，不足8位用空格补齐。<br />
<br />
然后按一下方法换为字母：<br />
1-A,2-D,3-I,4-空格，5-L,6-G,7-1,8-J,9-N,0-M,空格-K。<br />
然后进行乱序排序，对应如下：<br />
ABCDEFGH排序为<br />
EDAGFCHB<br />
至此明文加密完毕。<br />
</span><span style="color: #008000">*/</span><span style="color: #000000"><br />
</span><span style="color: #008000">//</span><span style="color: #008000">只适用于数字密码部分。</span><span style="color: #008000"><br />
</span><span style="color: #000000"><br />
#include&nbsp;<br />
<br />
</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;a,b,c,d,e,f,g,h;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;A,B,C,D,E,F,G,H;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;take_number(</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;x);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800000">"</span><span style="color: #800000">请输入加密后的密码。每输入一位按空格，回车键结束输入。</span><span style="color: #800000">"</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;cin</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">a</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">b</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">c</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">d</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">e</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">f</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">g</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">h;<br />
&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;p</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">/&gt;</span><span style="color: #000000"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">运算出原始的密码。<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">第一步，返回排序前的序列状态。</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;A</span><span style="color: #000000">=</span><span style="color: #000000">c;B</span><span style="color: #000000">=</span><span style="color: #000000">h;C</span><span style="color: #000000">=</span><span style="color: #000000">f;D</span><span style="color: #000000">=</span><span style="color: #000000">b;E</span><span style="color: #000000">=</span><span style="color: #000000">a;F</span><span style="color: #000000">=</span><span style="color: #000000">e;G</span><span style="color: #000000">=</span><span style="color: #000000">d;H</span><span style="color: #000000">=</span><span style="color: #000000">g;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">第二步，将字母变为数字。即为原始密码。</span><span style="color: #008000"><br />
</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;take_number(A);<br />
&nbsp;&nbsp;&nbsp;&nbsp;take_number(B);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;take_number(C);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;take_number(D);<br />
&nbsp;&nbsp;&nbsp;&nbsp;take_number(E);<br />
&nbsp;&nbsp;&nbsp;&nbsp;take_number(F);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;take_number(G);&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;take_number(H);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">cout&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&nbsp;p=""&nbsp;/&gt;</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="color: #000000">&lt;&lt;&lt;</span><span style="color: #800000">"</span><span style="color: #800000">按任意键退出程序。</span><span style="color: #800000">"</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;p</span><span style="color: #000000">=</span><span style="color: #800000">""</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">/&gt;</span><span style="color: #000000"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">;<br />
}<br />
<br />
</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;take_number(</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;x)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">&gt;</span><span style="color: #800080">96</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">x</span><span style="color: #000000">&lt;</span><span style="color: #800080">122</span><span style="color: #000000">)&nbsp;x</span><span style="color: #000000">=</span><span style="color: #000000">x</span><span style="color: #000000">-</span><span style="color: #800080">26</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;A&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">1</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;D&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">2</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;I&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">3</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;&nbsp;&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">4</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;L&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">5</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;G&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">6</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;</span><span style="color: #800080">1</span><span style="color: #000000">&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">7</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;J&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">8</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;N&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">9</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(x</span><span style="color: #000000">==</span><span style="color: #000000">&#180;M&#180;)&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #800080">0</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;cout</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&#180;&nbsp;&#180;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></span></div>
 <img src ="http://www.cnblogs.com/benbenkoala/aggbug/1300104.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42809/" target="_blank">[新闻]51.COM技术副总裁邵辉跳槽百度</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>也晒晒我的RBAC系统（二）：系统实现原理简介</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/09/17/1292231.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Wed, 17 Sep 2008 02:27:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/09/17/1292231.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1292231.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/09/17/1292231.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1292231.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1292231.html</trackback:ping><description><![CDATA[&#160;&#160;&#160;&#160; <strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">在阅读这篇文章以前，建议大家先看一下</span></strong><span style="line-height: 150%; font-family: 宋体">Wenzy</span><span style="line-height: 150%; font-family: 宋体">发布的&#8220;</span><a href="http://www.cnblogs.com/Wenzy/archive/2006/09/19/504124.html"><span style="color: windowtext; line-height: 150%; font-family: 宋体; text-decoration: none; text-underline: none">Asp.net RBAC membership framework For Visual Studio 2005 <span style="color: windowtext; line-height: 150%; font-family: 宋体; text-decoration: none; text-underline: none">免费开源的Asp.net </span><span style="color: windowtext; line-height: 150%; font-family: 宋体; text-decoration: none; text-underline: none">权限管理系统</span><span style="color: windowtext; line-height: 150%; font-family: 宋体; text-decoration: none; text-underline: none">&#8221;</span></span></a><span style="line-height: 150%; font-family: 宋体">（</span><a href="http://www.cnblogs.com/wenzy/articles/504124.html"><span style="line-height: 150%; font-family: 宋体">http://www.cnblogs.com/wenzy/articles/504124.html</span></a><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">），本人的RBAC系统从中借鉴了很多非常好的思路，在此要向Wenzy兄表示感谢。具体的数据库建模图请看本系列的第一篇，这里不再重复给出。</span></strong>
<p style="text-indent: 21pt; line-height: 150%"><strong>&#160;</strong></p>
<p style="text-indent: 21.1pt; line-height: 150%"><strong><span style="color: #4b4b4b; line-height: 150%; font-family: 宋体">要实现权限验证，首先必须有对具体权限的定义。</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">在没有RBAC的情况下，一些简单的系统是把权限定义直接写死，整个系统有几种角色都提前定义好，在使用中只能给用户分配固定的角色。编程时，哪个模块需要做权限验证，就在哪个模块中直接编写代码，根据用户所属角色来设定用户在模块中具有的权限。这样的方法实现起来最简单，但也是最不灵活的，因为每个涉及到权限控制的部分都需要编写相应的判定代码。如果新增一个新的角色，那所有涉及到权限验证的模块都需要增加对新角色的验证代码，非常不灵活。</span></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">合适的方法是在项目编程前和编程过程中，定义出来系统中共有多少模块，每个模块涉及到有什么权限，最后汇总出一个总的权限列表来。在使用中可以由用户自己定义角色及角色权限。这样在编程时，判断当前用户是否有权调用某项权限时，只要判断一下用户所属角色是否具有此权限即可。可以通过一个通用的验证模块来完成权限验证工作，也简化了编程工作。如下图这个示例，首先定义出了所有权限并存储于数据库中，然后定义角色、角色具有的各项权限、角色所属用户，也存储到数据库中。这样在使用中涉及到某项权限，如使用&#8220;客户查询&#8221;时，通过验证模块就能判断出当前用户是否有权使用，如果有则进入，没有则退出。此种方法的缺点是系统规模较大或权限设定较细的情况下，需要定义的权限非常多，会大大增加编程工作量。</span></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体"><img height="428" alt="" src="http://images.cnblogs.com/cnblogs_com/benbenkoala/RBAC201.JPG" width="512" border="0" /></span></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">&#160; </span></strong></p>
<strong>
<p style="text-indent: 21.1pt; line-height: 150%"><strong><span style="color: #4b4b4b; line-height: 150%; font-family: 宋体">说了这么多后，该说一下本系统的实现原理了。</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">首先还是权限的定义，但此处权限不是直接定义的，而是通过&#8220;资源</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">-</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">操作&#8221;组合对来定义。</span></strong></p>
<p style="text-indent: 21.1pt; line-height: 150%"><strong></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'"><img height="393" alt="" src="http://images.cnblogs.com/cnblogs_com/benbenkoala/RBAC202.jpg" width="345" border="0" /></span></strong></p>
</strong>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">首先需要定义出系统中涉及到的所有资源（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ksRBAC_Resources</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">表和</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ksRBAC_ResourceGroups</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">表）。如库存管理中的仓库、车辆，销售系统中的商品、柜组等。每一项内容都可以定义成一项资源，且可以无限细分。在这里，还引入了资源组的概念，通过资源组及下属资源组的划分，使不同资源能够进行分类归档，方便了资源的管理。</span></strong><strong></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">其次需要定义操作（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ksRBAC_Operations</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">表），操作是指允许对某项资源进行何种操作行为。如针对仓库的操作有出库、入库、盘点等，针对车辆的操作有驾驶、保养，针对商品的操作有添加、删除、销售、进货、退货等等。</span></strong><strong></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">有了资源与操作，就能够定义权限了（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ksRBAC_Privilgegs</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">表）。所谓的权限，其实就是定义了可以对某项资源进行何种操作，即&#8220;资源</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">-</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">操作&#8221;组合对。如商品销售是一个权限定义，驾驶汽车也是一个权限定义。具体需要定义那些权限，是根据项目的实际需要来设置的。如资产管理的项目，会定义驾驶汽车、保养汽车、报废汽车的权限来跟踪车辆生命周期过程，而办公管理的项目，则只会定义驾驶汽车一项权限，因为其只关心汽车的使用而不关心保养问题。</span></strong><strong></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong>&#160;</strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">定义完了权限，就该定义角色了（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ksRBAC_Roles</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">表）。本系统中关于角色的定义比较简单，因为考虑到一个系统中的角色不会有很多，所以角色部分没有设置分组功能。</span></strong><strong></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><img height="118" alt="" src="http://images.cnblogs.com/cnblogs_com/benbenkoala/RBAC203.jpg" width="128" border="0" />&#160;</p>
<p style="text-indent: 21pt; line-height: 150%"><strong></strong>&#160;</p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">至此，系统权限的基本架构已经完成，通过上面的各个数据表，已经能够很好存储项目中所定义的各项权限、角色和授权了。</span></strong><strong></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong>&#160;</strong></p>
<p style="text-indent: 21.1pt; line-height: 150%"><strong><span style="color: #4b4b4b; line-height: 150%; font-family: 宋体">定义好角色权限后，有两种权限验证方式。</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">一种是将用户加入某个角色，在进行权限（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">Privilege</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">）验证时，首先得到用户所属角色，然后对此角色进行权限（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">Privilege</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">）验证。采用此种方法，由于验证对象是角色，因此用户只能加入一个角色，使用上不是很灵活，</span></strong><strong></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">本系统采用了另一种方法，将权限验证对象降低为具体用户。一个用户，可以同时加入多个角色。在用户登录时，首先得到用户所属的角色列表，然后依次得到授权（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">Permission</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">）给每个角色的权限（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">Privilege</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">）集合，最后将每一项权限（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">Privilege</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">）加入用户的权限列表中。这样在使用时，只要判断用户的权限列表中是否具有指定的权限（</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">Privilege</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">）即可完成验证工作。</span></strong><strong></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">对于用户的定义，此处涉及到了三个表。</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ksRBAC_User</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">是基础表，负责存储用户的登陆名称和密码等最基础的信息。</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ksRBAC_UserMembership</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">表为权限表，用于存储与权限验证有关的内容。</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ksRBAC_UserDetail</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">表是用户基本信息表，用于存储用户的各种资料信息。基本信息表在项目中由用户自己根据实际需求定义字段内容，保证在不同项目用户资料不一致的情况下，此表能够灵活适应各种情况。</span></strong></p>
<p style="text-indent: 21pt; line-height: 150%"><img height="729" alt="" src="http://images.cnblogs.com/cnblogs_com/benbenkoala/RBAC205.jpg" width="695" border="0" />&#160; </p>
<p style="text-indent: 21pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">&#160;</span></strong></p>
<p style="margin-left: 5.25pt; text-indent: 15.8pt; line-height: 150%"><strong><span style="color: #4b4b4b; line-height: 150%; font-family: 宋体">前面说了权限的存储与验证机制，那么在具体编程过程中，如何确定一个权限。</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">也就是说，程序怎么知道这个模块的这个操作表示权限</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">A</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">，那个模块的那个操作就表示权限</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">B</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">呢？这里需要通过硬编码来完成。</span></strong><strong></strong></p>
<p style="margin-left: 5.25pt; text-indent: 15.75pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">例如用户在使用商品模块，需要执行入库操作时，首先程序会拿出代表&#8220;入库操作&#8221;这一权限的</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ID</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">号，然后用此</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ID</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">和用户的权限列表进行比对，判断其中是否存在此</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ID</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">，如果有则继续向下执行，没有的话则提示用户权限不足并不再继续。至于权限的</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ID</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">号，可以从数据库中查询得出，在编码时直接写出来即可。</span></strong><strong></strong></p>
<p style="margin-left: 5.25pt; text-indent: 15.75pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">如果在编程时仅仅做到上面这一步，那么虽然可以实现系统所需的全部功能，但是在编程中指定权限时，还需要知道权限的</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ID</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">号，非常不方便。因此实际操作中是提前定义了一个权限文件，在其中使用以权限名称命名的字符传来存储权限</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ID</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">号，在使用时直接输入权限名称，就能得到权限</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 'Verdana','sans-serif'">ID</span></strong><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体">了。</span></strong></p>
<p style="margin-left: 5.25pt; text-indent: 15.75pt; line-height: 150%"><strong></strong><strong>&#160;</strong></p>
<p style="margin-left: 5.25pt; text-indent: 15.75pt; line-height: 150%"><strong><span style="font-weight: normal; color: #4b4b4b; line-height: 150%; font-family: 宋体"><strong>说了这么多，系统的实现原理就介绍的基本差不多了。</strong>有些地方说得不是很细，会在以后的文章中展开介绍的。欢迎大家共同探讨。</span></strong><strong></strong></p><img src ="http://www.cnblogs.com/benbenkoala/aggbug/1292231.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42807/" target="_blank">[新闻]Mono 2.0终于到来</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>反序列化时出现“base-64 字符数组的无效长度”错误提示的解决</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/09/04/1284112.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Thu, 04 Sep 2008 10:11:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/09/04/1284112.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1284112.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/09/04/1284112.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1284112.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1284112.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 程序中实现了这样一个功能，将一个对象序列化后，作为参数传递给另一个页面，这个页面得到参数并反序列化后还原此对象，但是在运行时有时正常，有时出现&#8220;<font face="Verdana">base-64 字符数组的无效长度&#8221;的错误提示。</font></p>
<p>&nbsp;&nbsp;&nbsp; 在网上查找资料，都是说在使用Convert.ToBase64String()方法对字符串进行Base64编码时，需要使参数的长度等于4或4的偶数倍数，否则将抛出&#8220;FormatException&#8221;异常。但是我这里使用的参数是使用<font face="Verdana">Convert.ToBase64String()方法生成的，理论上是没有问题的。于是对比<font face="Verdana">用Convert.ToBase64String()</font>生成的字符串A与反序列化前Convert.ToBase64String()所使用的参数字符串B，发现A与B之间有差异，A中的加号变成了空格。这是由于网页传递参数时，会将加号编码成空格，但是在解码时却不会解码空格，结果就造成了字符串B不正确，无法背编码。</font></p>
<p>&nbsp;&nbsp;&nbsp; 确认了问题就好办了，在得到序列化字符串后，使用String.<font face="Verdana">Replace("+", "%2B")先将空格编码，然后再作为参数传给另一页面传递，这样页面在提取参数时才会将&#8220;%2B&#8221;解码为加号，参数没有差别，在执行反序列化成功就通过了。</font></p>
 <img src ="http://www.cnblogs.com/benbenkoala/aggbug/1284112.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42808/" target="_blank">[新闻]百度任命李一男担任首席技术官</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>实战剖析三层架构2：实例代码</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/08/23/1274518.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Sat, 23 Aug 2008 01:57:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/08/23/1274518.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1274518.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/08/23/1274518.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1274518.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1274518.html</trackback:ping><description><![CDATA[摘要: 前段时间写了《实战剖析三层架构》，看有些朋友希望提供一下代码。但近期博客园上关于三层架构的文章很多，而且写得都很好，所以就不准备被再写了。不过这几天又有朋友留言鼓励，而且编程中发现一段比较合适的，所以还是决定写出来共享给大家。 先简要介绍一下，这个模块是一个商品管理模块。程序中实现了商品的浏览、添加、修改等功能。  Model项目，商品品牌实体类，BrandInfo.cs：CodeCode hig&nbsp;&nbsp;<a href='http://www.cnblogs.com/benbenkoala/archive/2008/08/23/1274518.html'>阅读全文</a><img src ="http://www.cnblogs.com/benbenkoala/aggbug/1274518.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42805/" target="_blank">[新闻]Google Knol 开始尝试有声版</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>删除百度贴吧上的内容</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/08/20/1271875.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Wed, 20 Aug 2008 00:33:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/08/20/1271875.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1271875.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/08/20/1271875.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1271875.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1271875.html</trackback:ping><description><![CDATA[<p><span style="font-family: 宋体">今天老大发现网上有对公司诋毁的言论，是在百度贴吧上，就催着让赶紧给删了。贴吧咱还能管啊，没办法，只能联系百度咨询，得到了如下答复：</span></p>
<p>&nbsp;</p>
<p><em><span style="font-family: 宋体">尊敬的用户：</span></em></p>
<p><em><span style="font-family: 宋体">您好！</span></em></p>
<p><em><span style="font-family: 宋体">百度贴吧、空间和知道上的内容全部来自网友，不代表百度的观点。针对贵单位的投诉，为了更加有效的维护贵单位的合法权益，请您提供以下材料：</span></em></p>
<p><em><span style="font-family: 'Times New Roman','serif'">1</span></em><em><span style="font-family: 宋体">、您认为侵犯贵单位合法权益的具体<strong>地址链接（</strong></span></em><strong><em><span style="font-family: 'Times New Roman','serif'">url</span></em></strong><strong><em><span style="font-family: 宋体">）及具体内容</span></em></strong><em><span style="font-family: 宋体">；</span></em></p>
<p><em><span style="font-family: 'Times New Roman','serif'">2</span></em><em><span style="font-family: 宋体">、请提供<strong>贵单位营业执照</strong>；若涉及个人的请提供身份证；</span></em><em></em></p>
<p><em><span style="font-family: 'Times New Roman','serif'">3</span></em><em><span style="font-family: 宋体">、出具<strong>保证函</strong>，请详细填写并<strong>加盖单位公章</strong>（保证函见附件）；</span></em></p>
<p><em><span style="font-family: 'Times New Roman','serif'">4</span></em><em><span style="font-family: 宋体">、若贵单位由律师代理，请提供对代理律师事务所的<strong>授权书</strong>。</span></em></p>
<p><em>&nbsp;</em></p>
<p><strong><em><span style="font-family: 宋体">特别提示</span></em></strong><em><span style="font-family: 宋体">：</span></em></p>
<p><em><span style="font-family: 'Times New Roman','serif'">1</span></em><em><span style="font-family: 宋体">、具体链接（</span></em><em><span style="font-family: 'Dotum','sans-serif'">URL</span></em><em><span style="font-family: 宋体">）及内容请以邮件正文发送；</span></em></p>
<p><em><span style="font-family: 'Times New Roman','serif'">2</span></em><em><span style="font-family: 宋体">、请将营业执照、身份证、保证函、或授权书，通过扫描</span></em><em><span style="font-family: 'Dotum','sans-serif'">/</span></em><em><span style="font-family: 宋体">数码拍照方式后（</span></em><em><span style="font-family: 'Dotum','sans-serif'">jpg</span></em><em><span style="font-family: 宋体">格式）作为附件发送至：</span><a title="mailto:webmaster@baidu.com" href="blocked::mailto:webmaster@baidu.com"><strong><span style="font-size: 11pt; font-family: 'Dotum','sans-serif'">webmaster@baidu.com</strong></a></span></em><em> </em><em><span style="font-family: 宋体">。</span></em></p>
<p><em><span style="font-family: 宋体">百度公司在收到贵单位的相关材料后，会按照法律法规的规定，积极履行电子公告服务提供商的义务，对侵权内容采取相关措施。</span></em></p>
<p><em><span style="font-family: 宋体">感谢您的回馈！</span></em></p>
<p><em>&nbsp;</em></p>
<p><em><span style="font-family: 宋体">感谢使用百度。希望您继续支持与关注百度。</span></em></p>
<p><em><span style="font-family: 宋体">谢谢！</span></em></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">于是照着提示，提供了公司的营业执照和保证函的复印件，然后写明想要删除的贴子的网址，发给百度客服</span><a title="mailto:webmaster@baidu.com" href="blocked::mailto:webmaster@baidu.com"><strong><span style="font-size: 11pt; font-family: 'Dotum','sans-serif'">webmaster@baidu.com</strong></a></span><span style="font-family: 宋体">，效率还是比较高的，不到半天就给删了。但是百度快照上的内容，需要一两天后才会消失。</span></p>
<img src ="http://www.cnblogs.com/benbenkoala/aggbug/1271875.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42804/" target="_blank">[新闻]12日电脑与人进行世纪对话 可思考机器或诞生</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>实战剖析三层架构1</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/05/29/1209658.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Thu, 29 May 2008 01:01:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/05/29/1209658.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1209658.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/05/29/1209658.html#Feedback</comments><slash:comments>59</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1209658.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1209658.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="line-height: 150%; font-family: 宋体">引言：本文不是从理论的角度来探讨三层架构，而是用一个示例来介绍如何建设一个三层架构的项目，并说明项目中各个文件所处的层次与作用。写本文的目的，不是为了说明自己的这个方法有多对，别人的肯定不对，而是希望给那些初学三层架构却不知从何入手的朋友提供一点帮助。因为网上的文章，大多是注重理论的介绍，而忽略了具体的实践应用，或者有示例但讲得不透彻。导致看了之后，理论上又学习了一遍，但还是不知道代码怎么写。所以想从这个方面入手写一下，让从来没做过三层架构的初学者也能照猫画虎，写出代码来。文章表述的是笔者个人对三层架构的认识，肯定有许多不足的地方，欢迎大家指正，小弟也会根据反馈来修改这篇文章。文中的代码是伪代码，仅用来阐明思路。<br />
</span><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; 正文：<br />
</span><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; 一提三层架构，大家都知道是表现层（</span><span style="line-height: 150%">UI</span><span style="line-height: 150%; font-family: 宋体">），业务逻辑层（</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">）和数据访问层（</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">），而且每层如何细分也都有很多的方法。但具体代码怎么写，到底那些文件算在哪一层，却是模模糊糊的。下面用一个简单的例子来带领大家实战三层架构的项目，这个例子只有一个功能，就是用户的简单管理。<br />
</span><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; 首先建立一个空白解决方案，添加如下项目及文件<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>1</span><span style="line-height: 150%; font-family: 宋体">、添加</span><span style="line-height: 150%">ASP.NET Web Application</span><span style="line-height: 150%; font-family: 宋体">项目，命名为</span><span style="line-height: 150%">UI</span><span style="line-height: 150%; font-family: 宋体">，新建</span><span style="line-height: 150%">Web Form</span><span style="line-height: 150%; font-family: 宋体">类型文件</span><span style="line-height: 150%">User.aspx</span><span style="line-height: 150%; font-family: 宋体">（含</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>2</span><span style="line-height: 150%; font-family: 宋体">、添加</span><span style="line-height: 150%">ClassLibrary</span><span style="line-height: 150%; font-family: 宋体">项目，命名为</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">，新建</span><span style="line-height: 150%">Class</span><span style="line-height: 150%; font-family: 宋体">类型文件</span><span style="line-height: 150%">UserBLL.cs<br />
<span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 150%">3</span><span style="line-height: 150%; font-family: 宋体">、添加</span><span style="line-height: 150%">ClassLibrary</span><span style="line-height: 150%; font-family: 宋体">项目，命名为</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">，新建</span><span style="line-height: 150%">Class</span><span style="line-height: 150%; font-family: 宋体">类型文件</span><span style="line-height: 150%">UserDAL.cs</span><span style="line-height: 150%; font-family: 宋体">。添加</span><span style="line-height: 150%">SQLHelper</span><span style="line-height: 150%; font-family: 宋体">引用。（这个是微软的数据访问类，也可以不用，直接编写所有的数据访问代码。我一般用自己写的数据访问类</span><span style="line-height: 150%">DataAccessHelper </span><span style="line-height: 150%; font-family: 宋体">）。<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>4</span><span style="line-height: 150%; font-family: 宋体">、添加</span><span style="line-height: 150%">ClassLibrary</span><span style="line-height: 150%; font-family: 宋体">项目，命名为</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: 宋体">，新建</span><span style="line-height: 150%">Class</span><span style="line-height: 150%; font-family: 宋体">类型文件</span><span style="line-height: 150%">UserModel.cs<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>5</span><span style="line-height: 150%; font-family: 宋体">、添加</span><span style="line-height: 150%">ClassLibrary</span><span style="line-height: 150%; font-family: 宋体">项目，命名为</span><span style="line-height: 150%">IDAL</span><span style="line-height: 150%; font-family: 宋体">，新建</span><span style="line-height: 150%">Interface</span><span style="line-height: 150%; font-family: 宋体">类型文件</span><span style="line-height: 150%">IUserDAL.cs<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>6</span><span style="line-height: 150%; font-family: 宋体">、添加</span><span style="line-height: 150%">ClassLibrary</span><span style="line-height: 150%; font-family: 宋体">项目，命名为</span><span style="line-height: 150%">ClassFactory<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>相信大家已经看出来了，这个和</span><span style="line-height: 150%">Petshop</span><span style="line-height: 150%; font-family: 宋体">的示例没什么区别，而且更简单，因为在下也是通过</span><span style="line-height: 150%">Petshop</span><span style="line-height: 150%; font-family: 宋体">学习三层架构的。但一些朋友对于这几个项目所处的层次，以及它们之间的关系，可能比较模糊，这里逐个说明一下：<br />
</span><strong><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>1</span></strong><strong><span style="line-height: 150%; font-family: 宋体">、</span></strong><strong><span style="line-height: 150%">User.aspx</span></strong><strong><span style="line-height: 150%; font-family: 宋体">和</span></strong><strong><span style="line-height: 150%">User.aspx.cs<br />
</span></strong><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>这两个文件（以及文件所属的项目，下面也是如此，不再重复强调了）都属于表现层部分。</span><span style="line-height: 150%">User.aspx</span><span style="line-height: 150%; font-family: 宋体">比较好理解，因为它就是显示页面了。</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">有些人觉得不应该算，而是要划到业务逻辑层中去。如果不做分层的话，那么让</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">来处理业务逻辑，甚至操作数据库都没什么问题，但是做分层的话，这样就不应该了。在分层结构中，</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">仅应该处理与显示有关的内容，其它部分都不应该涉及。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>举例：我们实现用列表方式显示用户的功能，那么提取信息的工作是由</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">来做的，</span><span style="line-height: 150%">UI</span><span style="line-height: 150%; font-family: 宋体">（本例中是</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">）调用</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">得到</span><span style="line-height: 150%">UserInfo</span><span style="line-height: 150%; font-family: 宋体">后，通过代码绑定到</span><span style="line-height: 150%">User.aspx</span><span style="line-height: 150%; font-family: 宋体">的数据控件上，就实现了列表的显示。在此过程中</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">对</span><span style="line-height: 150%">UI</span><span style="line-height: 150%; font-family: 宋体">没有起到什么作用，仅是用来传递数据，而且因为实际编码中大部分情况都是如此的实现，所以使有些人觉得</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">不应该算</span><span style="line-height: 150%">UI</span><span style="line-height: 150%; font-family: 宋体">，而应该并入</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">负责逻辑处理。继续往下看，这时提出了一个新需求，要求在每个用户的前面加一个图标，生动地表现出用户的性别，而且不满</span><span style="line-height: 150%">18</span><span style="line-height: 150%; font-family: 宋体">岁的用儿童图标表示。这个需求的实现，就轮到</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">来做了，这种情况下</span><span style="line-height: 150%">User.aspx.cs</span><span style="line-height: 150%; font-family: 宋体">才算有了真正的用途。<br />
</span><strong><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>2</span></strong><strong><span style="line-height: 150%; font-family: 宋体">、</span></strong><strong><span style="line-height: 150%">NewBLL.cs<br />
</span></strong><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>添加如下方法：<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public IList&lt;UserInfo&gt; GetUsers()</span><span style="line-height: 150%; font-family: 宋体">：返回所有的用户信息列表<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public UserInfo GetUser(int UserId)</span><span style="line-height: 150%; font-family: 宋体">：返回指定用户的详细信息<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public bool AddUser(UserInfo User)</span><span style="line-height: 150%; font-family: 宋体">：新增用户信息<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public bool ChangeUser(UserInfo User)</span><span style="line-height: 150%; font-family: 宋体">：更新用户信息<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public void RemoveUser(int UserId)</span><span style="line-height: 150%; font-family: 宋体">：移除用户信息<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>此文件就属于业务逻辑层了，专门用来处理与业务逻辑有关的操作。可能有很多人觉得这一层唯一的用途，就是把表现层传过来的数据转发给数据层。这种情况确实很多，但这只能说明项目比较简单，或者项目本身与业务的关系结合的不紧密（比如当前比较流行的</span><span style="line-height: 150%">MIS</span><span style="line-height: 150%; font-family: 宋体">），所以造成业务层无事可做，只起到了一个转发的作用。但这不代表业务层可有可无，随着项目的增大，或者业务关系比较多，业务层就会体现出它的作用来了。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>此处最可能造成错误的，就是把数据操作代码划在了业务逻辑层，而把数据库作为了数据访问层。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>举例：有些朋友感觉</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">层意义不大，只是将</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">的数据提上来就转发给了</span><span style="line-height: 150%">UI</span><span style="line-height: 150%; font-family: 宋体">，而未作任何处理。看一下这个例子<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>BLL</span><span style="line-height: 150%; font-family: 宋体">层<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>SelectUser</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">UserInfo userInfo</span><span style="line-height: 150%; font-family: 宋体">）根据传入的</span><span style="line-height: 150%">username</span><span style="line-height: 150%; font-family: 宋体">或</span><span style="line-height: 150%">email</span><span style="line-height: 150%; font-family: 宋体">得到用户详细信息。<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>IsExist</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">UserInfo userInfo</span><span style="line-height: 150%; font-family: 宋体">）判断指定的</span><span style="line-height: 150%">username</span><span style="line-height: 150%; font-family: 宋体">或</span><span style="line-height: 150%">email</span><span style="line-height: 150%; font-family: 宋体">是否存在。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>然后</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">也相应提供方法共</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">调用<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>SelectUser</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">UserInfo userInfo</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>IsExist</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">UserInfo userInfo</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>这样</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">确实只起到了一个传递的作用。<br />
<span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 150%; font-family: 宋体">但如果这样做：<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>BLL.IsExist</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">Userinfo userinfo</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>{<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UerInfo user = DAL.SelectUser</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">User</span><span style="line-height: 150%; font-family: 宋体">）；<br />
<span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 150%">return (userInfo.Id != null);</span>&nbsp;<br />
<span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>}<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>那么</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">就无需实现</span><span style="line-height: 150%">IsExist()</span><span style="line-height: 150%; font-family: 宋体">方法了，</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">中也就有了逻辑处理的代码。<br />
</span><strong><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>3</span></strong><strong><span style="line-height: 150%; font-family: 宋体">、</span></strong><strong><span style="line-height: 150%">UserModel.cs<br />
</span></strong><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>实体类，这个东西，大家可能觉得不好分层。包括我以前在内，是这样理解的：</span><span style="line-height: 150%">UI</span><span style="line-height: 150%; font-family: Wingdings">&#223;</span><span style="line-height: 150%; font-family: Wingdings">&#224;</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: Wingdings">&#223;</span><span style="line-height: 150%; font-family: Wingdings">&#224;</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: Wingdings">&#223;</span><span style="line-height: 150%; font-family: Wingdings">&#224;</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: Wingdings">&#223;</span><span style="line-height: 150%; font-family: Wingdings">&#224;</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">，如此则认为</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: 宋体">在各层之间起到了一个数据传输的桥梁作用。不过在这里，我们不是把事情想简单，而是想复杂了。<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>Model</span><span style="line-height: 150%; font-family: 宋体">是什么？它什么也不是！它在三层架构中是可有可无的。它其实就是面向对象编程中最基本的东西：类。一个桌子是一个类，一条新闻也是一个类，</span><span style="line-height: 150%">int</span><span style="line-height: 150%; font-family: 宋体">、</span><span style="line-height: 150%">string</span><span style="line-height: 150%; font-family: 宋体">、</span><span style="line-height: 150%">doublie</span><span style="line-height: 150%; font-family: 宋体">等也是类，它仅仅是一个类而已。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>这样，</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: 宋体">在三层架构中的位置，和</span><span style="line-height: 150%">int</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%">string</span><span style="line-height: 150%; font-family: 宋体">等变量的地位就一样了，没有其它的目的，仅用于数据的存储而已，只不过它存储的是复杂的数据。所以如果你的项目中对象都非常简单，那么不用</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: 宋体">而直接传递多个参数也能做成三层架构。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>那为什么还要有</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: 宋体">呢，它的好处是什么呢。下面是思考一个问题时想到的，插在这里：</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span><strong>Model</strong></span><span style="line-height: 150%; font-family: 宋体"><strong>在各层参数传递时到底能起到做大的作用？</strong><br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>在各层间传递参数时，可以这样：<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>AddUser</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">userId</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%">userName</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%">userPassword</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%">&#8230;</span><span style="line-height: 150%; font-family: 宋体">，）<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>也可以这样：<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>AddUser</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">userInfo</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>这两种方法那个好呢。一目了然，肯定是第二种要好很多。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>什么时候用普通变量类型（</span><span style="line-height: 150%">int,string,guid,double</span><span style="line-height: 150%; font-family: 宋体">）在各层之间传递参数，什么使用</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: 宋体">传递？下面几个方法：<br />
<span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 150%">SelectUser</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">int UserId</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>SelectUserByName</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">string username</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>SelectUserByName</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">string username</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%">string password</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>SelectUserByEmail</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">string email</span><span style="line-height: 150%; font-family: 宋体">）<br />
<span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 150%">SelectUserByEmail</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">string email</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%">string password</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>可以概括为：<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>SelectUser</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">userId</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>SelectUser</span><span style="line-height: 150%; font-family: 宋体">（</span><span style="line-height: 150%">user</span><span style="line-height: 150%; font-family: 宋体">）<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>这里用</span><span style="line-height: 150%">user</span><span style="line-height: 150%; font-family: 宋体">这个</span><span style="line-height: 150%">Model</span><span style="line-height: 150%; font-family: 宋体">对象囊括了</span><span style="line-height: 150%">username</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%">password</span><span style="line-height: 150%; font-family: 宋体">，</span><span style="line-height: 150%">email</span><span style="line-height: 150%; font-family: 宋体">这三个参数的四种组合模式。</span><span style="line-height: 150%">UserId</span><span style="line-height: 150%; font-family: 宋体">其实也可以合并到</span><span style="line-height: 150%">user</span><span style="line-height: 150%; font-family: 宋体">中，但项目中其它</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">都实现了带有</span><span style="line-height: 150%">id</span><span style="line-height: 150%; font-family: 宋体">参数的接口，所以这里也保留这一项。</span>&nbsp;<br />
<span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>传入了</span><span style="line-height: 150%">userInfo</span><span style="line-height: 150%; font-family: 宋体">，那如何处理呢，这个就需要按照先后的顺序了，有具体代码决定。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>这里按这个顺序处理<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>首先看是否同时具有</span><span style="line-height: 150%">username</span><span style="line-height: 150%; font-family: 宋体">和</span><span style="line-height: 150%">password</span><span style="line-height: 150%; font-family: 宋体">，然后看是否同时具有</span><span style="line-height: 150%">email</span><span style="line-height: 150%; font-family: 宋体">和</span><span style="line-height: 150%">password</span><span style="line-height: 150%; font-family: 宋体">，然后看是否有</span><span style="line-height: 150%">username</span><span style="line-height: 150%; font-family: 宋体">，然后看是否有</span><span style="line-height: 150%">email</span><span style="line-height: 150%; font-family: 宋体">。依次处理。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>这样，如果以后增加一个新内容，会员卡（</span><span style="line-height: 150%">number</span><span style="line-height: 150%; font-family: 宋体">），则无需更改接口，只要在</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">的代码中增加对</span><span style="line-height: 150%">number</span><span style="line-height: 150%; font-family: 宋体">的支持就行，然后前台增加会员卡一项内容的表现与处理即可。</span>&nbsp;<br />
<strong><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>4</span></strong><strong><span style="line-height: 150%; font-family: 宋体">、</span></strong><strong><span style="line-height: 150%">UserDAL.cs<br />
</span></strong><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public IList&lt;UserInfo&gt; SelectUsers()</span><span style="line-height: 150%; font-family: 宋体">：返回所有的用户信息列表<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public UserInfo SelectUser(int UserId)</span><span style="line-height: 150%; font-family: 宋体">：返回指定用户的相信信息<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public bool InsertUser(UserInfo User)</span><span style="line-height: 150%; font-family: 宋体">：新增用户信息<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public bool UpdateUser(UserInfo User)</span><span style="line-height: 150%; font-family: 宋体">：更新用户信息<br />
</span><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>public void DeleteUser(int UserId)</span><span style="line-height: 150%; font-family: 宋体">：移除用户信息<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>很多人最闹不清的就是数据访问层，到底那部分才算数据访问层呢？有些认为数据库就是数据访问层，这是对定义没有搞清楚，</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">是数据访问层而不是数据存储层，因此数据库不可能是这一层的。也有的把</span><span style="line-height: 150%">SQLHelper</span><span style="line-height: 150%; font-family: 宋体">（或其同类作用的组件）作为数据访问层，它又是一个可有可无的东西，</span><span style="line-height: 150%">SQLHelper</span><span style="line-height: 150%; font-family: 宋体">的作用是减少重复性编码，提高编码效率，因此如果我习惯在乎效率或使用一个非数据库的数据源时，可以丢弃</span><span style="line-height: 150%">SQLHelper</span><span style="line-height: 150%; font-family: 宋体">，一个可以随意弃置的部分，又怎么能成为三层架构中的一层呢。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>可以这样定义：与数据源操作有关的代码，就应该放在数据访问层中，属于数据访问层<br />
</span><strong><span style="line-height: 150%"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>5</span></strong><strong><span style="line-height: 150%; font-family: 宋体">、</span></strong><strong><span style="line-height: 150%">IUserDAL<br />
</span></strong><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>数据访问层接口，这又是一个可有可无的东西，因为</span><span style="line-height: 150%">Petshop</span><span style="line-height: 150%; font-family: 宋体">中带了它和</span><span style="line-height: 150%">ClassFactory</span><span style="line-height: 150%; font-family: 宋体">类工厂，所以有些项目不论需不需要支持多数据源，都把这两个东西做了进来，有的甚至不建</span><span style="line-height: 150%">ClassFactory</span><span style="line-height: 150%; font-family: 宋体">而只建了</span><span style="line-height: 150%">IDAL</span><span style="line-height: 150%; font-family: 宋体">，然后&#8220;</span><span style="line-height: 150%">IUserDAL iUserDal = new UserDAL();</span><span style="line-height: 150%; font-family: 宋体">&#8221;，不知意义何在。这就完全是画虎不成反类犬了。<br />
<span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 150%; font-family: 宋体">许多人在这里有一个误解，那就是以为存在这样的关系：</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: Wingdings">&#223;</span><span style="line-height: 150%; font-family: Wingdings">&#224;</span><span style="line-height: 150%">IDAL</span><span style="line-height: 150%; font-family: Wingdings">&#223;</span><span style="line-height: 150%; font-family: Wingdings">&#224;</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">，认为</span><span style="line-height: 150%">IDAL</span><span style="line-height: 150%; font-family: 宋体">起到了</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">和</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">之间的桥梁作用，</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">是通过</span><span style="line-height: 150%">IDAL</span><span style="line-height: 150%; font-family: 宋体">来调用</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">的。但实际是即使你如此编码：&#8220;</span><span style="line-height: 150%">IUserDAL iUserDal = ClassFacotry.CreateUserDAL()</span><span style="line-height: 150%; font-family: 宋体">；&#8221;，那么在执行&#8220;</span><span style="line-height: 150%">iUserDal.SelectUsers()</span><span style="line-height: 150%; font-family: 宋体">&#8221;时，其实还是执行的</span><span style="line-height: 150%">UserDAL</span><span style="line-height: 150%; font-family: 宋体">实例，而不是</span><span style="line-height: 150%">IUserDAL</span><span style="line-height: 150%; font-family: 宋体">实例，所以</span><span style="line-height: 150%">IDAL</span><span style="line-height: 150%; font-family: 宋体">在三层中的位置是与</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">平级的关系。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>通过上面的介绍，基本上将三层架构的层次结构说明了。其实，本人有一个判断三层架构是否标准的方法，那就是将三层中的任意一层完全替换，都不会对其它两层造成影响，这样的构造基本就符合三层标准了（虽然实现起来比较难</span><span style="line-height: 150%">^_^</span><span style="line-height: 150%; font-family: 宋体">）。例如如果将项目从</span><span style="line-height: 150%">B/S</span><span style="line-height: 150%; font-family: 宋体">改为</span><span style="line-height: 150%">C/S</span><span style="line-height: 150%; font-family: 宋体">（或相反），那么除了</span><span style="line-height: 150%">UI</span><span style="line-height: 150%; font-family: 宋体">以外，</span><span style="line-height: 150%">BLL</span><span style="line-height: 150%; font-family: 宋体">与</span><span style="line-height: 150%">DAL</span><span style="line-height: 150%; font-family: 宋体">都不用改动；或者将</span><span style="line-height: 150%">SQLServer</span><span style="line-height: 150%; font-family: 宋体">改为</span><span style="line-height: 150%">Oracle</span><span style="line-height: 150%; font-family: 宋体">，只需替换</span><span style="line-height: 150%">SQLServerDAL</span><span style="line-height: 150%; font-family: 宋体">到</span><span style="line-height: 150%">OracleDAL</span><span style="line-height: 150%; font-family: 宋体">，无需其它操作等等。本来想在文中加入一些具体的代码的，但感觉不是很必要，如果大家觉得需要的话，我再补充吧。<br />
</span><span style="line-height: 150%; font-family: 宋体"><span style="line-height: 150%; font-family: 宋体">&nbsp;&nbsp;&nbsp; </span>总结：不要因为某个层对你来说没用，或者实现起来特别简单，就认为它没有必要，或者摒弃它，或者挪作它用。只要进行了分层，不管是几层，每一层都要有明确的目的和功能实现，而不要被实际过程所左右，造成同一类文件位于不同层的情况发生。也不要出现同一层实现了不同的功能的情况发生。</span> 
<img src ="http://www.cnblogs.com/benbenkoala/aggbug/1209658.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42803/" target="_blank">[新闻]人民网评:中国移动为什么要抛弃iPhone?</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>不吐不快：程序员到底有没有前途</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/02/26/1081481.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Tue, 26 Feb 2008 01:40:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/02/26/1081481.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1081481.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/02/26/1081481.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1081481.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1081481.html</trackback:ping><description><![CDATA[<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 早上到单位，看昨天晚上QQ群里的内容，有人在问做程序员怎么样。马上就有人跳出来告诉他程序员又苦、又累，要求又高、赚得也不比人多，而且30岁以后肯定失业那一套。对程序员的前途，自己有自己的想法，但这没什么好说的，而且每个人都有适合本人的路，也不想拿自己的想法来影响别人，可是今天实在实在是忍无可忍了，有一种不吐不快的感觉。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先，我说的可能过了些，但还是要说，现在中国不学无术还在祸害别人的人实在是太多了。我不清楚那些说程序员没前途的人到底是什么想法，是他自己没混好真的感觉没前途，还是已经混的不错了但却偏偏忽悠别人，好减少竞争对手。但是，归根到底，这种做法都是在误导程序员这个行业，不管是对业内人士，还是业外人士。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其次，一说程序员如何，好像大家都是在说干这行能赚多少钱，到底累不累。却很少有人讨论这行的工作性质如何，是否符合自己的生活习惯，是否适合自己的兴趣爱好。有人会说，不爱好谁会选这一行呢。但从潜意识的层面说起，你敢保证自己不是因为比尔盖茨等程序名人耀眼的光环与成功的事业经历而投身这一行的？看看现在网上的技术讨论，有多少人只是为了得到某个技术点的代码，而不是关心技术本身的呢。一个人如果不爱这一行，尤其是技术行业，很难想象他会在这一行有所成就。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 再次，我想说一点，现在程序员已经并不是高薪、享受的代名词了（虽然有些程序员确实很高薪很享受），它就是一个普通的职业，为什么那个行业赚3000你觉得理所当然，这个行业就觉得吃亏呢。我想问一句，有多少人是因为喜欢编程才进这一行的，又有多少人是抱着捞一笔就走的心态呢。<font face="Verdana">如果你想赚钱，可以去经商；如果你想出名，可以去选秀或从网上自秀，出名很快。如果您想安逸一些，可以找个行政事务性的工作（不见得是公务员，公司搞行政的岗位多的是）。每一行都能达到你的要求，为什么非要通过干程序员这一行来满足这些需求呢。归根到底，还是以前技术缺乏的时代只要能写几行代码就能赚钱出名的老观念在作怪，但是现在的社会已经变了，该醒醒了。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其实，每个程序员，都有这样的一种忧虑，以后干不动了我该怎么办？但我们真是过了30就干不动了么。<br />
</font></font><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不是跑题，让我说一个其它的行业吧。建筑业，虽然我不太熟悉这个行业，但是感觉它和编程行业有着很多相同点。每一座建筑，都是一个工程，而程序中每一个项目，不也是叫做工程么。决定建筑计划（决定项目计划）- 决定建筑功能（确定软件需求）- 建筑设计图纸（软件建模）- 开始建筑施工（进入编码阶段）- 施工完成验收（项目验收）- 客户入住（客户使用）- 后期维护阶段（后期技术支持），整个流程很类似吧。那么这样一座建筑，从开始到结束，一共需要多少个岗位支持呢（我肯定说的不准，欢迎大家指正）？业务人员：这个相当于软件公司的业务吧；建筑设计师：这个我不知道怎么类比，建筑界我现在马上想到了贝律铭，软件业能够将编程做到艺术级别的，少之又少；建筑工程师：相当于架构师吧。能够把天马行空的想法，转变为实际可行的编程架构。软件业这个级别的人才，就可以量产了，但还是很少。而且软件业不同于建筑业，许多东西都已经成为定式，在大学里就能学到。每一个好的架构师，都是靠大量的项目经历锻炼出来的。工头（呵呵，不清楚这个在建筑业怎么说）：相当于项目经理，统筹具体的日常工作。施工人员：工头下面，就是具体干活的人了，有电工、起重、焊工、架子工、木工、油漆工、砌筑工、抹灰工、瓦工、混凝土工、防水工，试验工、水工等，很多啊，对应软件业，不就是掌握各种技术的程序员了么。小工：这些人基本没有技术，全凭体力干活，软件业好像没有，但网管行业里好像很多这种类型的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 好了，废话说了很多，不清楚大家明白我的意思了没有，从行业整体来衡量，大家可以看看自己处于一个什么样的位置。同样的体系结构，有说建筑业没前途，30岁以后干不下去的么？换成软件业，怎么就怨声载道了。许多人，包括我自己在内，我们的技术可能已经达到了一定的水平，但我们的思维、所做的工作，还都是处在软件业的最底层。就像建筑业的施工人员，即使他会所有具体的工作，做得再熟练，但如果不继续深造向上发展的话，也成不了建筑工程师，那他会有前途么？我们凭什么说做程序员没前途，如果真的能够达到项目经理、架构师、甚至设计师的高度，还会发愁做不动，还会担心没前途么？<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其实，国内软件业的整体环境还比较差，程序员这一工作距离我们的理想环境还有很大的距离。而且作为一个程序员，即使是最普通的程序员，其前期技术积累所付出的精力与金钱也不是建筑行业的工人可以相比的。但这些不是我们抱怨的理由。如果你真的爱好编程，愿意长期从事这一行业，那我希望这篇文章能给您以小小的鼓励。做好自己的定位，坚定自己的信念，不要被他人所左右，只要持之以恒，绝对会有回报的。</font></p>
     <img src ="http://www.cnblogs.com/benbenkoala/aggbug/1081481.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42802/" target="_blank">[新闻]索尼推出第二代触控屏eBook电子书</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>也晒晒我的RBAC系统（一）：概述</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/01/26/1052953.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Sat, 26 Jan 2008 02:16:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/01/26/1052953.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1052953.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/01/26/1052953.html#Feedback</comments><slash:comments>28</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1052953.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1052953.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;引言：本来园子里已经有不少RBAC方面的文章了，而且自己的这个系统也参考了其中一些朋友的思想和创意，考虑是不是还有发表的必要。但感觉虽然是同样的东西，由于每个人的出发点与目标都不相同，所以做出来的东西也不会是一样的。而且有些东西，我现在只是做出了架构设计，具体实现起来会不会很合适，也不太清楚。有园子里的弟兄们给提提建议，也是一件好事。是不是发在首页，也考虑了一下，感觉这篇文章，抛开质量不说，起码从字数上会对得起大家<img alt="" src="http://www.cnblogs.com/Emoticons/QQ/15.gif" />。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong> 正文部分<br />
<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关于RBAC的基本理论，这里就不再多说了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我是去年才接触RBAC这个概念的，许多东西了解的并不透彻，而且由于几年前就已经熟练使用Windows活动目录的权限管理系统了，因此一些理念和正宗RBAC观念会有一些出入，但应该不会对RBAC的主旨产生太大的影响。如果您觉得我加入的一些东西是多余的，或者感觉不习惯，欢迎提出看法，我会根据情况进行改进，谢谢。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其实开始并没有编写RBAC的想法，但是使用了微软的membership后，感觉很不顺手，兼容性、易用性、复用度等方面也感觉不适合自己。正好手上几个项目都涉及到了较为复杂的用户权限管理功能，因此年初决定用几个月的时间来专门做一下这个项目，即通过这个过程进行学习，也减轻一下以后的工作量。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因此，我写这篇文章也不是为了建立一个RBAC的范本，从理论上来供大家研讨，而是一切从实际出发，把我制作这个项目中的想法随着项目的进度写出来，在这个过程中探讨遇到的理论与技术点。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>废话说得太多了，转入正题</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;要做RBAC，首先需要确定需求。开始是根据几个项目来考虑它们的共同点，看涉及到用户管理、权限验证的部分，那些是几个项目都需要实现的，哪些是某个项目所特有的，慢慢确立了RBAC的需求，决定了它要实现什么功能。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;开始时，只想将项目从数据库建模开始，往上做到BLL这一层，然后其它项目可以使用此BLL，处理RBAC方面的工作，就相当于把几个项目的RBAC部分共享一样。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后来感觉如果只做到这一层的话，以后复用的话，工作量还是会很大。所以决定将后台管理部分的UI层也做出来。这样就相当于几个项目连界面部分也可以共享了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;然而在实际过程中，觉得即使做出了后台管理的UI。其它项目使用这个模块也会比较费事。而且这种模式，项目对RBAC的调用与调用项目内模块没什么区别。用户在使用RBAC项目时还是需要了解其内部的一些操作方法，耦合度太高，没有实现封装。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后来有了进一步的想法，能不能将其做成一个框架。虽然水平有限，说框架有些大，而且也不见得能做完美，但目标还是可以定得高一点么。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;既然想做成框架，那就不是提供一个数据库模型，并完成相关的代码就了事的。我的想法就是，能够让用户在用脚本建立建立数据库，复制UI界面文件到项目文件夹，并引用dll后，无需再进行其它的配置工作，就能直接使用这套框架。用户自己编程进行RBAC操作时，只要一两个类就可以完成所有工作，对用户隐藏所有细节。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;基于这种想法，我开始进行项目的建设，现在已经建立了下面几部分：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （1）BLL：业务逻辑层。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用于处理业务逻辑相关的工作，此层内容仅对RBAC项目内的成员开发，不提供对外调用。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（2）ClassFactory：类工厂。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当前仅支持数据访问层对象的创建。以后视需要增加新的工厂。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（3）Demo&nbsp;for WinForm：C/S模式界面模板<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;提供Windows程序的界面文件与操作代码，如果不想自己设计界面，可以直接使用此现成的界面文件。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（4）Demo for WebForm：B/S模式界面模板<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;提供Web项目的界面文件与操作代码。如果不想自己设计Web界面，可以直接使用此界面。否则只要制作新的CSS文件，替换原有css文件，即可实现自己的界面。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（5）IDAL：数据库访问层接口定义<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;没什么好说的<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（6）Model：实体类<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;同样<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（7）OracleDAL：Oracle 数据库访问层<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;支持Oracle数据库，这个准备先放一放，Oracle编程太不爽了<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（8）Privilege Config Tools：权限配置工具<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Windows程序，其它项目在使用此框架时，需要生成自己的的权限文件。这个工具就是用来做这件事情的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（9）RBAC Manager：RABC管理类<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这个是对外服务的部分，其它项目只要直接引用此dll，即可进行涉及到RBAC的各种操作。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（10）SQLServerDAL：SQL Server 数据库访问层<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;支持SQL Server数据库。也没什么好说的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;现在大家可以看出来了，作为最终用户，如果在项目中使用这个框架的话，那么他所要关心的只是RBAC Manger这一个namespace下的类的使用，而无需关住RBAC的细节。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>项目组件说完了，再来介绍一下数据库建模<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;说明一下，为了保证大家都能看清楚图片，所以我把图片存得大了些，右边的几个表看不见，大家费点事另存到桌面上再看吧。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据库建模图：<br />
<br />
<img height="871" alt="" src="http://www.cnblogs.com/images/cnblogs_com/benbenkoala/RBAC_SQLServe_Model.jpg" width="888" border="0" /><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;说一下各表的用途<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所有表均以ksRBAC开头，避免与其它项目表重名。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（1）用户部分<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_Users：用户基本表。此表仅存储最少量的用户信息，用于用户登陆、权限认证等常见的工作。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_UserMembership：用户权限表。此表用来存储涉及到权限系统工作的想关信息。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_UserDetail：用户基本信息表。用于存储用户的日常信息。只在查看用户资料时需要调用。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其实这个三表的内容完全可以放到一张表中，但感觉分到三个表里，在编程上会清晰一些。这里可能有不合理的地方，还望大家指正。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（2）权限部分<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_ResourceGroups：资源分组。用于将同类资源进行分组，以方便管理，支持多级分类。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_Resources：资源。记录具体的资源对象。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_Operations：操作。记录具体的操作方法。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_Privileges：权限表。通过结成&#8220;资源-操作&#8221;对，来实现权限的定制。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（3）角色部分<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_Roles：角色表。存储所有角色。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_PrivilegeInRoles：<font face="Verdana">用户表，用于存储与身份验证有关的信息<br />
</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_UsersInRoles：用户所属角色表。通过此表来设定用户具有那个角色的权限。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（4）分组部分<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_Groups：分组表。存储分组相关信息<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_GroupsInGroups：组<font face="Verdana">属组表。设置分组所属的分组。</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_GroupEstates：<font face="Verdana">组状态类型</font>表。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_UsersInGroups：组属用户表。设置用户所属组。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_UserInGroupEstates：组用户状态类型表。用于记录<font face="Verdana">组中用户的状态。</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（5）日志部分<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这部分的内容还没有做完，因为现在还没有进展到涉及日志的操作，所以不能决定到底需要什么东西。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ksRBAC_UserLog：用户日志。用于记录用户操作<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对于用户、权限、角色三部分的表，大家应该都没有什么疑问，稍微有些理解上的差异也也该是设计习惯不同造成的。感觉主要会在分组这一块有不同的理解。看了一些相关文章，也有涉及到分组设计的，但这些设计从功能上来讲相差甚远。有的是将分组与角色关联，相当于做了一个RoleGroups表，这种分组起到了分类角色的作用。有的是将分组作为一个组织结构架构来做，然后再与用户关联，这种分组起到了分类用户的作用。本项目中的分组，是与用户相关的，而与角色无关，它实现的是用户分类的功能。但分组在这里并不仅仅起到一个分类用户的功能，还有一个重要的功能，但因为每进行具体的代码编写，所以现在还不好说，我会在完善以后写出来的。<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;本来还有许多想写的，但是刚开始感觉思路上不是特别清晰，有些无从下笔，一些东西也不清楚是不是有必要说，就此打住吧。看看大家反馈，再决定需要写些什么内容吧。欢迎大家拍砖。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第一篇文章，其实并没有涉及到具体的技术细节，只是从整体上俯瞰一下这个项目。如果您没有用过RBAC，肯定会感觉到有些不知所云。以后我会在涉及到细节的地方详细讲解的。
<img src ="http://www.cnblogs.com/benbenkoala/aggbug/1052953.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42801/" target="_blank">[新闻]百付宝加入战团 电子支付市场寻突破</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>执行foreach时出现An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll的错误查解</title><link>http://www.cnblogs.com/benbenkoala/archive/2008/01/07/1029016.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Mon, 07 Jan 2008 06:45:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2008/01/07/1029016.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1029016.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2008/01/07/1029016.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1029016.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1029016.html</trackback:ping><description><![CDATA[执行一个Foreach循环时，系统提示：<br />
<font face="Courier New">An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll<br />
从字面上看，是堆栈溢出错误。<br />
<br />
进过查找，发现这是因为进入了死循环，系统给出的提示。<br />
修改程序解决死循环后，问题解决。<br />
<br />
</font>
<img src ="http://www.cnblogs.com/benbenkoala/aggbug/1029016.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42800/" target="_blank">[新闻]邮件标准协议英文独占时代终结</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>微软Ajax.SlideShowExtender控件使用详解</title><link>http://www.cnblogs.com/benbenkoala/archive/2007/12/27/1016361.html</link><dc:creator>笨笨的考拉熊</dc:creator><author>笨笨的考拉熊</author><pubDate>Thu, 27 Dec 2007 02:28:00 GMT</pubDate><guid>http://www.cnblogs.com/benbenkoala/archive/2007/12/27/1016361.html</guid><wfw:comment>http://www.cnblogs.com/benbenkoala/comments/1016361.html</wfw:comment><comments>http://www.cnblogs.com/benbenkoala/archive/2007/12/27/1016361.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.cnblogs.com/benbenkoala/comments/commentRss/1016361.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/benbenkoala/services/trackbacks/1016361.html</trackback:ping><description><![CDATA[<p>近期因为需要，用到了Ajax控件库的<font face="Courier New">SlideShowExtender控件。一开始一点不懂，所以依照惯例从baidu、google上查找，但网上的文章不是转抄微软演示网站的那几行说明文字，就是给个示例，然后说自己用这个控件做出来了轮换的功能，炫耀一番，没有一个是教别人具体的使用方法的。自己费了一周的时间，终于用<font face="Courier New">SlideShowExtender实现了自己需要的功能，想到以后可能还有像我一样的朋友，把东西写出来，方便大家。<br />
多说一句，微软的Ajax控件库有源代码，大家可以参考。我将Ajax控件库的演示网站建在了本地服务器上，一开始只想到了<br />
研究网站的演示，竟忘了还有源代码可以看，浪费了好几天的时间。<br />
<br />
<strong>一、实现图片的轮换<br />
</strong><br />
首先在网站根目录建立一个文件夹Images，存入10张jpg图片，命名为01.jpg-10.jpg。建立Demo<font face="Courier New">SlideShowExtender.aspx文件，拖拽一个<font face="Courier New">SlideShowExtender</font>控件到页面上。然后添加一个Image控件，命名为imgPicture，用于显示轮换图片，添加三个Button控件，命名为btnPrevious、btnPlay、btnNext，分别实现后退、播放/暂停、前进三个功能。<br />
</font>使用<font face="Courier New">SlideShowExtender</font>，官方说明上给出了控件的各个参数设置。但我想所有初学者最想知道的功能，是如何设置轮换图片内容的方法，但却没有给出，而是语焉不详的写了如下说明：<br />
<br />
<strong>SlideShowServiceMethod</strong> - The webservice method that will be called to supply images. The signature of the method must match this: </p>
<p>[System.Web.Services.WebMethod][System.Web.Script.Services.ScriptMethod] public AjaxControlToolkit.Slide[] GetSlides() { ... }</p>
<p>反正我是没看懂，还好有源代码可以参考，在<font face="Courier New">Demo<font face="Courier New">SlideShowExtender.aspx中</font></font>，添加一个方法GetSlides，内容如下：<font face="Courier New"></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"><img id="Codehighlighter1_38_622_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_38_622_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_38_622_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_38_622_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_38_622_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_38_622_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_38_622_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_38_622_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">script&nbsp;</span><span style="color: #ff0000">runat</span><span style="color: #0000ff">="Server"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="text/C#"</span><span style="color: #0000ff">&gt;</span><span id="Codehighlighter1_38_622_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 alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_38_622_Open_Text"><span style="color: #000000; background-color: #f5f5f5"><br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;[System.Web.Services.WebMethod]<br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;[System.Web.Script.Services.ScriptMethod]<br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;AjaxControlToolkit.Slide[]&nbsp;GetSlides()<br />
<img id="Codehighlighter1_182_621_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_182_621_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_182_621_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_182_621_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_182_621_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_182_621_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_182_621_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_182_621_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_182_621_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 alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_182_621_Open_Text"><span style="color: #000000; background-color: #f5f5f5">{<br />
<img id="Codehighlighter1_230_618_Open_Image" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_230_618_Open_Text').style.display='none'; document.getElementById('Codehighlighter1_230_618_Closed_Image').style.display='inline'; document.getElementById('Codehighlighter1_230_618_Closed_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_230_618_Closed_Image" style="display: none" onclick="this.style.display='none'; document.getElementById('Codehighlighter1_230_618_Closed_Text').style.display='none'; document.getElementById('Codehighlighter1_230_618_Open_Image').style.display='inline'; document.getElementById('Codehighlighter1_230_618_Open_Text').style.display='inline';" alt="" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; background-color: #f5f5f5">return</span><span style="color: #000000; background-color: #f5f5f5">&nbsp;</span><span style="color: #0000ff; background-color: #f5f5f5">new</span><span style="color: #000000; background-color: #f5f5f5">&nbsp;AjaxControlToolkit.Slide[]&nbsp;</span><span id="Codehighlighter1_230_618_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 alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span id="Codehighlighter1_230_618_Open_Text"><span style="color: #000000; background-color: #f5f5f5">{&nbsp;<br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; background-color: #f5f5f5">new</span><span style="color: #000000; background-color: #f5f5f5">&nbsp;AjaxControlToolkit.Slide(</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">Images/01.jpg</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片01的标题</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片01的说明</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">),<br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; background-color: #f5f5f5">new</span><span style="color: #000000; background-color: #f5f5f5">&nbsp;AjaxControlToolkit.Slide(</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">Images/02.jpg</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片02的标题</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片02的说明</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">),<br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; background-color: #f5f5f5">new</span><span style="color: #000000; background-color: #f5f5f5">&nbsp;AjaxControlToolkit.Slide(</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">Images/03.jpg</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片03的标题</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片03的说明</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">),<br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; background-color: #f5f5f5">new</span><span style="color: #000000; background-color: #f5f5f5">&nbsp;AjaxControlToolkit.Slide(</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">Images/04.jpg</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片04的标题</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片04的说明</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">),<br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; background-color: #f5f5f5">new</span><span style="color: #000000; background-color: #f5f5f5">&nbsp;AjaxControlToolkit.Slide(</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">Images/05.jpg</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片05的标题</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">,&nbsp;</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">图片05的说明</span><span style="color: #000000; background-color: #f5f5f5">"</span><span style="color: #000000; background-color: #f5f5f5">)}</span></span><span style="color: #000000; background-color: #f5f5f5">;<br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000; background-color: #f5f5f5"><br />
<img alt="" src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align="top" /></span></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">script</span><span style="color: #0000ff">&gt;</span></div>
<p></font>这个方法就指明了要轮换的图片的路径，&#8220;new AjaxControlToolkit.Slide("Images/01.jpg", "图片01的标题", "图片01的说明"),&#8221;这一条可以任意添加，需要几张图片就加几条语句。</p>
<p>然后还有几个控件参数：<br />
<font face="Courier New">&lt;cc1:SlideShowExtender ID="SlideShowExtender1" runat="server"<br />
&nbsp;&nbsp;&nbsp;&nbsp;TargetControlID="imgPicture"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //指明要对那个Image控件实现图片轮换效果<br />
&nbsp;&nbsp;&nbsp;&nbsp;SlideShowServiceMethod="GetSlides"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//上面给出的指明了轮换图片路径的方法的名称，如果你的方法不是GetSlides，而是其它名称（比如MySlidesDemo），这里也要改成对应的名称<br />
&nbsp;&nbsp;&nbsp;&nbsp;AutoPlay="true"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//是否自动播放<br />
&nbsp;&nbsp;&nbsp;&nbsp;NextButtonID="btnNext"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//点击后切换到下一张图片的按钮Id<br />
&nbsp;&nbsp;&nbsp;&nbsp;PlayButtonID="btnPlay"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//点击后切换播放/暂停状态的按钮Id<br />
&nbsp;&nbsp;&nbsp;&nbsp;PreviousButtonID="btnPrevious"&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //点击后切换到前一张图片的按钮Id<br />
&nbsp;&nbsp;&nbsp;&nbsp;PlayButtonText="play"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//处于暂停状态时播放/暂停按钮文字<br />
&nbsp;&nbsp;&nbsp; StopButtonText="stop"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //处于播放状态时播放/暂停按钮文字<br />
&nbsp;&nbsp;&nbsp;&nbsp;Loop="true"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //是否循环显示图片<br />
&nbsp;&nbsp;&nbsp;&nbsp;&gt;<br />
&lt;/cc1:SlideShowExtender&gt;<br />
<br />
好了，运行一下，看是否能显示轮换图片了。<br />
<br />
<strong>二、将代码改放到cs文件中<br />
<br />
</strong>现在代码是在aspx文件中，与html掺杂在一起，感觉很不爽，把它改放到cs中吧。<br />
<br />
在设计视图中，点击<font face="Courier New">SlideShowExtender</font>控件，出现<font face="Courier New">SlideShowExtender</font> Task列表，选择唯一的一项&#8220;Add SlideShow page method&#8221;。<br />
<br />
SlideShowExtender控件属性中会多出一项&#8220;<fon