<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_陈希章@中国</title><subtitle type="text">:: 心有多宽，路就有多宽 :: | ::http://tech.xizhang.com ::  Microsoft .NET开发人员职业规划和学习路线图:: | ::架构师访谈</subtitle><id>http://feed.cnblogs.com/blog/u/12626/rss</id><updated>2012-02-04T09:08:13Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/12626/rss"/><entry><id>http://www.cnblogs.com/chenxizhang/archive/2012/02/04/2338115.html</id><title type="text">Office 插件开发和部署的总结</title><summary type="text">近日因为开发一个Outlook插件，用到了最新的Visual Studio开发工具，期间费了不少周折，主要体现在部署上面。这里整理一下给大家参考参考 1. 选择合适的模板，Visual Studio ...</summary><published>2012-02-04T09:08:00Z</published><updated>2012-02-04T09:08:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2012/02/04/2338115.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2012/02/04/2338115.html"/><content type="html">&lt;p&gt;近日因为开发一个Outlook插件，用到了最新的Visual Studio开发工具，期间费了不少周折，主要体现在部署上面。这里整理一下给大家参考参考&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. 选择合适的模板，Visual Studio 2010中支持对Office 2007和Office 2010开发两种解决方案&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;一种是所谓的插件，一种是所谓的文档。其实也很好理解，插件是指通用的功能，例如你可以给Outlook添加一个特殊的工具栏，文档则是某个特殊的Office文档吧，可以实现特定的功能，例如你可以设计一个特殊的Word文档。&lt;/p&gt; &lt;p&gt;值得注意的是，不支持Office 2003的开发。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201202/201202041708025379.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201202/201202041708036034.png" width="244" height="170"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;经过测试，如果你做的插件，是既需要用于Office 2007，又需要用于Office 2010，则你可以选择Office 2007的模板。这应该也是比较好理解的。&lt;/p&gt; &lt;p&gt;至于具体功能的开发，我这里就不展开了。大家可以参考微软的有关文档。例如&lt;/p&gt; &lt;p&gt;&lt;a title="http://msdn.microsoft.com/en-us/library/bb726434(v=office.12).aspx" href="http://msdn.microsoft.com/en-us/library/bb726434(v=office.12).aspx"&gt;http://msdn.microsoft.com/en-us/library/bb726434(v=office.12).aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;注意，我建议大家选择.NET Framework 4.0, 因为这个版本，可以将Office的那些COM组件，嵌入到插件中，这样就可以省去部署所谓的PIA （Primary Interop Assembly）的步骤。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2.测试项目&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;测试Office插件很简单，你只需要在Visual Studio 2010中对项目进行编译即可&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201202/201202041708047529.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201202/20120204170805659.png" width="644" height="203"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;正常情况下，就可以在Outlook中看到这个插件&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201202/201202041708084926.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201202/20120204170810697.png" width="1035" height="292"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;如果要删除这个插件，则只需要在Visual Studio 2010中对项目进行清理就可以了&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201202/201202041708115256.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201202/201202041708121452.png" width="964" height="226"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;3.部署项目&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;由于测试阶段是如此容易，导致很多朋友（包括我在内）想当然地觉得部署肯定也是很容易。遗憾的是，现实给了我们残酷的教训。你必须很仔细地阅读下面这篇文章&lt;/p&gt; &lt;p&gt;&lt;a title="http://msdn.microsoft.com/en-us/library/ff937654.aspx" href="http://msdn.microsoft.com/en-us/library/ff937654.aspx"&gt;http://msdn.microsoft.com/en-us/library/ff937654.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;这篇文章十分重要，请不要贪图快而略过某些步骤，我可以证明，如果按这个文章打包的安装程序，是可以安装成功的。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;要部署该项目，目标用户机器还必须具备如下的一些条件&lt;/p&gt; &lt;ul&gt; &lt;li&gt;1. 操作系统必须是Windows XP SP2或者更高版本，推荐Windows 7&lt;/li&gt; &lt;li&gt;2. 需要安装Office 2007或者Office 2010 &lt;/li&gt; &lt;ul&gt; &lt;li&gt;这里要注意，必须为Office 2007或者Office 2010安装“.NET编程性支持”这个功能。更加需要注意的是，要安装这项功能，需要先装好.NET Framework 2.0。对于这一点，我实在也感到很意外，但没有办法，这是先决条件。不过，好消息是：&lt;/li&gt; &lt;ul&gt; &lt;li&gt;正常情况下，Windows XP如果启用了自动更新的话，应该已经装好了.NET Framework 2.0&lt;/li&gt; &lt;li&gt;默认情况下，Windows 7是自带了.NET Framework 2.0&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt; &lt;li&gt;3. 需要安装.NET Framework 4.0 Client Profile或者.NET Framework 4.0&lt;/li&gt; &lt;ul&gt; &lt;li&gt;下载地址 &lt;a href="http://go.microsoft.com/fwlink/?LinkId=195254"&gt;http://go.microsoft.com/fwlink/?LinkId=195254&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;4. 需要安装Visual Studio 2010 Tools for Office Runtime&lt;/li&gt; &lt;ul&gt; &lt;li&gt;下载地址 &lt;a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=20479"&gt;http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=20479&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt; &lt;p&gt;&lt;/p&gt;    &lt;p&gt;以上整理给有需要的朋友参考参考&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2338115.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2012/02/04/2338115.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2012/01/01/2309600.html</id><title type="text">《如何成为卓越的大学教师》的阅读笔记及感想 （一）</title><summary type="text">这本书是由哈佛大学出版的，然后北京大学出版社引进翻译了中文版，年前我听到介绍然后购买的。今天看了一部分，总的评价是非常不错，很值得所有大学教师参考学习，当然也很适合于我等有志青年，作为研究学习...</summary><published>2012-01-01T12:36:00Z</published><updated>2012-01-01T12:36:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2012/01/01/2309600.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2012/01/01/2309600.html"/><content type="html">&lt;p&gt;&lt;/p&gt; &lt;p&gt;这本书是由哈佛大学出版的，然后北京大学出版社引进翻译了中文版，年前我听到介绍然后购买的。今天看了一部分，&lt;font color="#ff0000"&gt;&lt;strong&gt;总的评价是非常不错，很值得所有大学教师参考学习，当然也很适合于我等有志青年，作为研究学习之用。&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201201/201201012035362551.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="20051230-1_e" border="0" alt="20051230-1_e" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201201/201201012035363947.jpg" width="244" height="244"&gt;&lt;/a&gt;&lt;br&gt;&lt;/strong&gt;&lt;/font&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;a name="abstract"&gt;&lt;/a&gt;&lt;a name="content"&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;内容简介&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;本书是对不同大学和各个学科近百位卓越教师长达15年观察研究的总结。透过一个个生动的故事，本书为我们描绘了精彩教学的典范，举出了学生展现创意和发掘自己潜能的实例，揭示了卓越教师对学生产生持久积极影响的秘密。作者强调：卓越的教学是可以学习的。&lt;br&gt;本书不但是新、老教师增长见识和激发灵感的宝藏，而且对于有志成为大学教师的青年学生&lt;br&gt;也是绝好的参考书，同时本书所得出的结论也应该是广大学生及其家长的兴趣所在。  &lt;p&gt;&lt;a name="authorintro"&gt;&lt;/a&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;作者简介&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;肯·贝恩(Ken Bain)是美国影响较大的四个教学中心，即纽约大学优秀教学中心、西北大学瑟尔精英教学中心、范德比尔特大学教学中心和蒙特克莱尔新泽西州立大学教学资源中心的创始人，现为蒙特克莱尔新泽西州立大学教学资源中心主任，在教学研究方面有着丰富的理论和实践经验，曾获得多项全美教学奖，被誉为美国最好的老师之一。  &lt;p&gt;&lt;p&gt;值得推荐的是，来自微软亚洲研究院的邹欣老师，前两天发表了一篇读后感，总结得相当好， &lt;a title="http://www.cnblogs.com/xinz/archive/2011/12/29/2306652.html" href="http://www.cnblogs.com/xinz/archive/2011/12/29/2306652.html"&gt;http://www.cnblogs.com/xinz/archive/2011/12/29/2306652.html&lt;/a&gt; ，邹老师从美国总部回来后，这几年在几所重点大学里面参与教育方面的实践，主要讲授软件工程方面的内容，有兴趣的朋友可以关注他的&lt;a href="http://www.cnblogs.com/xinz/"&gt;博客&lt;/a&gt;。  &lt;p&gt;&lt;p&gt;本书的开篇第一章，谈到了为什么写这本书，以及如何定义“卓越”，并且高屋建瓴地给出了几个不算结论的结论。我这里做些笔记，并且在此基础上也谈谈我的一些感想。即便你没有时间看完整本书，我想通过下面几点，你也大致能对这本书要表达的主体思想略知一二了。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;一：最优秀的教师知道什么，了解什么？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;毫无疑问，人们必须懂得所教的知识才有可能成为优秀的老师。但这还只是一个必要前提，优秀的老师还应该擅长应用自己的知识来开发各种技能，以掌握基本原理和组织各种概念，目的是为了使别人能够使用这些原理和概念去构筑他们自己的理解和能力。他们认为，如果学对人们的思想、行为和感觉方式不能产生持久的实质性的影响，那么学习将毫无意义可言。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;二：他们如何为教学做准备？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;卓越的老师把讲课、讨论、解决问题和其他各种教学要素视作严肃的智力上的努力，这种努力如同他们做研究、搞学术所付出的努力一样要求苛刻和意义重大。为一堂课做准备，包括设计更有意义的提问，并且设计讲稿、讨论基于可能遭遇的问题。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;三：他们对学生的期望是什么？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;总体而言，卓越的老师对学生的期望自然是更加高的。他们不会满足于学生仅仅是考试及格，或者哪怕是拿到了高分，而是喜欢那些贴近生活的思想和行为的目标。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;四：他们如何教学？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;他们将试图营造一个“自然的批判性的学习环境”，这这样的环境中，学生解决有趣的、巧妙的或者重要的问题，完成激励他们去努力掌握概念的真实任务，通过这样的方式来学习，反思他们的假设，研究他们针对现实的思维模式。学习者对自己的学习有一种控制感，他们同别人协同工作，并且相信他们的努力会得到公正和诚实的评判；他们可以不断尝试、失败并且接受有经验的学习者的反馈意见，然后获得他们的努力所作出的累积性评价。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;五：他们如何对待学生？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;他们通常认为学生渴望学习，而且，如果没有相反的证据，他们认为学生有能力学习。他们对学生坦诚以待，并且倾向于非常大方得体地对待学生。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;六：他们如何检查自己的进步和评价自己的努力？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;他们不是完美的人，但他们的优秀在于他们能认识到自己的不完美，并且能有一套方法评估自己的努力并做出适当地调整。同时，他们从不因为自己所面对的困难而责备学生，最后，他们通常对学术界有一种强烈的责任感，而不只是关注于在课堂上的个人成功。  &lt;p&gt;&lt;p&gt;上面这些大多直接来自原文，我摘录整理了一下。但在此基础上，我也结合我的一些经历，谈谈一些个人的见解和感想  &lt;p&gt;&lt;p&gt;这是我读过的第一本专门地、系统地论述如何教学的书籍，而且本书可贵之处在于不是教条式地讲理论，花了15年时间时间观察研究才写出这样的书，其所传达的意义与本书所要倡议的精神是不谋而合的：教育是一个严肃的话题，而论述教育更为严肃。优秀是可以通过培养得到的，这需要时间，并且这份坚持需要深层次的文化思想的支撑。  &lt;p&gt;&lt;p&gt;我会读这本书虽然因为机缘巧合，但也却非纯属偶然。生活中总是这样的，你其实会不断地寻找一些东西，也许一下子没有寻找到，但因为你一直在寻找，然后在某个时候你就会遇到，然后你就会说：哦，原来在这里呀。这不仅仅是一个比喻，我的意思是说，人都会关注一些自己感兴趣的东西，而且这种关注将引导你朝着这个方向前进。从这个意义上说，我们每个人都需要时常思考，你关注什么，因为你很可能会决定你最终会成为什么。  &lt;p&gt;&lt;p&gt;我并不是大学教师，虽然从业以来有一段与大学的短暂的合作，但我这些年来主要工作还是直接服务于一些企业，我是从06年开始开始了我作为讲师的一段旅程吧。这些年以来，讲师都是我的身份之一。算起来，我也去过不少地方，接触过各类企业，总体而言，我虽然谈不上是最好的讲师，甚至连最好的之一都谈不上，但表现也算中规中矩吧。我给自己的评分是80分左右吧。  &lt;p&gt;&lt;p&gt;接触过我的朋友大致都知道，我自己对教育方面有些小小的想法。在这样的前提，以及我对自己也不十分满意的背景下，就不难理解我为什么会对这本书有相见恨晚的感慨了。我一直也在想，有没有办法学习到一些较为系统的教学方面的方法，或者如何改进自己的一些讲课方面的不足。  &lt;p&gt;&lt;p&gt;我08年～09年左右有一段与某软件学院的短暂合作，期间也体会到我们教育体制的一些常见问题。这方面，我想等后面我的看法更加成熟的时候，再谈谈吧。这是一个大的话题，这些年来我发现越来越多的人开始关注教育，这是一个可喜的事情，有人去努力，总是会有些积极变化的。我也由衷地希望更多的力量投入到教育事业上去，而且真的要有责任感和使命感，并且注意提高教学的水平。  &lt;p&gt;&lt;p&gt;我先谈谈我在企业做培训的一些感想。我这里只能称之为“培训”，因为在企业内部做的这种课程，与在大学里面讲课还是有很大区别的。&lt;/p&gt; &lt;p&gt;首先，目的性不太一样。企业培训的目的性更加有针对性，我总结分析过一般是三大类的情况&lt;/p&gt; &lt;ol&gt; &lt;li&gt;新员工入职之后的培训（侧重于讲解核心的技术，帮助新员工快速开展工作）  &lt;li&gt;企业对于员工的梯队式培养（侧重于针对不同级别，设计不同的课程，单独学习）  &lt;li&gt;对于某些疑难问题的专题学习（例如性能调优，或者排错之类，往往是有些特定的问题）&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;其次，受众的情况不太一样。一般而言，企业培训的受众都是有一定工作经验基础的，经验有时候是好事，有时候也是坏事。所以，针对企业员工的培训课程，有时候很好讲，但反之亦然。&lt;/p&gt;  &lt;p&gt;最后，授课的条件不太一样。企业的培训，通常时间是较为短期的，通常每次最多也就是2～3天，并且大家要知道，企业培训一般一讲就是一整天（6小时甚至以上），智力劳动之外，也是一个体力劳动。在这么一个短而且集中的时间内，首先相互也需要有一个熟悉的过程，并且最起码要完成一定的培训目标，如果能做到较为圆满，则是相对不易的。值得一提的是，有的企业在安排课程的时候，出于一些考虑，会要求压缩时间，这个时候，我也会提醒他们要根据自己的情况，不要盲目地压缩，效果肯定是不好的。&lt;/p&gt;  &lt;p&gt;我还要谈一谈，由于所处的行业，决定了我所做的培训在一般的企业培训的基础上，又有一些特殊性：我们所处的IT行业，或者有的人说的计算机行业，其实一般又分为两个领域：研究和应用。我们大部分人现在做的是应用方面这个领域。&lt;/p&gt; &lt;p&gt;【备注】如何理解研究和应用，可以给大家举个形象一点的例子，以我对微软的粗浅了解，他们在亚洲有研究院和工程院，研究院就是倾向于研究的，他们目前所研究的技术，可能会在多年后有用（当然，也可能没有用），工程院则侧重于将现有技术转化为微软的一些具体的产品中。&lt;/p&gt;  &lt;p&gt;应用这个领域有什么特点呢？我想最简单的总结就是：技术繁多，而且更新换代很快。技术多，且更新快，这将对这个领域的讲师本身来说是一个很大的挑战，如果你不能将对有关的课题的理解提升到一定的高度，那么你自己要学会这些尚且不易，何况乎要去跟别人讲课呢？&lt;/p&gt;  &lt;p&gt;经常也有朋友对我提出这样的问题，如何成为一个合格的讲师？问我这话的朋友，大抵首先是对我讲课还比较满意，觉得这样讲一讲也挺轻松似的。我当然首先首先因为得到认可而感到很开心，但还是会实事求是地说，其实我每次讲课也是如履薄冰，生怕出洋相，往往准备也要很长时间。总体而言，我觉得首要的一点，就是还是要有这份心，并且以此要求自己做好这份工作。&lt;/p&gt;  &lt;p&gt;所以，由于这种工作的关系，加上我自己对教育比较兴趣。所以这些年的一些思考，虽然主要在于如何将企业培训的价值做得更加好一些，归根结底是想探索一些教育方面的方法。这本书所提到的一些大的方面的思想，有的我也想到一些，但没有具体化。我相信读这本书必然对我有所助益，并且也希望籍此推荐给更多的有兴趣的朋友。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1. 教育是有意义的事情。&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;不管你是在学校，还是在其他相关的领域，如果你从事教学方面的工作，那么就尽量做好它，帮助到更多的人，同时也帮助你得到提升。我自己的最大收获，也就是在教学相长中有很大的进步。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2. 要有恰当、并且行之有效的方法来提高教学质量&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;要做好这件事情，与其他任何事情一样，光有热情还是不够的，还得有方法。要了解受众的需要，但也不失正确的引导。了解受众的需要，称之为因材施教，因势利导；而所谓不失正确的引导，是因为身为教育者，需要有一定程度上的权威性和原则性，该要求就要求，这也是教育的意义所在。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3. 培养思考的能力比传递具体的知识更重要&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;古话说的好“授人以鱼，不若授之以渔”，我也很赞同这一点。我感觉这方面还需要多多实践。主体思想就是，不要照本宣科地讲，一定要有自己的见解，并且要提出问题，给予一些空间和时间，让学习者参与进来。&lt;/p&gt;  &lt;p&gt;以上算是我的一些笔记和感想，后续还会写一点&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2309600.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2012/01/01/2309600.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2011/12/20/2295118.html</id><title type="text">关于网站应用程序池的帐号密码更改及其影响的实例分析</title><summary type="text">这个标题看起来有点绕，但其实是一个常见的问题，而且很多朋友对此的理解都不深。我这里用一个例子来解释一下 实例场景 我们有一个网站（名称为test),它使用了一个应用程序池(名称也为test) 这...</summary><published>2011-12-20T12:31:00Z</published><updated>2011-12-20T12:31:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/20/2295118.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/20/2295118.html"/><content type="html">&lt;p&gt;这个标题看起来有点绕，但其实是一个常见的问题，而且很多朋友对此的理解都不深。我这里用一个例子来解释一下&lt;/p&gt; &lt;p&gt;&lt;strong&gt;实例场景&lt;/strong&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;我们有一个网站（名称为test),它使用了一个应用程序池(名称也为test)&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202030464929.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202030488716.png" width="454" height="554"&gt;&lt;/a&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;这个应用程序池所使用的用户帐号为app_pool_test&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202030507278.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202030545199.png" width="454" height="554"&gt;&lt;/a&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;这个帐号当前的密码,假设为 abc 。当我设置好之后，我可以正常打开网站&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202030559475.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202030561526.png" width="595" height="141"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;这个演示页面的功能很简单，我是使用下面的代码去访问了一下数据库&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.UI;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.UI.WebControls;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Data.SqlClient;&#xD;
&lt;span &gt;namespace&lt;/span&gt; WebApplication1&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;partial&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; _default : System.Web.UI.Page&#xD;
    {&#xD;
        &lt;span &gt;protected&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Page_Load(&lt;span &gt;object&lt;/span&gt; sender, EventArgs e)&#xD;
        {&#xD;
            &lt;span &gt;using&lt;/span&gt;(var conn = &lt;span &gt;new&lt;/span&gt; SqlConnection(&lt;span &gt;"server=(local)\\sqlexpress;database=northwind;integrated security=true"&lt;/span&gt;))&#xD;
            {&#xD;
                conn.Open();&#xD;
                Response.Write(conn.State.ToString());&#xD;
            }&#xD;
        }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;请注意，这里我并没有指定用户名和密码，而是使用了integrated security=true。这通常称为“信任连接”或者“集成验证”。这个问题，我下面还会解释。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;大家可以看到，网站能正常工作。功能没有什么了不起的，这是一个简单的演示而已。但是下面大家思考一个问题：&lt;/p&gt;&#xD;
&lt;p&gt;假设app_pool_test 这个帐号的密码因为什么原因需要修改（这个很正常，很多公司都有密码修改策略的），那么&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;1.网站还是否能正常打开？&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;2.数据库还是否能访问？&lt;/font&gt;&lt;/p&gt;&#xD;
&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我这里就做一个测试，我现在将帐号的密码修改掉&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202030586675.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202030592380.png" width="398" height="260"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;奇怪的是，我们会发现网站照样能打开，数据库居然也照样能访问得上。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031006382.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031017038.png" width="595" height="141"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;首先，这里你应该会有一个疑问：这是为什么呢？难道改了密码没有生效吗？到底什么时候会生效呢？&lt;/p&gt;&#xD;
&lt;p&gt;我们接下去做实验。假使当前这个服务器，因为某种原因（例如安装补丁包），需要重新启动。或者你自己因为某个原因，需要对IIS进行重启，例如执行了下面的命令&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031038108.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031041828.png" width="681" height="446"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;然后，我们再次尝试打开刚才那个网页，就会发现如下的错误&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031067566.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031073554.png" width="759" height="310"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;一般而言，503错误都是表示后台的Application Pool存在问题，我们到IIS中查看，确实发现它被停止了&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031097830.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031105487.png" width="805" height="159"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;而且你还会发现，无论你如何启动，只要页面刷新一下，它就又停止了。&lt;/p&gt;&#xD;
&lt;p&gt;除非，你再次在它这里将正确的用户名和密码设置一次。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031128227.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031148915.png" width="457" height="551"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;然后，你会发现网站能正常工作了&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031157934.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112202031169462.png" width="595" height="141"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我希望你看懂了我想要描述的一个问题：&lt;font color="#ff0000"&gt;&lt;strong&gt;当网站的应用程序池帐号密码被修改之后，将如何影响到当前的网站。&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;先将结论给大家说一下&lt;/p&gt;&#xD;
&lt;p&gt;1. 如果当前的网站，没有被重置。我测试下来是，只要IIS没有被重启过，或者应用程序池没有被停止过，就可以继续使用。&lt;/p&gt;&#xD;
&lt;p&gt;2. 否则，当前网站会无法正常工作，而且应用程序池再也无法启动，除非设置正确的密码。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;那么，这是为什么呢？&lt;/p&gt;&#xD;
&lt;p&gt;1. IIS启动的时候，默认会启动所有的应用程序池，并且使用它们的标识和密码，去请求windows系统（可能是本机，也可能是AD)进行认证&lt;/p&gt;&#xD;
&lt;p&gt;2. 只要认证通过了，那么应用程序池将启动，而且这个身份会被缓存起来。&lt;/p&gt;&#xD;
&lt;p&gt;3. 一般的应用程序，要访问后台数据库的时候，如果选择了“集成验证(integrated security=true)”这种方式的话，那么就是使用应用程序池的这个身份。&lt;/p&gt;&#xD;
&lt;p&gt;4. “集成验证”有时候也称为信任连接，这是什么意思呢？就是说SQL Server其实不再对帐号和密码进行验证，它“信任”windows传递过来的身份，也就是说，只要上面的第2步通过了，确实帐号是app_pool_test，那么SQL Server就认为它是app_pool_test,而不再重复验证密码。&lt;/p&gt;&#xD;
&lt;p&gt;5. 当IIS被重启，或者应用程序池被重启，此时就需要再次验证身份。而如果此时发现密码不匹配了，就自然无法启动应用程序池，然后也自然无法启动网站，然后也不会发生访问数据库的行为。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在做应用程序部署的时候，你会遇到很多复杂甚至棘手的情况，这篇文章就描述了其中一种常见的状况：&lt;/p&gt;&#xD;
&lt;p&gt;应用程序池的帐号密码修改之后（其实，很多时候，作为开发人员的角度，你可能不知道密码已经被修改了），所以你可能会发现一些“诡异”的现象，例如刚刚还能正常使用的程序，突然又不能使用了。理解本文，将有助于你解释这样的状况，以及了解如何解决。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2295118.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/12/20/2295118.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2011/12/18/2291658.html</id><title type="text">关于SharePoint 2010体系架构的几个话题</title><summary type="text">最近给一个客户讲解SharePoint体系架构、管理维护这方面的内容。有几个主要问题整理出来给大家参考参考。陆续会有几篇文章 1.SharePoint到底是怎么工作的？ 这个问题要从“SharePo...</summary><published>2011-12-18T03:13:00Z</published><updated>2011-12-18T03:13:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/18/2291658.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/18/2291658.html"/><content type="html">&lt;p&gt;最近给一个客户讲解SharePoint体系架构、管理维护这方面的内容。有几个主要问题整理出来给大家参考参考。陆续会有几篇文章&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1.SharePoint到底是怎么工作的？&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;这个问题要从“SharePoint是什么”说起。SharePoint其实说到底是一个基于ASP.NET的应用平台。它的主体部分是通过一个用户所熟知的网站提供服务的，此为其一。&lt;/p&gt; &lt;p&gt;接下来，我们就要问了，作为一个网站而言，SharePoint的网站与一般的网站是否有什么不一样呢？答案是，有。SharePoint的网站虽然在IIS里面看起来与一般的网站并不什么两样（如下图），但是其实内部有很大的区别。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113027032.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113027065.png" width="387" height="365"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;SharePoint的网站，注册了一些特殊的HttpModule和HttpHandler，熟悉ASP.NET开发的朋友们都知道，这是ASP.NET中高级定制的两个重要手段。简单来说，SharePoint通过这些自定义的Module(模块）接管了用户的请求，从根本上实现了动态网页处理的功能。（下一个话题还会介绍一下动态网页的概念）&lt;/p&gt; &lt;p&gt;这些Module或者Handler的定义，默认如下（你可以在网站的web.config）找到它们&lt;/p&gt;&lt;pre &gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;system.webServer&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;security&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;requestFiltering&lt;/span&gt; &lt;span &gt;allowDoubleEscaping&lt;/span&gt;&lt;span &gt;="true"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;requestLimits&lt;/span&gt; &lt;span &gt;maxAllowedContentLength&lt;/span&gt;&lt;span &gt;="2147483647"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;requestFiltering&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;security&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;validation&lt;/span&gt; &lt;span &gt;validateIntegratedModeConfiguration&lt;/span&gt;&lt;span &gt;="false"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;modules&lt;/span&gt; &lt;span &gt;runAllManagedModulesForAllRequests&lt;/span&gt;&lt;span &gt;="true"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="AnonymousIdentification"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="FileAuthorization"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="Profile"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="WebDAVModule"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="Session"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="SPRequestModule"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="Microsoft.SharePoint.ApplicationRuntime.SPRequestModule, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="ScriptModule"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="SharePoint14Module"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="StateServiceModule"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="Microsoft.Office.Server.Administration.StateModule, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="PublishingHttpModule"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="Microsoft.SharePoint.Publishing.PublishingHttpModule, Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;modules&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;handlers&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="OPTIONSVerbHandler"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="WebServiceHandlerFactory-Integrated"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="svc-Integrated"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;remove&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="WebDAV"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="svc-Integrated"&lt;/span&gt; &lt;span &gt;path&lt;/span&gt;&lt;span &gt;="*.svc"&lt;/span&gt; &lt;span &gt;verb&lt;/span&gt;&lt;span &gt;="*"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="OwssvrHandler"&lt;/span&gt; &lt;span &gt;scriptProcessor&lt;/span&gt;&lt;span &gt;="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\isapi\owssvr.dll"&lt;/span&gt; &lt;span &gt;path&lt;/span&gt;&lt;span &gt;="/_vti_bin/owssvr.dll"&lt;/span&gt; &lt;span &gt;verb&lt;/span&gt;&lt;span &gt;="*"&lt;/span&gt; &lt;span &gt;modules&lt;/span&gt;&lt;span &gt;="IsapiModule"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="ScriptHandlerFactory"&lt;/span&gt; &lt;span &gt;verb&lt;/span&gt;&lt;span &gt;="*"&lt;/span&gt; &lt;span &gt;path&lt;/span&gt;&lt;span &gt;="*.asmx"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="ScriptHandlerFactoryAppServices"&lt;/span&gt; &lt;span &gt;verb&lt;/span&gt;&lt;span &gt;="*"&lt;/span&gt; &lt;span &gt;path&lt;/span&gt;&lt;span &gt;="*_AppService.axd"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="ScriptResource"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;verb&lt;/span&gt;&lt;span &gt;="GET,HEAD"&lt;/span&gt; &lt;span &gt;path&lt;/span&gt;&lt;span &gt;="ScriptResource.axd"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="JSONHandlerFactory"&lt;/span&gt; &lt;span &gt;path&lt;/span&gt;&lt;span &gt;="*.json"&lt;/span&gt; &lt;span &gt;verb&lt;/span&gt;&lt;span &gt;="*"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/span&gt; &lt;span &gt;resourceType&lt;/span&gt;&lt;span &gt;="Unspecified"&lt;/span&gt; &lt;span &gt;preCondition&lt;/span&gt;&lt;span &gt;="integratedMode"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="ReportViewerWebControl"&lt;/span&gt; &lt;span &gt;verb&lt;/span&gt;&lt;span &gt;="*"&lt;/span&gt; &lt;span &gt;path&lt;/span&gt;&lt;span &gt;="Reserved.ReportViewerWebControl.axd"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;handlers&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
  &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;system.webServer&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;需要注意的是，SharePoint 2010是基于IIS 7的，默认情况下，它采用的管道模型是“集成（integratedMode）”，所以这些Module和Handler是注册在system.webServer下面的。&lt;/p&gt;&#xD;
&lt;p&gt;关于IIS 7的管道模型，如果你有兴趣，可以参考 &lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/06/19/2084579.html"&gt;如何理解IIS 7的两种应用程序池的管道模式（Managed Pipeline Mode)&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2. SharePoint的网页在磁盘上有没有？&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;接下来一个话题就是，SharePoint的网页到底在哪里？是在磁盘中，还是在数据库中？&lt;/p&gt;&#xD;
&lt;p&gt;这个问题的答案是：有的是在磁盘上，有的是在数据库里面。有时候在磁盘上，有时候在数据库里面。&lt;/p&gt;&#xD;
&lt;p&gt;听起来有点玄，对吧，其实也不难理解的，且听我解释&lt;/p&gt;&#xD;
&lt;p&gt;首先讲，&lt;font color="#ff0000"&gt;有的是在磁盘上，有的是在数据库里面。&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我想大部分人开始了解SharePoint的时候，都知道它是一个网站,我们一般会通过如下的地址去访问它，假设当前这个webapplication就是在我的本地服务器，而且是在80端口的&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://chenxizhang-pc/" href="http://chenxizhang-pc/"&gt;http://chenxizhang-pc/&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在sharepoint 2010中，默认情况下，这个地址会被重定向到&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://chenxizhang-pc/SitePages/Home.aspx" href="http://chenxizhang-pc/SitePages/Home.aspx"&gt;http://chenxizhang-pc/SitePages/Home.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这是自动的行为，我们先来看一下它到底是怎么样的&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113025670.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113029606.png" width="923" height="538"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这是我们熟悉的一个页面。很多朋友就好奇了，那么这个Home.aspx是在哪里的呢？这个页面（本质上是一个wiki页面），是在数据库里面的。为什么呢？它其实是定义在一个文档库中的&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113031035.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113035736.png" width="918" height="383"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个页面是由当前这个Site Template自动提供的，SharePoint 2010 默认情况下会使用wiki页面作为首页。wiki页面的好处编辑很方便。这是我们都是知道的。&lt;/p&gt;&#xD;
&lt;p&gt;如果我们需要添加其他页面，你有两种选择：wiki页面和web part页面（之前的SharePoint 2007的默认页面结构）。需要注意的是，这两个页面都是放在数据库里面的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113033576.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113038593.png" width="1018" height="342"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;同时，SharePoint允许我们将其中任何一个页面设置为主页&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113031657.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113048310.png" width="810" height="253"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;所以，总结一下，这一类页面，属于是用户定制出来的，自然是要放在数据库里面的。&lt;/p&gt;&#xD;
&lt;p&gt;那么，那些页面是不放在数据库里面的呢？&lt;/p&gt;&#xD;
&lt;p&gt;下面这个页面，default.aspx，默认就不放在数据库里面，而是会读取到本地磁盘上，网站模板中的文件&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113041690.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/20111218111304295.png" width="815" height="297"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个文件，默认是由网站模板提供的，如下图&lt;/p&gt;&#xD;
&lt;p&gt;C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\SiteTemplates\sts&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113041723.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113048376.png" width="870" height="291"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;同时，默认情况下，所有列表的新建，编辑，显示页面，都是读取本地磁盘的文件，而不读取数据库。&lt;/p&gt;&#xD;
&lt;p&gt;C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\SiteTemplates\SPSSITES\LISTS\SITESLST&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113045901.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113057329.png" width="635" height="370"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这是第二大类页面，他们属于网站默认就应该有的，默认情况下，这些文件无需读取数据库，直接使用本地模板就可以了。【请注意，我说的是默认情况下，不需要读取数据库】&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;还有第三类页面，例如网站配置页面&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://chenxizhang-pc/_layouts/settings.aspx" href="http://chenxizhang-pc/_layouts/settings.aspx"&gt;http://chenxizhang-pc/_layouts/settings.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这种页面永远读取本地文件，而且这种页面，我们有个专业术语，叫做Application Page。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/20111218111305394.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113059871.png" width="861" height="684"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个页面对应的文件位置在&lt;/p&gt;&#xD;
&lt;p&gt;C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/20111218111306526.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113075052.png" width="704" height="725"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;有时候，我们也会为SharePoint定制一些解决方案，也许也会用到一些页面，那么这些页面其实也是要部署到这个目录里面来。也就是说，Application Page永远都是使用本地文件的。&lt;/p&gt;&#xD;
&lt;p&gt;所以，总结起来，SharePoint中有三种页面，他们分别对应的位置如下&lt;/p&gt;&#xD;
&lt;table style="color: #000000" border="1" cellspacing="0" cellpadding="2" width="731"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="449"&gt;页面类型&lt;/td&gt;&#xD;
&lt;td valign="top" width="280"&gt;位置&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="449"&gt;wiki页面，和webpart页面（有时候称为内容页）&lt;/td&gt;&#xD;
&lt;td valign="top" width="280"&gt;数据库&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="449"&gt;default.aspx或者列表所用的页面&lt;/td&gt;&#xD;
&lt;td valign="top" width="280"&gt;默认在磁盘，可能在数据库（下面会解释这个问题）&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="449"&gt;应用程序页面&lt;/td&gt;&#xD;
&lt;td valign="top" width="280"&gt;磁盘&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;那么，为什么说default.aspx或者列表所用的页面有时候在磁盘上，有时候在数据库里面呢？&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这些页面，默认读取磁盘的用意很明显，就是说尽量减少对数据库的读写。大家可以试想一下，假设你有100个网站，里面有N个列表，如果为每个列表都产生上面所提到的11个页面，放在数据库里面，那将是多少页面。如果列表页面不需要特别定制，为什么不可以使用一个页面，而且就使用本地这个文件呢？&lt;/p&gt;&#xD;
&lt;p&gt;所以，如果说这些页面，不需要经过定制的话，读取磁盘上的文件是最佳的做法。&lt;/p&gt;&#xD;
&lt;p&gt;但是，如果这些页面，需要经过定制，形成当前网站的独特设计，再读取磁盘上的文件就不合适了，此时该文件就会被复制一份，放在该网站所对应的内容数据库里面去。而SharePoint的引擎，要处理某个页面请求的时候，会先检查数据库中是否有该页面，如果没有，则尝试读取本地磁盘。&lt;/p&gt;&#xD;
&lt;p&gt;有意思的是，为了以示区分，经过定制的页面，在SharePoint Designer中看到的效果有点特殊。页面前面会有一个图标&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113076481.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112181113078673.png" width="572" height="165"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在微软官方文档中，这些没有定制过的页面，有一个叫法为“ghosting page”，而经过定制的页面，叫为“unghosted page”&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这一篇先谈这两个话题吧，希望大家可以对sharepoint的体系结构有更加深入的理解&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2291658.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/12/18/2291658.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2011/12/14/2288062.html</id><title type="text">谈谈MVC项目中的缓存功能设计的相关问题</title><summary type="text">今天这一篇文章我来谈一谈在MVC 3项目中的缓存功能，以及针对缓存的一些设计上的考量，给大家参考参考 前言 为什么需要讨论缓存？缓存是一个中大型系统所必须考虑的问题。为了避免每次请求都去访问后台的资源...</summary><published>2011-12-14T13:01:00Z</published><updated>2011-12-14T13:01:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/14/2288062.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/14/2288062.html"/><content type="html">&lt;p&gt;今天这一篇文章我来谈一谈在MVC 3项目中的缓存功能，以及针对缓存的一些设计上的考量，给大家参考参考&lt;/p&gt; &lt;p&gt;&lt;strong&gt;前言&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;为什么需要讨论缓存？缓存是一个中大型系统所必须考虑的问题。为了避免每次请求都去访问后台的资源（例如数据库），我们一般会考虑将一些更新不是很频繁的，可以重用的数据，通过一定的方式临时地保存起来，后续的请求根据情况可以直接访问这些保存起来的数据。这种机制就是所谓的缓存机制。&lt;/p&gt; &lt;p&gt;根据缓存的位置不同，可以区分为：&lt;/p&gt; &lt;ol&gt; &lt;li&gt;客户端缓存（缓存在用户的客户端，例如浏览器中）&lt;/li&gt; &lt;li&gt;服务器缓存（缓存在服务器中，可以缓存在内存中，也可以缓存在文件里，并且还可以进一步地区分为本地缓存和分布式缓存两种）&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;应该说，缓存的设计是一门较为复杂的学问，主要考虑的问题包括&lt;/p&gt; &lt;ol&gt; &lt;li&gt;要不要缓存？&lt;/li&gt; &lt;li&gt;要缓存哪些数据？&lt;/li&gt; &lt;li&gt;要缓存多少数据？&lt;/li&gt; &lt;li&gt;要缓存多久？&lt;/li&gt; &lt;li&gt;如何更新缓存（手动还是自动）&lt;/li&gt; &lt;li&gt;将缓存放在哪里？&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;本文将以较为通俗易懂的方式，来看一看在MVC3的项目中，如何使用缓存功能。对于上述提到的一些具体业务问题，我这里不会进行太过深入地探讨。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;MVC3中的缓存功能&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ASP.NET MVC3 继承了ASP.NET的优良传统，内置提供了缓存功能支持。主要表现为如下几个方面&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;可以直接在Controller，Action或者ChildAction上面定义输出缓存（这个做法相当于原先的页面缓存和控件缓存功能）&lt;/p&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;支持通过CacheProfile的方式，灵活定义缓存的设置（新功能）&lt;/p&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;支持缓存依赖，以便当外部资源发生变化时得到通知，并且更新缓存&lt;/p&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;支持使用缓存API，还支持一些第三方的缓存方案（例如分布式缓存）&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;那么，下面我们就逐一来了解一下吧&lt;/p&gt; &lt;p&gt;&lt;strong&gt;0.范例准备&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;我准备了一个空白的MVC 3项目，里面创建好了一个Model类型：Employee&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationCacheSample.Models&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Employee&#xD;
    {&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;int&lt;/span&gt; ID { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; Name { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; Gender { get; set; }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;然后，我还准备了一个HomeController&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationCacheSample.Models;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationCacheSample.Controllers&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; HomeController : Controller&#xD;
    {&#xD;
        &lt;span &gt;//&lt;/span&gt;&#xD;
        &lt;span &gt;// GET: /Home/&lt;/span&gt;&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult Index()&#xD;
        {&#xD;
            &lt;span &gt;//这里目前作为演示，是直接硬编码，实际上可能是读取数据库的数据&lt;/span&gt;&#xD;
            var employees = &lt;span &gt;new&lt;/span&gt;[]{&#xD;
                &lt;span &gt;new&lt;/span&gt; Employee(){ID=1,Name=&lt;span &gt;"ares"&lt;/span&gt;,Gender=&lt;span &gt;"Male"&lt;/span&gt;}&#xD;
            };&#xD;
            &lt;span &gt;return&lt;/span&gt; View(employees);&#xD;
        }&#xD;
&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;同时，为这个Action生成了一个View&lt;/p&gt;&lt;pre &gt;@model IEnumerable&amp;lt;MvcApplicationCacheSample.Models.Employee&amp;gt;&#xD;
&#xD;
@{&#xD;
    ViewBag.Title = &lt;span &gt;"Index"&lt;/span&gt;;&#xD;
}&#xD;
&#xD;
&amp;lt;h2&amp;gt;Index&amp;lt;/h2&amp;gt;&#xD;
&#xD;
&amp;lt;p&amp;gt;&#xD;
    @Html.ActionLink(&lt;span &gt;"Create New"&lt;/span&gt;, &lt;span &gt;"Create"&lt;/span&gt;)&#xD;
&amp;lt;/p&amp;gt;&#xD;
&amp;lt;table&amp;gt;&#xD;
    &amp;lt;tr&amp;gt;&#xD;
        &amp;lt;th&amp;gt;&#xD;
            Name&#xD;
        &amp;lt;/th&amp;gt;&#xD;
        &amp;lt;th&amp;gt;&#xD;
            Gender&#xD;
        &amp;lt;/th&amp;gt;&#xD;
        &amp;lt;th&amp;gt;&amp;lt;/th&amp;gt;&#xD;
    &amp;lt;/tr&amp;gt;&#xD;
&#xD;
@&lt;span &gt;foreach&lt;/span&gt; (var item &lt;span &gt;in&lt;/span&gt; Model) {&#xD;
    &amp;lt;tr&amp;gt;&#xD;
        &amp;lt;td&amp;gt;&#xD;
            @Html.DisplayFor(modelItem =&amp;gt; item.Name)&#xD;
        &amp;lt;/td&amp;gt;&#xD;
        &amp;lt;td&amp;gt;&#xD;
            @Html.DisplayFor(modelItem =&amp;gt; item.Gender)&#xD;
        &amp;lt;/td&amp;gt;&#xD;
        &amp;lt;td&amp;gt;&#xD;
            @Html.ActionLink(&lt;span &gt;"Edit"&lt;/span&gt;, &lt;span &gt;"Edit"&lt;/span&gt;, &lt;span &gt;new&lt;/span&gt; { id=item.ID }) |&#xD;
            @Html.ActionLink(&lt;span &gt;"Details"&lt;/span&gt;, &lt;span &gt;"Details"&lt;/span&gt;, &lt;span &gt;new&lt;/span&gt; { id=item.ID }) |&#xD;
            @Html.ActionLink(&lt;span &gt;"Delete"&lt;/span&gt;, &lt;span &gt;"Delete"&lt;/span&gt;, &lt;span &gt;new&lt;/span&gt; { id=item.ID })&#xD;
        &amp;lt;/td&amp;gt;&#xD;
    &amp;lt;/tr&amp;gt;&#xD;
}&#xD;
&#xD;
&amp;lt;/table&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
所以，当前的应用程序运行起来看到的效果大致是下面这样的&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142100599925.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142100594626.png" width="578" height="310"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个例子很简单，没有太多需要解释的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.使用输出缓存&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;那么，现在我们假设这个读取员工的数据很频繁，但是数据又更新不是很频繁，我们就会想到，能不能对这部分数据进行缓存，以便减少每次执行的时间。&lt;/p&gt;&#xD;
&lt;p&gt;是的，我们可以这么做，而且也很容易做到这一点。MVC中内置了一个OutputCache的ActionFilter，我们可以将它应用在某个Action或者ChildAction上面&lt;/p&gt;&#xD;
&lt;p&gt;【备注】ChildAction是MVC3的一个新概念，本质上就是一个Action，但通常都是返回一个PartialView。通常这类Action，可以加上一个ChildActionOnly的ActionFilter以标识它只能作为Child被请求，而不能直接通过地址请求。&lt;/p&gt;&#xD;
&lt;p&gt;【备注】我们确实可以在Controller级别定义输出缓存，但我不建议这么做。缓存是要经过考虑的，而不是不管三七二十一就全部缓存起来。缓存不当所造成的问题可能比没有缓存还要大。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下面的代码启用了Index这个Action的缓存功能，我们让他缓存10秒钟。&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationCacheSample.Models;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationCacheSample.Controllers&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; HomeController : Controller&#xD;
    {&#xD;
        &lt;span &gt;//&lt;/span&gt;&#xD;
        &lt;span &gt;// GET: /Home/&lt;/span&gt;&#xD;
 &lt;strong&gt;       [OutputCache(Duration=10)]&lt;/strong&gt;&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult Index()&#xD;
        {&#xD;
            &lt;span &gt;//这里目前作为演示，是直接硬编码，实际上可能是读取数据库的数据&lt;/span&gt;&#xD;
            var employees = &lt;span &gt;new&lt;/span&gt;[]{&#xD;
                &lt;span &gt;new&lt;/span&gt; Employee(){ID=1,Name=&lt;span &gt;"ares"&lt;/span&gt;,Gender=&lt;span &gt;"Male"&lt;/span&gt;}&#xD;
            };&#xD;
            &lt;span &gt;return&lt;/span&gt; View(employees);&#xD;
        }&#xD;
&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;那么，也就是说，第一次请求这个Index的时候，里面的代码会执行，并且结果会被缓存起来，然后在10秒钟内，第二个或者后续的请求，就不需要再次执行，而是直接将结果返回给用户即可。&lt;/p&gt;&#xD;
&lt;p&gt;这个OutputCache的Attribute，实际上是一个ActionFilter，它有很多参数，具体的请参考&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://msdn.microsoft.com/zh-cn/library/system.web.mvc.outputcacheattribute.aspx" href="http://msdn.microsoft.com/zh-cn/library/system.web.mvc.outputcacheattribute.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/system.web.mvc.outputcacheattribute.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这些参数中，Duration是必须的，这是设置一个过期时间，以秒为单位，这个我想大家都很好理解。我重点要一下下面几个&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;VaryByContentEncoding&lt;br&gt;VaryByCustom&lt;br&gt;VaryByHeader&lt;br&gt;VaryByParam&lt;/li&gt;&lt;/ul&gt;&#xD;
&lt;p&gt;这四个参数的意思是，决定缓存中如何区分不同请求，就是说，哪些因素将决定使用还是不使用缓存。默认情况下，如果不做任何设置，那么在规定的时间内（我们称为缓存期间），所有用户，不管用什么方式来访问，都是直接读取缓存。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;VaryByParam&lt;/font&gt;，可以根据用户请求的参数来决定是否读取缓存。这个参数主要指的就是QueryString。例如&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;&lt;font color="#000000"&gt;如果我们缓存了&lt;a href="http://localhost/Home/Index"&gt;http://localhost/Home/Index&lt;/a&gt;，那么用这个地址来访问的时候，规定时间内都是读取缓存。但如果用&lt;a href="http://localhost/Home/Index?name=chenxizhang"&gt;http://localhost/Home/Index?name=chenxizhang&lt;/a&gt;这样的地址过来访问，显然我们希望不要读取缓存，因为参数不一样了。要实现这样的需求，也就是说，希望根据name参数的不同缓存不同的数据。则可以设置VaryByParam=”name”。&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#000000"&gt;如果有多个参数的话，可以用逗号分开他们。例如 VaryByParam=”name,Id”&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&#xD;
&lt;p&gt;&lt;font color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 【备注】这里其实会有一个潜在的风险，由于针对不同的参数（以及他们的组合）需要缓存不同的数据版本，假设有一个恶意的程序，分别用不同的参数发起大量的请求，那么就会导致缓存爆炸的情况，极端情况下，会导致服务器出现问题。（当然，IIS里面，如果发现缓存的内容不够用了，会自动将一些数据清理掉，但这就同样导致了程序的不稳定性，因为某些正常需要用的缓存可能会被销毁掉）。这也就是我为什么强调说，缓存设计是一个比较复杂的事情。&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;VaryByHeader&lt;/font&gt;，可以根据用户请求中所提供的一些Header信息不同而决定是否读取缓存。我们可以看到在每个请求中都会包含一些Header信息，如下图所示&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142100593022.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142100594135.png" width="817" height="618"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个也很有用，例如根据不同的语言，我们显然是有不同的版本的。或者根据用户浏览器不同，也可以缓存不同的版本。可以通过这样设置&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;VaryByHeader=”Accept-Language,User-Agent”&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;上面两个是比较常用的。当然还有另外两个属性也可以设置&lt;/p&gt;&#xD;
&lt;p&gt;VaryByContentEncoding，一般设置为Accept-Encoding里面可能的Encoding名称，从上图也可以看出，Request里面是包含这个标头的。&lt;/p&gt;&#xD;
&lt;p&gt;VaryByCustom，则是一个完全可以定制的设置，例如我们可能需要根据用户角色来决定不同的缓存版本，或者根据浏览器的一些小版本号来区分不同的缓存版本，我们可以这样设置：VaryByCustom=”Role,BrowserVersion”,这些名称是你自己定义的，光这样写当然是没有用的，我们还需要在Global.asax文件中，添加一个特殊的方法，来针对这种特殊的需求进行处理。&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Routing;&#xD;
&lt;strong&gt;&lt;font color="#ff0000"&gt;&lt;span &gt;using&lt;/span&gt; System.Web.Security;&lt;/font&gt;&lt;/strong&gt;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationCacheSample&#xD;
{&#xD;
    &lt;span &gt;// Note: For instructions on enabling IIS6 or IIS7 classic mode, &lt;/span&gt;&#xD;
    &lt;span &gt;// visit http://go.microsoft.com/?LinkId=9394801&lt;/span&gt;&#xD;
&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; MvcApplication : System.Web.HttpApplication&#xD;
    {&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; RegisterGlobalFilters(GlobalFilterCollection filters)&#xD;
        {&#xD;
            filters.Add(&lt;span &gt;new&lt;/span&gt; HandleErrorAttribute());&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; RegisterRoutes(RouteCollection routes)&#xD;
        {&#xD;
            routes.IgnoreRoute(&lt;span &gt;"{resource}.axd/{*pathInfo}"&lt;/span&gt;);&#xD;
&#xD;
            routes.MapRoute(&#xD;
                &lt;span &gt;"Default"&lt;/span&gt;, &lt;span &gt;// Route name&lt;/span&gt;&#xD;
                &lt;span &gt;"{controller}/{action}/{id}"&lt;/span&gt;, &lt;span &gt;// URL with parameters&lt;/span&gt;&#xD;
                &lt;span &gt;new&lt;/span&gt; { controller = &lt;span &gt;"Home"&lt;/span&gt;, action = &lt;span &gt;"Index"&lt;/span&gt;, id = UrlParameter.Optional } &lt;span &gt;// Parameter defaults&lt;/span&gt;&#xD;
            );&#xD;
&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;protected&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Application_Start()&#xD;
        {&#xD;
            AreaRegistration.RegisterAllAreas();&#xD;
&#xD;
            RegisterGlobalFilters(GlobalFilters.Filters);&#xD;
            RegisterRoutes(RouteTable.Routes);&#xD;
        }&#xD;
&#xD;
&lt;strong&gt;&lt;font color="#ff0000"&gt;        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;override&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; GetVaryByCustomString(HttpContext context, &lt;span &gt;string&lt;/span&gt; custom)&#xD;
        {&#xD;
            &lt;span &gt;switch&lt;/span&gt;(custom)&#xD;
            {&#xD;
                &lt;span &gt;case&lt;/span&gt; &lt;span &gt;"Role"&lt;/span&gt;:&#xD;
                    {&#xD;
                        &lt;span &gt;return&lt;/span&gt; &lt;span &gt;string&lt;/span&gt;.Join(&lt;span &gt;","&lt;/span&gt;, Roles.GetRolesForUser());&#xD;
                    }&#xD;
                &lt;span &gt;case&lt;/span&gt; &lt;span &gt;"BrowserVersion"&lt;/span&gt;:&#xD;
                    {&#xD;
                        &lt;span &gt;return&lt;/span&gt; context.Request.Browser.Type;&#xD;
                    }&#xD;
&#xD;
                &lt;span &gt;default&lt;/span&gt;:&#xD;
                    &lt;span &gt;break&lt;/span&gt;;&#xD;
            }&#xD;
&#xD;
            &lt;span &gt;return&lt;/span&gt; &lt;span &gt;string&lt;/span&gt;.Empty;&#xD;
        }&lt;/font&gt;&lt;/strong&gt;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;上面四个属性，可以改变缓存使用的行为。另外还有一个重要属性将影响缓存保存的位置，这就是Location属性，这个属性有如下几个可选项，我从文档中摘录过来&lt;/p&gt;&#xD;
&lt;table style="color: #000000" border="1" cellspacing="1" cellpadding="2" width="926"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="200"&gt;&#xD;
&lt;p style="line-height: normal; text-indent: 0pt"&gt;&lt;font face="Times New Roman"&gt;成员名称&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="721"&gt;&#xD;
&lt;p style="line-height: normal; text-indent: 0pt"&gt;&lt;font face="Times New Roman"&gt;说明&lt;/font&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="200"&gt;&lt;font face="Times New Roman"&gt;Any&lt;/font&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="721"&gt;&lt;font face="Times New Roman"&gt;输出缓存可位于产生请求的浏览器客户端、参与请求的代理服务器（或任何其他服务器）或处理请求的服务器上。&lt;strong&gt;&lt;font color="#ff0000"&gt;（这是默认值）&lt;/font&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="200"&gt;&lt;font face="Times New Roman"&gt;Client&lt;/font&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="721"&gt;&lt;font face="Times New Roman"&gt;输出缓存位于产生请求的浏览器客户端上。&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="200"&gt;&lt;font face="Times New Roman"&gt;Downstream&lt;/font&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="721"&gt;&lt;font face="Times New Roman"&gt;输出缓存可存储在任何 HTTP 1.1 可缓存设备中，源服务器除外。这包括代理服务器和发出请求的客户端。&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="200"&gt;&lt;font face="Times New Roman"&gt;Server&lt;/font&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="721"&gt;&lt;font face="Times New Roman"&gt;输出缓存位于处理请求的 Web 服务器上。&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="200"&gt;&lt;font face="Times New Roman"&gt;None&lt;/font&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="721"&gt;&lt;font face="Times New Roman"&gt;对于请求的页，禁用输出缓存。&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="200"&gt;&lt;font face="Times New Roman"&gt;ServerAndClient&lt;/font&gt;&lt;/td&gt;&#xD;
&lt;td valign="top" width="721"&gt;&lt;font face="Times New Roman"&gt;输出缓存只能存储在源服务器或发出请求的客户端中。代理服务器不能缓存响应。&lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&#xD;
&lt;p&gt;这里要思考一个问题，设置为Client与设置为Server有哪些行为上面的不同&lt;/p&gt;&#xD;
&lt;p&gt;如果设置为Client，那么第一次请求的时候，得到的响应标头里面，会记录好这个页面应该是要缓存的，并且在10秒之后到期。如下图所示&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142101008072.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142101001693.png" width="817" height="618"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;而如果设置为Server的话，则会看到客户端是没有缓存的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142101001726.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142101005663.png" width="817" height="618"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;看起来不错，不是吗？如果你不加思索地就表示同意，我要告诉你，你错了。所以，不要着急就下结论，请再试一下设置为Client的情况，你会发现，如果你刷新页面，那么仍然会发出请求，而且Result也是返回200，这表示这是一个新的请求，确实也返回了结果。这显然是跟我们预期不一样的。&lt;/p&gt;&#xD;
&lt;p&gt;为了做测试，我特意加了一个时间输出，如果仅仅设置为Client的话，每次刷新这个时间都是不一样的。这说明，服务器端代码被执行了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142101015139.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142101019840.png" width="817" height="618"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;同样的问题也出现在，如果我们将Location设置为ServerAndClient的时候，其实你会发现Client的缓存好像并没有生效，每次都仍然是请求服务器，只不过这一种情况下，服务器端已经做了缓存，所以在规定时间内，服务器代码是不会执行的，所以结果也不会变。但是问题在于，既然设置了客户端缓存，那么理应就直接使用客户端的缓存版本，不应该去请求服务器才对。&lt;/p&gt;&#xD;
&lt;p&gt;这个问题，其实属于是ASP.NET本身的一个问题，这里有一篇文章介绍 &lt;a title="http://blog.miniasp.com/post/2010/03/30/OutputCacheLocation-ServerAndClient-problem-fixed.aspx" href="http://blog.miniasp.com/post/2010/03/30/OutputCacheLocation-ServerAndClient-problem-fixed.aspx"&gt;http://blog.miniasp.com/post/2010/03/30/OutputCacheLocation-ServerAndClient-problem-fixed.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们可以看一下，将Location设置为ServerAndClient， 对代码稍作修改&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationCacheSample.Models;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.UI;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationCacheSample.Controllers&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; HomeController : Controller&#xD;
    {&#xD;
        &lt;span &gt;//&lt;/span&gt;&#xD;
        &lt;span &gt;// GET: /Home/&lt;/span&gt;&#xD;
        [OutputCache(Duration=10,Location=OutputCacheLocation.ServerAndClient)]&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult Index()&#xD;
        {&#xD;
&#xD;
           &lt;strong&gt;&lt;font color="#ff0000"&gt; Response.Cache.SetOmitVaryStar(&lt;span &gt;true&lt;/span&gt;);&#xD;
&lt;/font&gt;&lt;/strong&gt;&#xD;
            ViewBag.CurrentTime = DateTime.Now.ToString();&#xD;
&#xD;
&#xD;
            &lt;span &gt;//这里目前作为演示，是直接硬编码，实际上可能是读取数据库的数据&lt;/span&gt;&#xD;
            var employees = &lt;span &gt;new&lt;/span&gt;[]{&#xD;
                &lt;span &gt;new&lt;/span&gt; Employee(){ID=1,Name=&lt;span &gt;"ares"&lt;/span&gt;,Gender=&lt;span &gt;"Male"&lt;/span&gt;}&#xD;
            };&#xD;
            &lt;span &gt;return&lt;/span&gt; View(employees);&#xD;
        }&#xD;
&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142101012381.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112142101026875.png" width="817" height="610"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们看到，从第二次请求开始，状态码是304，这表示该页被缓存了，所以浏览器并不需要请求服务器的数据。而且你可以看到Received的字节为221B，而不是原先的1.25KB。&lt;/p&gt;&#xD;
&lt;p&gt;但是，&lt;font color="#ff0000"&gt;&lt;strong&gt;如果仅仅设置为Client，则仍然无法真正实现客户端缓存（这个行为是有点奇怪的）&lt;/strong&gt;&lt;/font&gt;。这个问题我确实也一直没有找到办法，如果我们确实需要使用客户端缓存，索性我们还是设置为ServerAndClient吧。&lt;/p&gt;&#xD;
&lt;p&gt;使用客户端缓存，可以明显减少对服务器发出的请求数，这从一定意义上更加理想。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.使用缓存配置文件&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;第一节中，我们详细地了解了MVC中，如何通过OutputCache这个ActionFilter来设置缓存。但是，因为这些设置都是通过C#代码直接定义在Action上面的，所以未免不是很灵活，例如我们可能需要经常调整这些设置，该如何办呢？&lt;/p&gt;&#xD;
&lt;p&gt;ASP.NET 4.0中提供了一个新的机制，就是CacheProfile的功能，我们可以在配置文件中，定义所谓的Profile，然后在OutputCache这个Attribute里面可以直接使用。&lt;/p&gt;&#xD;
&lt;p&gt;通过下面的例子，可以很容易看到这种机制的好处。下面的节点定义在system.web中&lt;/p&gt;&lt;pre &gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;caching&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;outputCacheSettings&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;outputCacheProfiles&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
          &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="employee"&lt;/span&gt; &lt;span &gt;duration&lt;/span&gt;&lt;span &gt;="10"&lt;/span&gt; &lt;span &gt;enabled&lt;/span&gt;&lt;span &gt;="true"&lt;/span&gt; &lt;span &gt;location&lt;/span&gt;&lt;span &gt;="ServerAndClient"&lt;/span&gt; &lt;span &gt;varyByParam&lt;/span&gt;&lt;span &gt;="none"&lt;/span&gt;&lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;outputCacheProfiles&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;outputCacheSettings&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;caching&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;然后，代码中可以直接地使用这个Profile了&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationCacheSample.Models;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.UI;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationCacheSample.Controllers&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; HomeController : Controller&#xD;
    {&#xD;
        &lt;span &gt;//&lt;/span&gt;&#xD;
        &lt;span &gt;// GET: /Home/&lt;/span&gt;&#xD;
        [OutputCache(CacheProfile=&lt;span &gt;"employee"&lt;/span&gt;)]&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult Index()&#xD;
        {&#xD;
&#xD;
            &lt;span &gt;//Response.Cache.SetOmitVaryStar(true);&lt;/span&gt;&#xD;
&#xD;
            ViewBag.CurrentTime = DateTime.Now.ToString();&#xD;
&#xD;
&#xD;
            &lt;span &gt;//这里目前作为演示，是直接硬编码，实际上可能是读取数据库的数据&lt;/span&gt;&#xD;
            var employees = &lt;span &gt;new&lt;/span&gt;[]{&#xD;
                &lt;span &gt;new&lt;/span&gt; Employee(){ID=1,Name=&lt;span &gt;"ares"&lt;/span&gt;,Gender=&lt;span &gt;"Male"&lt;/span&gt;}&#xD;
            };&#xD;
            &lt;span &gt;return&lt;/span&gt; View(employees);&#xD;
        }&#xD;
&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;这个例子很直观，有了Profile，我们可以很轻松地在运行时配置缓存的一些关键值。&lt;/p&gt;&#xD;
&lt;pre &gt;&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;3.使用缓存API&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;通过上面的两步，我们了解到了使用OutputCache，并且结合CacheProfile，可以很好地实现灵活的缓存配置。但是有的时候，我们可能还希望对缓存控制得更加精细一些。因为OutputCache是对Action的缓存，不同的Action之间是不能共享数据的，假如某些数据，我们是在不同的Action之间共享的，那么，简单地采用OutputCache来做，就会导致对同一份数据，缓存多次的问题。&lt;/p&gt;&#xD;
&lt;p&gt;所以，ASP.NET除了提供OutputCache这种基于声明的输出缓存设置之外，还允许我们在代码中，自己控制要对哪些数据进行缓存，并且提供了更多的选项。&lt;/p&gt;&#xD;
&lt;p&gt;关于如何通过API的方式添加或者使用缓存，请参考&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://msdn.microsoft.com/zh-cn/library/18c1wd61%28v=VS.80%29.aspx" href="http://msdn.microsoft.com/zh-cn/library/18c1wd61%28v=VS.80%29.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/18c1wd61%28v=VS.80%29.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;基本上就是使用HttpContext.Cache类型，可以完成所有的操作，而且足够灵活。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;值得一提的是，我知道不少公司在项目中都会采用一些ORM框架，某些ORM框架中也允许实现缓存。例如NHibernate就提供了较为丰富的缓存功能，大致可以参考一下 &lt;a title="http://www.cnblogs.com/RicCC/archive/2009/12/28/nhibernate-cache-internals.html" href="http://www.cnblogs.com/RicCC/archive/2009/12/28/nhibernate-cache-internals.html"&gt;http://www.cnblogs.com/RicCC/archive/2009/12/28/nhibernate-cache-internals.html&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;需要注意的是，微软自己提供的Entity Framework本身并没有包含缓存的功能。&lt;/p&gt;&#xD;
&lt;p&gt;这里仍然要特别提醒一下，使用这种基于API的缓存方案，需要仔细推敲每一层缓存的设置是否合理，以及更新等问题。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.使用缓存依赖&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;很早之前，在ASP.NET中设计缓存的时候，我们就可以使用缓存依赖的技术。关于缓存依赖，详细的信息请参考 &lt;a title="http://msdn.microsoft.com/zh-cn/library/ms178604.aspx" href="http://msdn.microsoft.com/zh-cn/library/ms178604.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/ms178604.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;实际上，这个技术确实很有用，ASP.NET默认提供了一个&lt;a href="http://msdn.microsoft.com/zh-cn/library/system.web.caching.sqlcachedependency.aspx"&gt;SqlCacheDependency&lt;/a&gt;，可以通过配置，连接SQL Server数据库，当数据库的表发生变化的时候，会通知到ASP.NET，该缓存就会失效。&lt;/p&gt;&#xD;
&lt;p&gt;值得一提的是，不管是采用OutputCache这样的声明式的缓存方式，还是采用缓存API的方式，都可以使用到缓存依赖。而且使用缓存API的话，除了使用SqlCacheDependency之外，还可以使用标准的CacheDependency对象，实现对文件的依赖。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://msdn.microsoft.com/zh-cn/library/system.web.caching.cachedependency%28v=VS.80%29.aspx" href="http://msdn.microsoft.com/zh-cn/library/system.web.caching.cachedependency%28v=VS.80%29.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/system.web.caching.cachedependency%28v=VS.80%29.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.分布式缓存&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;上面提到的手段都很不错，如果应用系统不是很庞大的话，也够用了。需要注意的是，上面所提到的缓存手段，都是在Web服务器本地内存中进行缓存，这种做法的问题在于，如果我们需要做负载均衡（一般就会有多台服务器）的时候，就不可能在多台服务器之间共享到这些缓存。正因为如此，分布式缓存的概念就应运而生了。&lt;/p&gt;&#xD;
&lt;p&gt;谈到分布式缓存，目前比较受到大家认可的一个开源框架是 memcached。顾名思义，它仍然使用的是内存的缓存，只不过，它天生就是基于分布式的，它的访问都是直接通过tcp的方式，所以可以访问远程服务器，也可以多台Web服务器访问同一台缓存服务器。&lt;/p&gt;&#xD;
&lt;p&gt;关于memcached以及它在.NET中的使用，之前有一个朋友有写过一个介绍，可以参考使用一下&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://www.cnblogs.com/zjneter/archive/2007/07/19/822780.html" href="http://www.cnblogs.com/zjneter/archive/2007/07/19/822780.html"&gt;http://www.cnblogs.com/zjneter/archive/2007/07/19/822780.html&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;需要注意的是，&lt;strong&gt;&lt;font color="#ff0000"&gt;分布式缓存不是为了来提高性能的（这可能是一个误区）&lt;/font&gt;&lt;/strong&gt;，并且可以肯定的是，它的速度一定会被本地慢一些。如果你的应用只有一台服务器就能满足要求，你就没有必要使用memcached。它的最大好处就是跨服务器，跨应用共享缓存。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2288062.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/12/14/2288062.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2011/12/13/2285816.html</id><title type="text">MVC3课程中的几个问题整理</title><summary type="text">这是几个小问题，整理出来给大家参考 1. 如何为不同类型的属性设置不同的编辑界面 备注：这个实例的源代码，可以通过这里下载 MvcApplicationEditTemplate.rar 我们探讨到...</summary><published>2011-12-13T03:27:00Z</published><updated>2011-12-13T03:27:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/13/2285816.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/13/2285816.html"/><content type="html">&lt;p&gt;这是几个小问题，整理出来给大家参考&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. 如何为不同类型的属性设置不同的编辑界面&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;备注：这个实例的源代码，可以通过这里下载 &lt;a title="MvcApplicationEditTemplate.rar" href="http://files.cnblogs.com/chenxizhang/MvcApplicationEditTemplate.rar"&gt;MvcApplicationEditTemplate.rar&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;我们探讨到了针对不同的属性，MVC3其实可以专门定制不同的编辑界面。这个概念，其实早在MVC出来之前，就曾经有过。之前有一个Dynamic Data的网站模板 ，里面大致也是用到了所谓的编辑器模板（FieldTemplates)的概念。&lt;/p&gt; &lt;p&gt;我们可以大致看一眼之前的做法&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126283157.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126283190.png" width="337" height="732"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;注意,Dynamic Data这个模板，是基于Web Forms实现的一个应用架构。这里不作进一步展开，如果有兴趣的朋友，可以参考：&lt;a title="http://msdn.microsoft.com/en-us/library/ee845452.aspx" href="http://msdn.microsoft.com/en-us/library/ee845452.aspx"&gt;http://msdn.microsoft.com/en-us/library/ee845452.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;提一下Dynamic Data，是希望给大家一个初步印象，确实可以针对不同类型的字段，设置不同的界面来编辑或者显示。MVC中也提供了这样的机制。&lt;/p&gt; &lt;p&gt;下面我们来做一个常见的例子，&lt;strong&gt;&lt;font color="#ff0000"&gt;我们希望那些类型为DateTime的属性，在页面上编辑的时候，自动调用jquery的一个日历效果让用户可以选择，而不是简单的一个文本框。&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;准备一个业务实体类型(Employee)&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationEditTemplate.Models&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Employee&#xD;
    {&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;int&lt;/span&gt; ID { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; FirstName { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; LastName { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; DateTime Birthday { get; set; }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;准备一个HomeController&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationEditTemplate.Controllers&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; HomeController : Controller&#xD;
    {&#xD;
        &lt;span &gt;//&lt;/span&gt;&#xD;
        &lt;span &gt;// GET: /Home/&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult Index()&#xD;
        {&#xD;
            var emp = &lt;span &gt;new&lt;/span&gt; Models.Employee();&#xD;
&#xD;
            &lt;span &gt;return&lt;/span&gt; View(emp);&#xD;
        }&#xD;
&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;为这个Action生成一个Edit视图&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;@model MvcApplicationEditTemplate.Models.Employee&#xD;
&#xD;
@{&#xD;
    ViewBag.Title = "Index";&#xD;
}&#xD;
&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;h2&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Index&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;h2&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
&#xD;
&#xD;
@using (Html.BeginForm()) {&#xD;
    @Html.ValidationSummary(true)&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;fieldset&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;legend&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Employee&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;legend&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
        @Html.HiddenFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.ID)&#xD;
&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-label"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.LabelFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.FirstName)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-field"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.EditorFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.FirstName)&#xD;
            @Html.ValidationMessageFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.FirstName)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-label"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.LabelFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.LastName)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-field"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.EditorFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.LastName)&#xD;
            @Html.ValidationMessageFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.LastName)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-label"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.LabelFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.Birthday)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-field"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.EditorFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.Birthday)&#xD;
            @Html.ValidationMessageFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.Birthday)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;p&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;input&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="submit"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="Save"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;p&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;fieldset&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
}&#xD;
&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    @Html.ActionLink("Back to List", "Index")&#xD;
&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;注意看这里的语法：EditorFor。这是MVC比较推荐的做法，我发现不少朋友可能还是习惯自己去些input，但我个人觉得那不是一个很好的做法。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;预览效果 &#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126283223.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126293256.png" width="552" height="513"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们的需求就是，将Birthday下面这个文本框定制一下，让他可以自动显示出来一个日历。（我们将采用jquery ui来实现）&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;添加一个EditorTemplate&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;由于Birthday属性是DateTime类型，所以我们可以针对这个类型设计一个编辑器模板。为了共享，我们可以将这个模板放在Shared目录下面&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126292417.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126294959.png" width="348" height="114"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;请注意，这里的目录名必须叫做：EditorTemplates。那个模板的名称也必须叫DateTime.cshtml。 再一次领教了MVC中约定胜于配置的特性吧。&lt;/p&gt;&lt;pre &gt;@model System.DateTime&#xD;
@Html.TextBox("",ViewData.TemplateInfo.FormattedModelValue,new {date_picker=true})&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;在这个文件中，我们只需要指定两行代码。（这是Razor表达式语法），从上面的语法可以看出，我们其实还是放了一个文本框（TextBox)，但这里的关键在于，我们会通过jquery来给这个文本框添加特效。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;添加一个jscript文件（EditorBehavior.js)&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;/// &amp;lt;reference path="jquery-1.5.1-vsdoc.js" /&amp;gt;&lt;/span&gt;&#xD;
$(&lt;span &gt;function&lt;/span&gt; () {&#xD;
    $(&lt;span &gt;":input[date-picker]"&lt;/span&gt;).datepicker();&#xD;
});&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;strong&gt;在视图中引入这个脚本文件&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;@model MvcApplicationEditTemplate.Models.Employee&#xD;
&#xD;
@{&#xD;
    ViewBag.Title = "Index";&#xD;
}&#xD;
&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;h2&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Index&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;h2&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;script&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="@Url.Content("&lt;/span&gt;~/&lt;span &gt;Scripts&lt;/span&gt;/&lt;span &gt;jquery-ui-1&lt;/span&gt;.&lt;span &gt;8&lt;/span&gt;.&lt;span &gt;11&lt;/span&gt;.&lt;span &gt;js&lt;/span&gt;&lt;span &gt;")"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="text/javascript"&lt;/span&gt;&lt;span &gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;script&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &amp;lt;script src=&lt;span &gt;"@Url.Content("&lt;/span&gt;~/Scripts/EditorBehavior.js&lt;span &gt;")"&lt;/span&gt; type=&lt;span &gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;script&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
@using (Html.BeginForm()) {&#xD;
    @Html.ValidationSummary(true)&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;fieldset&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;legend&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Employee&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;legend&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
        @Html.HiddenFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.ID)&#xD;
&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-label"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.LabelFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.FirstName)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-field"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.EditorFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.FirstName)&#xD;
            @Html.ValidationMessageFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.FirstName)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-label"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.LabelFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.LastName)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-field"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.EditorFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.LastName)&#xD;
            @Html.ValidationMessageFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.LastName)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-label"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.LabelFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.Birthday)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="editor-field"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @Html.EditorFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.Birthday)&#xD;
            @Html.ValidationMessageFor(model =&lt;span &gt;&amp;gt;&lt;/span&gt; model.Birthday)&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;p&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;input&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="submit"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="Save"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;p&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;fieldset&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
}&#xD;
&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    @Html.ActionLink("Back to List", "Index")&#xD;
&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;最后预览得到的效果就是下面这样。按照这样的思路，我们还可以给其他类型的属性指定编辑器模板。&lt;/p&gt;&lt;pre &gt;&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126306420.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126305930.png" width="476" height="621"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个实例的源代码，可以通过这里下载 &lt;a title="MvcApplicationEditTemplate.rar" href="http://files.cnblogs.com/chenxizhang/MvcApplicationEditTemplate.rar"&gt;MvcApplicationEditTemplate.rar&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2. 为什么脚本移动位置之后，页面的样式变化了&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这是一个小问题，我们先来看一下默认情况下MVC项目的样式&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126314011.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126317109.png" width="931" height="627"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个布局和样式，是在_layout.cshtml中定义好的&lt;/p&gt;&lt;pre &gt;&lt;span &gt;&amp;lt;!&lt;/span&gt;&lt;span &gt;DOCTYPE&lt;/span&gt; &lt;span &gt;html&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;html&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;head&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;meta&lt;/span&gt; &lt;span &gt;charset&lt;/span&gt;&lt;span &gt;="utf-8"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;title&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;@ViewBag.Title&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;title&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;link&lt;/span&gt; &lt;span &gt;href&lt;/span&gt;&lt;span &gt;="@Url.Content("&lt;/span&gt;~/&lt;span &gt;Content&lt;/span&gt;/&lt;span &gt;Site&lt;/span&gt;.&lt;span &gt;css&lt;/span&gt;&lt;span &gt;")"&lt;/span&gt; &lt;span &gt;rel&lt;/span&gt;&lt;span &gt;="stylesheet"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="text/css"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;script&lt;/span&gt; &lt;span &gt;src&lt;/span&gt;&lt;span &gt;="@Url.Content("&lt;/span&gt;~/&lt;span &gt;Scripts&lt;/span&gt;/&lt;span &gt;jquery-1&lt;/span&gt;.&lt;span &gt;5&lt;/span&gt;.&lt;span &gt;1&lt;/span&gt;.&lt;span &gt;min&lt;/span&gt;.&lt;span &gt;js&lt;/span&gt;&lt;span &gt;")"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="text/javascript"&lt;/span&gt;&lt;span &gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;script&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &amp;lt;script src=&lt;span &gt;"@Url.Content("&lt;/span&gt;~/Scripts/modernizr-1.7.min.js&lt;span &gt;")"&lt;/span&gt; type=&lt;span &gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;script&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;head&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;body&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;class&lt;/span&gt;&lt;span &gt;="page"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;header&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;id&lt;/span&gt;&lt;span &gt;="title"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
                &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;h1&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
                    My MVC Application&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;h1&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;div&lt;/span&gt; &lt;span &gt;id&lt;/span&gt;&lt;span &gt;="logindisplay"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
                @Html.Partial("_LogOnPartial")&#xD;
            &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;nav&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
                &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;ul&lt;/span&gt; &lt;span &gt;id&lt;/span&gt;&lt;span &gt;="menu"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
                    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;li&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;@Html.ActionLink("Home", "Index", "Home")&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;li&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
                    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;li&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;@Html.ActionLink("About", "About", "Home")&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;li&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
                &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;ul&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;nav&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;header&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;section&lt;/span&gt; &lt;span &gt;id&lt;/span&gt;&lt;span &gt;="main"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
            @RenderBody()&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;section&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;footer&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;footer&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;div&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;body&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;html&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;出于网站设计优化的考虑，我们知道应该尽可能地将javascript的引用放在页面底部。Yahoo有一个专门的文章讲这方面的内容：&lt;a href="http://developer.yahoo.com/performance/rules.html"&gt;Best Practices for Speeding Up Your Web Site&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;所以，你可能会尝试将脚本移动到footer里面，例如下面这样&lt;/p&gt;&lt;pre &gt;&amp;lt;!DOCTYPE html&amp;gt;&#xD;
&amp;lt;html&amp;gt;&#xD;
&amp;lt;head&amp;gt;&#xD;
    &amp;lt;meta charset=&lt;span &gt;"utf-8"&lt;/span&gt; /&amp;gt;&#xD;
    &amp;lt;title&amp;gt;@ViewBag.Title&amp;lt;/title&amp;gt;&#xD;
    &amp;lt;link href=&lt;span &gt;"@Url.Content("&lt;/span&gt;~/Content/Site.css&lt;span &gt;")"&lt;/span&gt; rel=&lt;span &gt;"stylesheet"&lt;/span&gt; type=&lt;span &gt;"text/css"&lt;/span&gt; /&amp;gt;&#xD;
&amp;lt;/head&amp;gt;&#xD;
&amp;lt;body&amp;gt;&#xD;
    &amp;lt;div &lt;span &gt;class&lt;/span&gt;=&lt;span &gt;"page"&lt;/span&gt;&amp;gt;&#xD;
        &amp;lt;header&amp;gt;&#xD;
            &amp;lt;div id=&lt;span &gt;"title"&lt;/span&gt;&amp;gt;&#xD;
                &amp;lt;h1&amp;gt;&#xD;
                    My MVC Application&amp;lt;/h1&amp;gt;&#xD;
            &amp;lt;/div&amp;gt;&#xD;
            &amp;lt;div id=&lt;span &gt;"logindisplay"&lt;/span&gt;&amp;gt;&#xD;
                @Html.Partial(&lt;span &gt;"_LogOnPartial"&lt;/span&gt;)&#xD;
            &amp;lt;/div&amp;gt;&#xD;
            &amp;lt;nav&amp;gt;&#xD;
                &amp;lt;ul id=&lt;span &gt;"menu"&lt;/span&gt;&amp;gt;&#xD;
                    &amp;lt;li&amp;gt;@Html.ActionLink(&lt;span &gt;"Home"&lt;/span&gt;, &lt;span &gt;"Index"&lt;/span&gt;, &lt;span &gt;"Home"&lt;/span&gt;)&amp;lt;/li&amp;gt;&#xD;
                    &amp;lt;li&amp;gt;@Html.ActionLink(&lt;span &gt;"About"&lt;/span&gt;, &lt;span &gt;"About"&lt;/span&gt;, &lt;span &gt;"Home"&lt;/span&gt;)&amp;lt;/li&amp;gt;&#xD;
                &amp;lt;/ul&amp;gt;&#xD;
            &amp;lt;/nav&amp;gt;&#xD;
        &amp;lt;/header&amp;gt;&#xD;
        &amp;lt;section id=&lt;span &gt;"main"&lt;/span&gt;&amp;gt;&#xD;
            @RenderBody()&#xD;
        &amp;lt;/section&amp;gt;&#xD;
        &amp;lt;footer&amp;gt;&#xD;
            &amp;lt;script src=&lt;span &gt;"@Url.Content("&lt;/span&gt;~/Scripts/jquery-1.5.1.min.js&lt;span &gt;")"&lt;/span&gt; type=&lt;span &gt;"text/javascript"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&#xD;
            &amp;lt;script src=&lt;span &gt;"@Url.Content("&lt;/span&gt;~/Scripts/modernizr-1.7.min.js&lt;span &gt;")"&lt;/span&gt; type=&lt;span &gt;"text/javascript"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&#xD;
        &amp;lt;/footer&amp;gt;&#xD;
    &amp;lt;/div&amp;gt;&#xD;
&amp;lt;/body&amp;gt;&#xD;
&amp;lt;/html&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;看起来很好，但是再次打开网站的话，就会发现网页的样式有些问题&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/20111213112634503.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126358900.png" width="931" height="627"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这是为什么呢？原因是MVC3默认使用了HTML 5的语法来构建页面，目前HTML 5因为还没有成为事实上的标准，所以使用了一个专门的javascript库来提供支持。这个javascript库就是：modernizr-1.7.min.js， 这是一个开源的作品，请参考这里 &lt;a title="http://www.modernizr.com/" href="http://www.modernizr.com/"&gt;http://www.modernizr.com/&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在页面中用到的header,section,footer这类的tag其实是html 5专用的，所以如果上面这个脚本没有预先加载，可能显示的时候，就会有些问题。&lt;/p&gt;&#xD;
&lt;p&gt;所以，我们应该将modernizr-1.7.min.js放在header里面去。这样就和谐了&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126362031.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126368717.png" width="931" height="627"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;值得一说的是，这个库只有10KB左右，所以将它放在header里面对性能影响很小。&lt;/p&gt;&#xD;
&lt;p&gt;我们还可以使用微软提供的CDN功能，尽可能地减少用户需要下载的javascript的体积。关于CDN，请参考这里：&lt;a title="http://www.asp.net/ajaxlibrary/cdn.ashx" href="http://www.asp.net/ajaxlibrary/cdn.ashx"&gt;http://www.asp.net/ajaxlibrary/cdn.ashx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.Remote验证&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&#xD;
&#xD;
&lt;p&gt;MVC3提供了一个新增的数据验证功能，叫做Remote验证，意思是可以利用客户端javascript，发起异步的请求，调用服务器代码进行验证。这个功能很不错，例如有一个页面提供用户输入用户名进行注册，我们经常需要检测用户名是否已经被别人占用。这种验证显然是无法在客户端直接提供，而是需要利用服务器代码来实现。&lt;/p&gt;&#xD;
&lt;p&gt;下面来看一个例子&lt;/p&gt;&#xD;
&lt;p&gt;首先，我们要为类型定义Annotation，需要注意的是，Remote这个Annotation是MVC专用的，所以要using System.Web.Mvc&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.ComponentModel.DataAnnotations;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationEditTemplate.Models&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Employee&#xD;
    {&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;int&lt;/span&gt; ID { get; set; }&#xD;
        [Required]&#xD;
        [Remote(&lt;span &gt;"IsNameValid"&lt;/span&gt;,&lt;span &gt;"Home"&lt;/span&gt;)]&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; FirstName { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; LastName { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; DateTime Birthday { get; set; }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;这里指定了一个远程验证用的Controller（Home）和Action（IsNameValid）&lt;/p&gt;&#xD;
&lt;p&gt;所以，接下来我们准备这样一个Action&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationEditTemplate.Controllers&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; HomeController : Controller&#xD;
    {&#xD;
        &lt;span &gt;//&lt;/span&gt;&#xD;
        &lt;span &gt;// GET: /Home/&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult Index()&#xD;
        {&#xD;
            var emp = &lt;span &gt;new&lt;/span&gt; Models.Employee();&#xD;
&#xD;
            &lt;span &gt;return&lt;/span&gt; View(emp);&#xD;
        }&#xD;
&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult IsNameValid(&lt;span &gt;string&lt;/span&gt; FirstName)&#xD;
        {&#xD;
            &lt;span &gt;if&lt;/span&gt;(FirstName == &lt;span &gt;"ares"&lt;/span&gt;)&#xD;
            {&#xD;
                &lt;span &gt;return&lt;/span&gt; Json(&lt;span &gt;true&lt;/span&gt;, JsonRequestBehavior.AllowGet);&#xD;
            }&#xD;
            &lt;span &gt;return&lt;/span&gt; Json(&lt;span &gt;"Your name is invalid"&lt;/span&gt;, JsonRequestBehavior.AllowGet);&#xD;
        }&#xD;
&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
注意，这里只是做了一个例子，直接比较FirstName是不是等于ares。实际情况下，这里可以执行数据库查询，得到结果。&lt;/p&gt;&#xD;
&lt;p&gt;还需要注意的是，这里必须返回json的数据，并且必须设置为AllowGet。&lt;/p&gt;&#xD;
&lt;p&gt;接下来，在视图中，要添加两个脚本引用，如下所示&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126362653.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126378783.png" width="699" height="732"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;远程验证的效果如下&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126372719.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112131126372752.png" width="467" height="536"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2285816.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/12/13/2285816.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2011/12/12/2285304.html</id><title type="text">在MVC3项目中结合NInject组件实现依赖注入的设计</title><summary type="text">这是本次MVC3讲座中的一个话题，整理出来给大家参考参考 名词解释 依赖注入：英文是Dependency Injection。有时候也称为反转控制(Ioc)吧。不管名词怎么讲，它的大致意思是，让我们的...</summary><published>2011-12-12T13:19:00Z</published><updated>2011-12-12T13:19:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/12/2285304.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/12/2285304.html"/><content type="html">&lt;p&gt;这是本次MVC3讲座中的一个话题，整理出来给大家参考参考&lt;/p&gt; &lt;p&gt;&lt;strong&gt;名词解释&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;依赖注入：英文是Dependency Injection。有时候也称为反转控制(Ioc)吧。不管名词怎么讲，它的大致意思是，让我们的应用程序所依赖的一些外部服务，可以根据需要动态注入，而不是预先在应用程序中明确地约束。这种思想，在当前的软件开发领域，为了保证架构的灵活性，应该还是很有意义的。&lt;/p&gt; &lt;p&gt;在MVC这个框架中，为依赖注入的设计提供了先天的支持。结合一些我们熟知的DI组件，例如NInject，我们可以较为容易地实现上述提到的功能。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;场景介绍&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;我们的应用程序，需要支持各种不同的数据源，而且我们希望日后可以很容易地切换，不会因为数据源的变化而导致对Contoller或者Model，或者View做修改。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;本文完整源代码，请通过这里下载 &lt;a title="MvcApplicationDISample.rar" href="http://files.cnblogs.com/chenxizhang/MvcApplicationDISample.rar"&gt;MvcApplicationDISample.rar&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;演练步骤&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;第一步：准备一个MVC项目(选择空白模板）&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118455072.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118463153.png" width="1028" height="732"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;第二步：准备一个业务实体类型&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationDISample.Models&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Employee&#xD;
    {&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;int&lt;/span&gt; ID { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; FirstName { get; set; }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; LastName { get; set; }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;第三步：准备一个数据访问的接口定义&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Text;&#xD;
&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationDISample.Models;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationDISample.Services&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;interface&lt;/span&gt; IDataService&#xD;
    {&#xD;
        Employee[] GetEmployee();&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;第四步：创建一个HomeController&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118467089.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118467122.png" width="608" height="397"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationDISample.Services;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationDISample.Models;&#xD;
&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationDISample.Controllers&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; HomeController : Controller&#xD;
    {&#xD;
&#xD;
        IDataService DataService;&#xD;
        &lt;span &gt;public&lt;/span&gt; HomeController(IDataService service)&#xD;
        {&#xD;
            DataService = service;&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;//&lt;/span&gt;&#xD;
        &lt;span &gt;// GET: /Home/&lt;/span&gt;&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult Index()&#xD;
        {&#xD;
            var data = DataService.GetEmployee();&#xD;
            &lt;span &gt;return&lt;/span&gt; View(data);&#xD;
        }&#xD;
&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
注意，这里需要为HomeController添加一个特殊的构造函数，传入IDataService这个接口。通常，所有的DI组件都是通过这样的方式注入的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;在设计HomeController的时候，我们不需要关心到底日后会用具体的哪种DataService，我们只是要求要传入一个IDataService的具体实现就可以了，这就是DI的本质了。&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;到这里为止，我们该做的准备工作基本就绪了。下面来看看如何结合DI组件来实现我们的需求&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;第五步：引入NInject组件&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这是我比较喜欢的一个DI组件。它还针对MVC3专门有一个扩展&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118463252.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118478301.png" width="868" height="594"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118477778.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118479447.png" width="868" height="594"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;添加这个组件之后，除了自动添加了很多引用之外，还有一个特殊的文件App_Start\NinjectMVC3.cs&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118486972.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118482860.png" width="362" height="244"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;[assembly: WebActivator.PreApplicationStartMethod(&lt;span &gt;typeof&lt;/span&gt;(MvcApplicationDISample.App_Start.NinjectMVC3), &lt;span &gt;"Start"&lt;/span&gt;)]&#xD;
[assembly: WebActivator.ApplicationShutdownMethodAttribute(&lt;span &gt;typeof&lt;/span&gt;(MvcApplicationDISample.App_Start.NinjectMVC3), &lt;span &gt;"Stop"&lt;/span&gt;)]&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationDISample.App_Start&#xD;
{&#xD;
    &lt;span &gt;using&lt;/span&gt; System.Reflection;&#xD;
    &lt;span &gt;using&lt;/span&gt; Microsoft.Web.Infrastructure.DynamicModuleHelper;&#xD;
    &lt;span &gt;using&lt;/span&gt; Ninject;&#xD;
    &lt;span &gt;using&lt;/span&gt; Ninject.Web.Mvc;&#xD;
&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; NinjectMVC3 &#xD;
    {&#xD;
        &lt;span &gt;private&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;readonly&lt;/span&gt; Bootstrapper bootstrapper = &lt;span &gt;new&lt;/span&gt; Bootstrapper();&#xD;
&#xD;
        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// Starts the application&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Start() &#xD;
        {&#xD;
            DynamicModuleUtility.RegisterModule(&lt;span &gt;typeof&lt;/span&gt;(OnePerRequestModule));&#xD;
            DynamicModuleUtility.RegisterModule(&lt;span &gt;typeof&lt;/span&gt;(HttpApplicationInitializationModule));&#xD;
            bootstrapper.Initialize(CreateKernel);&#xD;
        }&#xD;
        &#xD;
        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// Stops the application.&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Stop()&#xD;
        {&#xD;
            bootstrapper.ShutDown();&#xD;
        }&#xD;
        &#xD;
        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// Creates the kernel that will manage your application.&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;returns&amp;gt;The created kernel.&amp;lt;/returns&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;private&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; IKernel CreateKernel()&#xD;
        {&#xD;
            var kernel = &lt;span &gt;new&lt;/span&gt; StandardKernel();&#xD;
            RegisterServices(kernel);&#xD;
            &lt;span &gt;return&lt;/span&gt; kernel;&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// Load your modules or register your services here!&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;param name="kernel"&amp;gt;The kernel.&amp;lt;/param&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;private&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; RegisterServices(IKernel kernel)&#xD;
        {&#xD;
        }        &#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&#xD;
&#xD;
&lt;p&gt;这个类型很有意思，WebActivator.PreApplicationStartMethod这个方法其实是注册了一个在MVC程序启动之前运行的方法。这些代码大家应该能看懂，它在CreateKernel中，添加一个新的Kernel（用来做注入的容器）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;第六步：创建一个IDataService的具体实现&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationDISample.Models;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationDISample.Services&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; SampleDataService:IDataService&#xD;
    {&#xD;
        &lt;span &gt;#region&lt;/span&gt; IDataService Members&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; Employee[] GetEmployee()&#xD;
        {&#xD;
            &lt;span &gt;return&lt;/span&gt; &lt;span &gt;new&lt;/span&gt;[]{&#xD;
                &lt;span &gt;new&lt;/span&gt; Employee(){ID=1,FirstName=&lt;span &gt;"ares"&lt;/span&gt;,LastName=&lt;span &gt;"chen"&lt;/span&gt;}};&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;#endregion&lt;/span&gt;&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
作为举例，我们这里用了一个硬编码的方式实现了该服务。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;第七步：实现注入&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;回到App_Start\NinjectMVC3.cs这个文件，修改RegisterServices方法如下&lt;/p&gt;&lt;pre &gt;&lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// Load your modules or register your services here!&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;param name="kernel"&amp;gt;The kernel.&amp;lt;/param&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;private&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; RegisterServices(IKernel kernel)&#xD;
        {&#xD;
            kernel.Bind&amp;lt;Services.IDataService&amp;gt;().To&amp;lt;Services.SampleDataService&amp;gt;();&#xD;
        }      &lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;第八步：测试Controller的功能&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/20111212211848385.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118487038.png" width="682" height="315"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们可以看到，数据已经展现出来了。这说明，HomeController中的Index方法，确实调用了我们后期插入的这个SampleDataService。而通过下图，则可以更加清楚看到这一点&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118484006.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118499023.png" width="807" height="208"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;到这里为止，我们就结合Ninject组件实现了一个简单的依赖注入的实例。Ninject 针对MVC 3有这么一个特殊的文件，可以极大地方便我们的编程。但即便没有这个文件，我们也可以通过另外一些方法来实现需求。&lt;/p&gt;&#xD;
&lt;p&gt;下面介绍两种比较传统的，通过扩展MVC组件实现的方式&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;第一种：实现自定义ControllerFactory&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们都知道,Controller其实都是由ControllerFactory来生成的，那么，为了给所有新创建从Controller都自动注入我们的服务，那么就可以从ControllerFactory这个地方动动脑筋了。&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&lt;span &gt;using&lt;/span&gt; Ninject;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationDISample.Services;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationDISample.Extensions&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; InjectControllerFactory:DefaultControllerFactory&#xD;
    {&#xD;
&#xD;
        &lt;span &gt;private&lt;/span&gt; IKernel kernel;&#xD;
        &lt;span &gt;public&lt;/span&gt; InjectControllerFactory()&#xD;
        {&#xD;
            kernel = &lt;span &gt;new&lt;/span&gt; StandardKernel();&#xD;
            kernel.Bind&amp;lt;IDataService&amp;gt;().To&amp;lt;SampleDataService&amp;gt;();&#xD;
        }&#xD;
        &lt;span &gt;protected&lt;/span&gt; &lt;span &gt;override&lt;/span&gt; IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)&#xD;
        {&#xD;
            &lt;span &gt;return&lt;/span&gt; (IController)kernel.Get(controllerType);&#xD;
        }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
要使用这个自定义的 ControllerFactory，我们需要修改Global.ascx文件中的Application_Start方法，添加下面的粗体部分代码&lt;/p&gt;&lt;pre &gt;&lt;span &gt;protected&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Application_Start()&#xD;
        {&#xD;
            AreaRegistration.RegisterAllAreas();&#xD;
&#xD;
            RegisterGlobalFilters(GlobalFilters.Filters);&#xD;
            RegisterRoutes(RouteTable.Routes);&#xD;
&#xD;
           &lt;strong&gt;ControllerBuilder.Current.SetControllerFactory(&lt;span &gt;new&lt;/span&gt; Extensions.InjectControllerFactory());&#xD;
&lt;/strong&gt;        }&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;这样做好之后，我们可以测试HomeController中的Index这个Action，我们发现它还是能正常工作。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118492403.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118491008.png" width="634" height="315"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;第二种：实现自定义的DependencyResolver&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;顾名思义，这就是MVC框架里面专门来处理所谓的依赖项的处理器。可以说这是MVC专门为DI准备的一个后门。下面是我写好的一个例子&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Mvc;&#xD;
&lt;span &gt;using&lt;/span&gt; Ninject;&#xD;
&lt;span &gt;using&lt;/span&gt; MvcApplicationDISample.Services;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationDISample.Extensions&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; InjectDependencyResolver:IDependencyResolver&#xD;
    {&#xD;
        &lt;span &gt;private&lt;/span&gt; IKernel kernel;&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; InjectDependencyResolver()&#xD;
        {&#xD;
            kernel = &lt;span &gt;new&lt;/span&gt; StandardKernel();&#xD;
            kernel.Bind&amp;lt;IDataService&amp;gt;().To&amp;lt;SampleDataService&amp;gt;();&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;#region&lt;/span&gt; IDependencyResolver Members&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;object&lt;/span&gt; GetService(Type serviceType)&#xD;
        {&#xD;
            &lt;span &gt;return&lt;/span&gt; kernel.TryGet(serviceType);&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span &gt;object&lt;/span&gt;&amp;gt; GetServices(Type serviceType)&#xD;
        {&#xD;
            &lt;span &gt;return&lt;/span&gt; kernel.GetAll(serviceType);&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;#endregion&lt;/span&gt;&#xD;
    }&#xD;
}&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&#xD;
&lt;p&gt;那么，如何使用这个自定义的处理器呢？&lt;/p&gt;&#xD;
&lt;p&gt;很简单，我们仍然是修改Global.asax文件中的Application_Start方法&lt;/p&gt;&lt;pre &gt;&lt;span &gt;protected&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Application_Start()&#xD;
        {&#xD;
            AreaRegistration.RegisterAllAreas();&#xD;
&#xD;
            RegisterGlobalFilters(GlobalFilters.Filters);&#xD;
            RegisterRoutes(RouteTable.Routes);&#xD;
&#xD;
            &lt;span &gt;//ControllerBuilder.Current.SetControllerFactory(new Extensions.InjectControllerFactory());&lt;/span&gt;&#xD;
&#xD;
            DependencyResolver.SetResolver(&lt;span &gt;new&lt;/span&gt; Extensions.InjectDependencyResolver());&#xD;
        }&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;br&gt;&lt;br&gt;请注意，之前那个设置ControllerFactory的代码，我们可以注释掉了&lt;/p&gt;&#xD;
&lt;p&gt;这个解决方案的最终效果和之前是一样的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118496024.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112122118495501.png" width="634" height="315"&gt;&lt;/a&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本文完整源代码，请通过这里下载 &lt;a title="MvcApplicationDISample.rar" href="http://files.cnblogs.com/chenxizhang/MvcApplicationDISample.rar"&gt;MvcApplicationDISample.rar&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2285304.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/12/12/2285304.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2011/12/11/2284198.html</id><title type="text">在MVC项目中为用户登录失败次数实现提示</title><summary type="text">这两天在给一个客户讲解MVC 3的架构和在项目中的应用，有提到这样一个问题： MVC3 默认实现的Forms Authentication机制，可以结合SQL Server做成员管理，而且可以设置在...</summary><published>2011-12-11T13:27:00Z</published><updated>2011-12-11T13:27:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/11/2284198.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/11/2284198.html"/><content type="html">&lt;p&gt;这两天在给一个客户讲解MVC 3的架构和在项目中的应用，有提到这样一个问题：&lt;/p&gt; &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt; &lt;p&gt;MVC3 默认实现的Forms Authentication机制，可以结合SQL Server做成员管理，而且可以设置在一定时间内如果用户连续输入密码错误达到一定次数的话，就自动将用户锁定。&lt;/p&gt; &lt;p&gt;但是，默认情况下，却没有提供一定的机制，给用户提示，例如你已经输入几次失败了，还最多可以输入几次等等。这在有的时候给用户造成了一些不便。&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;那么，是否有办法解决这个问题呢？&lt;/p&gt; &lt;p&gt;本文源代码，可以通过这里下载 &lt;a title="MvcApplicationSample.rar" href="http://files.cnblogs.com/chenxizhang/MvcApplicationSample.rar"&gt;MvcApplicationSample.rar&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;首先，我们来看一下默认的一些设置和代码&lt;/p&gt; &lt;p&gt;&lt;strong&gt;MemberShip的配置&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;membership&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;providers&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;clear&lt;/span&gt;&lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="AspNetSqlMembershipProvider"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="System.Web.Security.SqlMembershipProvider"&lt;/span&gt; &lt;span &gt;connectionStringName&lt;/span&gt;&lt;span &gt;="ApplicationServices"&lt;/span&gt;&#xD;
             &lt;span &gt;enablePasswordRetrieval&lt;/span&gt;&lt;span &gt;="false"&lt;/span&gt; &lt;span &gt;enablePasswordReset&lt;/span&gt;&lt;span &gt;="true"&lt;/span&gt; &lt;span &gt;requiresQuestionAndAnswer&lt;/span&gt;&lt;span &gt;="false"&lt;/span&gt; &lt;span &gt;requiresUniqueEmail&lt;/span&gt;&lt;span &gt;="false"&lt;/span&gt;&#xD;
             &lt;span &gt;maxInvalidPasswordAttempts&lt;/span&gt;&lt;span &gt;="5"&lt;/span&gt; &lt;span &gt;minRequiredPasswordLength&lt;/span&gt;&lt;span &gt;="6"&lt;/span&gt; &lt;span &gt;minRequiredNonalphanumericCharacters&lt;/span&gt;&lt;span &gt;="0"&lt;/span&gt; &lt;span &gt;passwordAttemptWindow&lt;/span&gt;&lt;span &gt;="10"&lt;/span&gt;&#xD;
             &lt;span &gt;applicationName&lt;/span&gt;&lt;span &gt;="/"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;providers&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;membership&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;上面的配置是默认的，意思是在10分钟内，如果连续输入密码5次错误的话，就锁住用户&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;AccountController中的代码&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;[HttpPost]&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult LogOn(LogOnModel model, &lt;span &gt;string&lt;/span&gt; returnUrl)&#xD;
        {&#xD;
            &lt;span &gt;if&lt;/span&gt;(ModelState.IsValid)&#xD;
            {&#xD;
                &lt;span &gt;if&lt;/span&gt;(Membership.ValidateUser(model.UserName, model.Password))&#xD;
                {&#xD;
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);&#xD;
                    &lt;span &gt;if&lt;/span&gt;(Url.IsLocalUrl(returnUrl) &amp;amp;&amp;amp; returnUrl.Length &amp;gt; 1 &amp;amp;&amp;amp; returnUrl.StartsWith(&lt;span &gt;"/"&lt;/span&gt;)&#xD;
                        &amp;amp;&amp;amp; !returnUrl.StartsWith(&lt;span &gt;"//"&lt;/span&gt;) &amp;amp;&amp;amp; !returnUrl.StartsWith(&lt;span &gt;"/\\"))&#xD;
                    {&#xD;
                        return Redirect(returnUrl);&#xD;
                    }&#xD;
                    else&#xD;
                    {&#xD;
                        return RedirectToAction("&lt;/span&gt;Index&lt;span &gt;", "&lt;/span&gt;Home&lt;span &gt;");&#xD;
                    }&#xD;
                }&#xD;
                else&#xD;
                {&#xD;
&#xD;
                    ModelState.AddModelError("&lt;/span&gt;&lt;span &gt;", "&lt;/span&gt;The user name or password provided &lt;span &gt;is&lt;/span&gt; incorrect.");&#xD;
                }&#xD;
            }&#xD;
&#xD;
            &lt;span &gt;// If we got this far, something failed, redisplay form&lt;/span&gt;&#xD;
            &lt;span &gt;return&lt;/span&gt; View(model);&#xD;
        }&lt;/pre&gt;&#xD;
&lt;p&gt;这里的代码很简单，只要不通过验证的话，就显示一个错误消息：The user name or password provided &lt;span &gt;is&lt;/span&gt; incorrect.&lt;/p&gt;&#xD;
&lt;p&gt;但其实这个消息对用户来说并不是很直观，他不会知道到底是哪里出了错：是用户名不对呢？还是密码不对？甚至说，密码还可以最多输入几次？&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;所以，默认情况下，如果登录不成功，就会看到如下的界面&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/20111211212712960.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112112127146981.png" width="931" height="627"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如果连续输入错误超过5次，就会导致用户再也无法登录，而他没有得到任何提示。我们通过数据库可以看到这个用户已经被锁定了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112112127165750.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112112127179819.png" width="1047" height="129"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;而且在这个表中确实有一个字段是记录了连续输入密码错误的次数&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112112127189951.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112112127203671.png" width="738" height="130"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;那么，接下来看看是否有什么办法解决？我想到的解决方案如下&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;添加一个自定义的MembershipProvider&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;既然默认的Membership Provider提供不了这个功能，那么我们可以尝试自己做一个，想办法去读取这张表应该就能实现&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System.Configuration;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Data.SqlClient;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Web.Security;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; MvcApplicationSample.Extensions&#xD;
{&#xD;
    &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;/// 这是一个自定义的MembershipProvider，添加了一个功能，可以获取用户连续输入密码失败的次数&lt;/span&gt;&#xD;
    &lt;span &gt;/// 作者：陈希章&lt;/span&gt;&#xD;
    &lt;span &gt;/// 反馈：ares@xizhang.com&lt;/span&gt;&#xD;
    &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; MySQLMemberShipProvider:SqlMembershipProvider&#xD;
    {&#xD;
&#xD;
        &lt;span &gt;private&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; connectionString = &lt;span &gt;string&lt;/span&gt;.Empty;&#xD;
&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;override&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Initialize(&lt;span &gt;string&lt;/span&gt; name, System.Collections.Specialized.NameValueCollection config)&#xD;
        {&#xD;
            &lt;span &gt;base&lt;/span&gt;.Initialize(name, config);&#xD;
&#xD;
            &lt;span &gt;//这里获取到默认使用的数据库连接字符串&lt;/span&gt;&#xD;
            connectionString = ConfigurationManager.ConnectionStrings[&lt;span &gt;"ApplicationServices"&lt;/span&gt;].ConnectionString;&#xD;
        }&#xD;
&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;int&lt;/span&gt; GetFailedPasswordAttemptCount(&lt;span &gt;string&lt;/span&gt; userName)&#xD;
        {&#xD;
            &lt;span &gt;using&lt;/span&gt;(var conn = &lt;span &gt;new&lt;/span&gt; SqlConnection(connectionString))&#xD;
            {&#xD;
                &lt;span &gt;using&lt;/span&gt;(var cmd = conn.CreateCommand())&#xD;
                {&#xD;
                    cmd.CommandText = &lt;span &gt;"SELECT aspnet_Membership.FailedPasswordAttemptCount FROM aspnet_Membership INNER JOIN aspnet_Users ON aspnet_Membership.UserId = aspnet_Users.UserId INNER JOIN aspnet_Applications ON aspnet_Membership.ApplicationId =aspnet_Applications.ApplicationId AND aspnet_Users.ApplicationId = aspnet_Applications.ApplicationId WHERE (aspnet_Users.UserName = @userName) AND (aspnet_Applications.ApplicationName =@applicationName)"&lt;/span&gt;;&#xD;
&#xD;
                    cmd.Parameters.AddWithValue(&lt;span &gt;"@userName"&lt;/span&gt;, userName);&#xD;
                    cmd.Parameters.AddWithValue(&lt;span &gt;"@applicationName"&lt;/span&gt;, &lt;span &gt;this&lt;/span&gt;.ApplicationName);&#xD;
&#xD;
                    conn.Open();&#xD;
                    var result = cmd.ExecuteScalar();&#xD;
                    conn.Close();&#xD;
&#xD;
                    &lt;span &gt;if&lt;/span&gt;(result != &lt;span &gt;null&lt;/span&gt;)&#xD;
                    {&#xD;
                        &lt;span &gt;return&lt;/span&gt; (&lt;span &gt;int&lt;/span&gt;)result;&#xD;
                    }&#xD;
                }&#xD;
            }&#xD;
            &lt;span &gt;//如果用户不存在，则返回-1&lt;/span&gt;&#xD;
            &lt;span &gt;return&lt;/span&gt; -1;&#xD;
        }&#xD;
    }&#xD;
}&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;修改web.config使用这个新的membership Provider&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;修改部分为下面粗体的部分&lt;/p&gt;&lt;pre &gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;membership&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;providers&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;clear&lt;/span&gt;&lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;name&lt;/span&gt;&lt;span &gt;="AspNetSqlMembershipProvider"&lt;/span&gt; &lt;span &gt;type&lt;/span&gt;&lt;span &gt;="&lt;strong&gt;MvcApplicationSample.Extensions.MySQLMemberShipProvider,MvcApplicationSample&lt;/strong&gt;"&lt;/span&gt; &lt;span &gt;connectionStringName&lt;/span&gt;&lt;span &gt;="ApplicationServices"&lt;/span&gt;&#xD;
             &lt;span &gt;enablePasswordRetrieval&lt;/span&gt;&lt;span &gt;="false"&lt;/span&gt; &lt;span &gt;enablePasswordReset&lt;/span&gt;&lt;span &gt;="true"&lt;/span&gt; &lt;span &gt;requiresQuestionAndAnswer&lt;/span&gt;&lt;span &gt;="false"&lt;/span&gt; &lt;span &gt;requiresUniqueEmail&lt;/span&gt;&lt;span &gt;="false"&lt;/span&gt;&#xD;
             &lt;span &gt;maxInvalidPasswordAttempts&lt;/span&gt;&lt;span &gt;="5"&lt;/span&gt; &lt;span &gt;minRequiredPasswordLength&lt;/span&gt;&lt;span &gt;="6"&lt;/span&gt; &lt;span &gt;minRequiredNonalphanumericCharacters&lt;/span&gt;&lt;span &gt;="0"&lt;/span&gt; &lt;span &gt;passwordAttemptWindow&lt;/span&gt;&lt;span &gt;="10"&lt;/span&gt;&#xD;
             &lt;span &gt;applicationName&lt;/span&gt;&lt;span &gt;="/"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;providers&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;membership&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;修改AccountController中的代码（请注意粗体部分）&lt;/strong&gt;&lt;/p&gt;&lt;pre &gt;[HttpPost]&#xD;
        &lt;span &gt;public&lt;/span&gt; ActionResult LogOn(LogOnModel model, &lt;span &gt;string&lt;/span&gt; returnUrl)&#xD;
        {&#xD;
            &lt;span &gt;if&lt;/span&gt;(ModelState.IsValid)&#xD;
            {&#xD;
                &lt;span &gt;if&lt;/span&gt;(Membership.ValidateUser(model.UserName, model.Password))&#xD;
                {&#xD;
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);&#xD;
                    &lt;span &gt;if&lt;/span&gt;(Url.IsLocalUrl(returnUrl) &amp;amp;&amp;amp; returnUrl.Length &amp;gt; 1 &amp;amp;&amp;amp; returnUrl.StartsWith(&lt;span &gt;"/"&lt;/span&gt;)&#xD;
                        &amp;amp;&amp;amp; !returnUrl.StartsWith(&lt;span &gt;"//"&lt;/span&gt;) &amp;amp;&amp;amp; !returnUrl.StartsWith(&lt;span &gt;"/\\"))&#xD;
                    {&#xD;
                        return Redirect(returnUrl);&#xD;
                    }&#xD;
                    else&#xD;
                    {&#xD;
                        return RedirectToAction("&lt;/span&gt;Index&lt;span &gt;", "&lt;/span&gt;Home&lt;span &gt;");&#xD;
                    }&#xD;
                }&#xD;
                else&#xD;
                {&#xD;
&#xD;
&#xD;
     &lt;strong&gt;               var provider = (Extensions.MySQLMemberShipProvider)Membership.Provider;&#xD;
                    var count = provider.GetFailedPasswordAttemptCount(model.UserName);&#xD;
                    var max = provider.MaxInvalidPasswordAttempts;&#xD;
&#xD;
                    &#xD;
&#xD;
&#xD;
                    if(count != -1)&#xD;
                    {&#xD;
&#xD;
&#xD;
&#xD;
                        ModelState.AddModelError("&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;span &gt;", count==max?"&lt;/span&gt;Your account &lt;span &gt;is&lt;/span&gt; locked.&lt;span &gt;":string.Format("&lt;/span&gt;You have been continually input the wrong password {0} times, &lt;span &gt;if&lt;/span&gt; then enter {1} mistakes, your account will be locked&lt;/strong&gt;&lt;strong&gt;&lt;span &gt;", count, max - count));&#xD;
                    }&#xD;
                    else&#xD;
                        ModelState.AddModelError("&lt;/span&gt;&lt;span &gt;", "&lt;/span&gt;The user name or password provided &lt;span &gt;is&lt;/span&gt; incorrect.");&lt;/strong&gt;&#xD;
                }&#xD;
            }&#xD;
&#xD;
            &lt;span &gt;// If we got this far, something failed, redisplay form&lt;/span&gt;&#xD;
            &lt;span &gt;return&lt;/span&gt; View(model);&#xD;
        }&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;这样的话，我们来测试一下效果看看&lt;/p&gt;&lt;pre &gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112112127226378.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112112127238495.png" width="931" height="627"&gt;&lt;/a&gt;&lt;/pre&gt;&lt;pre &gt;如果连续输错5次，则提示已经被锁定了&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&lt;pre &gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112112127252248.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/20111211212726220.png" width="931" height="627"&gt;&lt;/a&gt;&lt;/pre&gt;&lt;pre &gt;&lt;/pre&gt;&#xD;
&lt;p&gt;本文源代码，可以通过这里下载 &lt;a title="MvcApplicationSample.rar" href="http://files.cnblogs.com/chenxizhang/MvcApplicationSample.rar"&gt;MvcApplicationSample.rar&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2284198.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/12/11/2284198.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2011/12/06/2278457.html</id><title type="text">如何解决在Windows XP下的IIS 5.1经常出现编号为500的服务器错误</title><summary type="text">传说中，这是一个常见的问题。我自己多年前用Windows XP的时候，倒也没有怎么遇到过。今天因为在讲一个课程的时候，用到了Windows XP作为虚拟机系统，在进行一个Web 服务部署的时候，居然这...</summary><published>2011-12-06T12:54:00Z</published><updated>2011-12-06T12:54:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/06/2278457.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2011/12/06/2278457.html"/><content type="html">&lt;p&gt;传说中，这是一个常见的问题。我自己多年前用Windows XP的时候，倒也没有怎么遇到过。今天因为在讲一个课程的时候，用到了Windows XP作为虚拟机系统，在进行一个Web 服务部署的时候，居然这么走运就遇到了这个问题，课堂上时间紧，一下子也没有排除这个问题。回来后稍微研究了一下，整理出来，给有需要的朋友也参考一下&lt;/p&gt; &lt;p&gt;找问题的解决方案时，我参考了以下这个文章 &lt;a title="http://www.coogg.com/article.asp?id=494" href="http://www.coogg.com/article.asp?id=494"&gt;http://www.coogg.com/article.asp?id=494&lt;/a&gt;&lt;/p&gt; &lt;p&gt;我自己总结下来两个步骤&lt;/p&gt; &lt;p&gt;1.确认如下几个服务，都是设置为自动启动的，并且处于启动状态&lt;/p&gt; &lt;ul&gt; &lt;li&gt;COM+ Event System&lt;/li&gt; &lt;li&gt;COM+ System Application&lt;/li&gt; &lt;li&gt;Distributed Transaction Coordinator（DTC)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;为什么要开这几个服务呢？其实如果熟悉IIS的朋友一定知道，IIS5这个版本，其实是通过COM+实现的一个应用程序，所以自然是依赖COM+服务的，然后IIS可以参与分布式事务协调，所以需要开启DTC服务。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;2. 通过如下的命令对IIS 进行注册。我没有想明白为什么这个还需要手工来注册，可能是今天我们在安装IIS的介质有什么问题，或者说安装的时候，上述几个服务没有开起来导致的？（如果是这样，那也实在有点让人费解）。现在已经无从查证了，总之，这样做了就可以解决问题。&lt;/p&gt; &lt;p&gt;cd c:\WINDOWS\system32\inetsrv&lt;/p&gt; &lt;p&gt;rundll32 wamreg.dll, CreateIISPackage &lt;/p&gt; &lt;p&gt;regsvr32 asptxn.dll&amp;nbsp;&amp;nbsp; &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;经过上面两个步骤，终于可以如愿打开网站了。下面只是一个测试的例子。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112062054248383.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201112/201112062054269660.png" width="710" height="515"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;好长时间不用Windows XP了，也确实有点生疏了。这次是为了方便，做了一个虚拟机，里面安装了所需要的开发环境，采用XP的好处是占用内存稍小一点。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2278457.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/12/06/2278457.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/chenxizhang/archive/2011/11/27/2264826.html</id><title type="text">SQL Server CE 和db4o以及XMLdatabase的应用比较</title><summary type="text">引子 上一篇 (SQL Server、Oracle、db2所提供的简装版(Express)比较) 我针对在应用程序开发中，可能会用到的三款数据库产品的简装版做了一些介绍和比较。如果我们的应用的数据量不...</summary><published>2011-11-27T00:23:00Z</published><updated>2011-11-27T00:23:00Z</updated><author><name>陈希章</name><uri>http://www.cnblogs.com/chenxizhang/</uri></author><link rel="alternate" href="http://www.cnblogs.com/chenxizhang/archive/2011/11/27/2264826.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/chenxizhang/archive/2011/11/27/2264826.html"/><content type="html">&lt;p&gt;&lt;strong&gt;引子&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/11/26/2264558.html"&gt;上一篇&lt;/a&gt; (&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/11/26/2264558.html"&gt;SQL Server、Oracle、db2所提供的简装版(Express)比较&lt;/a&gt;) 我针对在应用程序开发中，可能会用到的三款数据库产品的简装版做了一些介绍和比较。如果我们的应用的数据量不是很大，例如不超过4GB，而且用户的并发情况也不多的话，它们是不错的选择。但有一个问题就是，他们都需要在运行环境中，安装相应的数据库引擎，而且相对来说，所占用的内存还不小。如果我们这个应用是一个针对个人用户或者要在终端用户的桌面上运行的的，那么就可能遇到一个部署的障碍。大家试想一下，有多少人愿意在自己的日常工作的电脑上面安装这样的数据库引擎呢？尤其是他们对这些东西又不熟悉的情况下。你可能会苦口婆心地去跟用户解释，动之以情，晓之以理……不过，请打住，用户会跟你说：“Don’t make me think”，&lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none"  alt="Winking smile" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822567331.png"&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;那么，是否有办法实现，不安装任何数据库引擎的情况下，也能完成类似数据库的存取呢？答案是肯定的。这一篇文章，我同样介绍三个产品给大家参考参考。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;名词定义和介绍&lt;/strong&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;SQL Server CE:全称叫SQL Server Compact Edition。这是从SQL Server 2005开始提供的一个特殊版本。原本叫SQL Server Mobile Edition，顾名思义，是定位用在手机开发中的。不过，期间又改过几次名字，我们就不要深究了。目前而言，这个版本可以用于一些脱机的、本地的存取，它继承了SQL Server的优良传统，提供了与SQL Server一致性的访问体验，并且这个数据库可以很容易地与服务器端的SQL Server实现同步。你可以通过微软官方网站了解更多或者进行下载：&lt;a title="http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid=85E0C3CE-3FA1-453A-8CE9-AF6CA20946C3&amp;amp;displaylang=zh-cn" href="http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid=85E0C3CE-3FA1-453A-8CE9-AF6CA20946C3&amp;amp;displaylang=zh-cn"&gt;http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid=85E0C3CE-3FA1-453A-8CE9-AF6CA20946C3&amp;amp;displaylang=zh-cn&lt;/a&gt;&lt;/li&gt; &lt;li&gt;db4o:全称是Open Source Object–Oriented Database ，顾名思义，它是一个开源的、面向对象的数据库。它基于JAVA和.NET分别做了很好的实现，并且对LINQ做了很好的支持。总体来说，这是一款相当不错的产品。它的官方网站在：&lt;a title="http://db4o.com/" href="http://db4o.com/"&gt;http://db4o.com/&lt;/a&gt;&lt;/li&gt; &lt;li&gt;XMLdatabase：全称就是xml database，这是我自己做的一个轻型的数据库，目前只提供基于.NET版本的实现。与db4o相同的是，这是也是完全面向对象的，并且支持LINQ语法。然后，不同的是，这个数据库将完全采用XML格式存储所有的数据，而不是二进制。这在当前XML统治一切的时代，是有相当的积极意义的。你可以通过 &lt;a title="http://xmldatabase.codeplex.com/" href="http://xmldatabase.codeplex.com/"&gt;http://xmldatabase.codeplex.com/&lt;/a&gt; 了解更多，也可以通过 &lt;a title="http://nuget.org/List/Packages/XMLDatabase" href="http://nuget.org/List/Packages/XMLDatabase"&gt;http://nuget.org/List/Packages/XMLDatabase&lt;/a&gt; 下载使用&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;SQL Server CE&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;如果你本来就比较熟悉SQL Server，并且希望你的这个程序，可以与服务器端实现数据同步，那么你应该优先选用SQL Server CE。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822565346.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822576185.png" width="905" height="617"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;需要注意的是，Local Database Cache是一个特殊的模板，它可以结合Sync Framework实现与服务器端数据库的同步&lt;/p&gt; &lt;p&gt;我们先来看一下简单的Local Database的做法，通过模板创建一个sdf文件之后，双击它，就会自动打开Server Explorer&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822571168.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822572248.png" width="332" height="299"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;在这里，你可以像在服务器一样，添加表（注意，只能添加表，没有其他对象，例如视图，存储过程等）&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822579183.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822573610.png" width="911" height="751"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822576086.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822582705.png" width="326" height="486"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;访问SQL Server CE的数据库，实在太简单了。我们可以用ADO.NET Entity Framework来快速建模和访问。注意，它不支持LINQ to SQL.&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822582116.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822585987.png" width="959" height="664"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822594002.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/2011112708225965.png" width="631" height="562"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270822598396.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823004983.png" width="1028" height="631"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;在应用程序中，你可以通过如下的方式对数据进行查询&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Windows.Forms;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; WindowsFormsApplicationSample&#xD;
{&#xD;
    &lt;span &gt;static&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Program&#xD;
    {&#xD;
        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// The main entry point for the application.&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        [STAThread]&#xD;
        &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Main()&#xD;
        {&#xD;
            Application.EnableVisualStyles();&#xD;
            Application.SetCompatibleTextRenderingDefault(&lt;span &gt;false&lt;/span&gt;);&#xD;
            &#xD;
&#xD;
&#xD;
            &lt;span &gt;//使用LINQ to Entities访问SQL Server CE数据库&lt;/span&gt;&#xD;
&#xD;
            &lt;span &gt;//1.创建数据库上下文&lt;/span&gt;&#xD;
            var ctx = &lt;span &gt;new&lt;/span&gt; UsersEntities();&#xD;
            &lt;span &gt;//2.构造查询&lt;/span&gt;&#xD;
            var query = from u &lt;span &gt;in&lt;/span&gt; ctx.Employees&#xD;
                        &lt;span &gt;where&lt;/span&gt; u.Email.Contains(&lt;span &gt;"xizhang"&lt;/span&gt;)&#xD;
                        select u;&#xD;
            &lt;span &gt;//3.得到结果&lt;/span&gt;&#xD;
            var result = query.ToArray();&#xD;
            &lt;span &gt;//4.执行其他操作（绑定，或者遍历）&lt;/span&gt;&#xD;
        }&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;通过如下的方式对数据库进行修改，例如新增，删除，更新等&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Windows.Forms;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; WindowsFormsApplicationSample&#xD;
{&#xD;
    &lt;span &gt;static&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Program&#xD;
    {&#xD;
        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;/// The main entry point for the application.&lt;/span&gt;&#xD;
        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&#xD;
        [STAThread]&#xD;
        &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Main()&#xD;
        {&#xD;
            Application.EnableVisualStyles();&#xD;
            Application.SetCompatibleTextRenderingDefault(&lt;span &gt;false&lt;/span&gt;);&#xD;
            &#xD;
&#xD;
&#xD;
            &lt;span &gt;//使用LINQ to Entities访问SQL Server CE数据库&lt;/span&gt;&#xD;
&#xD;
            &lt;span &gt;//1.创建数据库上下文&lt;/span&gt;&#xD;
            var ctx = &lt;span &gt;new&lt;/span&gt; UsersEntities();&#xD;
            &lt;span &gt;//2.新增一条记录&lt;/span&gt;&#xD;
            ctx.AddToEmployees(&lt;span &gt;new&lt;/span&gt; Employee() { EmployeeId = 1, FirstName = &lt;span &gt;"ares"&lt;/span&gt;, LastName = &lt;span &gt;"chen"&lt;/span&gt;, Email = &lt;span &gt;"ares@xizhang.com"&lt;/span&gt; });&#xD;
&#xD;
            &lt;span &gt;//3.更新一条记录&lt;/span&gt;&#xD;
            var ares = ctx.Employees.FirstOrDefault(e =&amp;gt; e.FirstName == &lt;span &gt;"ares"&lt;/span&gt;);&#xD;
            &lt;span &gt;if&lt;/span&gt;(ares != &lt;span &gt;null&lt;/span&gt;)&#xD;
                ares.Email = &lt;span &gt;"ares@microsoft.com"&lt;/span&gt;;&#xD;
&#xD;
            &lt;span &gt;//4.删除一条记录&lt;/span&gt;&#xD;
            &lt;span &gt;if&lt;/span&gt;(ares != &lt;span &gt;null&lt;/span&gt;)&#xD;
                ctx.DeleteObject(ares);&#xD;
&#xD;
            &lt;span &gt;//5.以上三个操作，最终都要通过保存才最终能反应到数据库中&lt;/span&gt;&#xD;
            ctx.SaveChanges();&#xD;
&#xD;
        }&#xD;
&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
大家可以看到，这样的语法应该是很好理解。SQL Server CE在这三个产品中，最大的优势就是：它仍然是一个关系型数据库，所有你拥有的关系数据库的知识和经验都可以复用，而且它完全支持XML数据类型。在访问上，它与正常的数据库访问没有什么区别。&lt;/p&gt;&#xD;
&lt;p&gt;更加强大的是，保存在SQL Server CE数据库中可以很方便地与服务器端的SQL Server进行同步。这个功能，需要结合&lt;a href="http://msdn.microsoft.com/zh-cn/library/bb902854.aspx"&gt;Microsoft Sync Framework&lt;/a&gt;. 这对于需要提供脱机支持并且后续需要同步的场景，是多么重要。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823007773.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823001885.png" width="959" height="664"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823011819.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823018198.png" width="816" height="592"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823026180.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823022559.png" width="711" height="464"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;限于篇幅，我这里就不一个一个去截图了，有兴趣的朋友，可以参考 &lt;a title="http://msdn.microsoft.com/zh-cn/library/bb726002.aspx" href="http://msdn.microsoft.com/zh-cn/library/bb726002.aspx"&gt;http://msdn.microsoft.com/zh-cn/library/bb726002.aspx&lt;/a&gt; 进行一些动手实验。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;db4o&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这是我见过最好的一个嵌入式、面向对象的数据库之一。目前针对.NET 4.0和3.5都分别有安装程序，并且甚至还提供了对Silverlight的支持。&lt;/p&gt;&#xD;
&lt;p&gt;总体而言，它的核心理念是面向对象，就是说，我们可以忘记数据库，忘记SQL语句。我们所有的操作都是利用对象的方式来实现。下面的代码摘自官方提供的Tutorial。可以很清晰地看到它的用法：增、删、改、查&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.IO;&#xD;
&lt;span &gt;using&lt;/span&gt; Db4objects.Db4o;&#xD;
&lt;span &gt;using&lt;/span&gt; Db4objects.Db4o.Query;&#xD;
&lt;span &gt;using&lt;/span&gt; Db4odoc.Tutorial;&#xD;
&lt;span &gt;namespace&lt;/span&gt; Db4odoc.Tutorial.F1.Chapter1&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; FirstStepsExample : Util&#xD;
    {&#xD;
        &lt;span &gt;readonly&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; YapFileName = Path.Combine(&#xD;
                               Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),&#xD;
                               &lt;span &gt;"formula1.yap"&lt;/span&gt;);&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Main(&lt;span &gt;string&lt;/span&gt;[] args)&#xD;
        {&#xD;
            File.Delete(YapFileName);&#xD;
            AccessDb4o();&#xD;
            File.Delete(YapFileName);&#xD;
            &lt;span &gt;using&lt;/span&gt;(IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))&#xD;
            {&#xD;
                StoreFirstPilot(db);&#xD;
                StoreSecondPilot(db);&#xD;
                RetrieveAllPilots(db);&#xD;
                RetrievePilotByName(db);&#xD;
                RetrievePilotByExactPoints(db);&#xD;
                UpdatePilot(db);&#xD;
                DeleteFirstPilotByName(db);&#xD;
                DeleteSecondPilotByName(db);&#xD;
            }&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; AccessDb4o()&#xD;
        {&#xD;
            &lt;span &gt;using&lt;/span&gt;(IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))&#xD;
            {&#xD;
                &lt;span &gt;// do something with db4o&lt;/span&gt;&#xD;
            }&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; StoreFirstPilot(IObjectContainer db)&#xD;
        {&#xD;
            Pilot pilot1 = &lt;span &gt;new&lt;/span&gt; Pilot(&lt;span &gt;"Michael Schumacher"&lt;/span&gt;, 100);&#xD;
            db.Store(pilot1);&#xD;
            Console.WriteLine(&lt;span &gt;"Stored {0}"&lt;/span&gt;, pilot1);&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; StoreSecondPilot(IObjectContainer db)&#xD;
        {&#xD;
            Pilot pilot2 = &lt;span &gt;new&lt;/span&gt; Pilot(&lt;span &gt;"Rubens Barrichello"&lt;/span&gt;, 99);&#xD;
            db.Store(pilot2);&#xD;
            Console.WriteLine(&lt;span &gt;"Stored {0}"&lt;/span&gt;, pilot2);&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; RetrieveAllPilotQBE(IObjectContainer db)&#xD;
        {&#xD;
            Pilot proto = &lt;span &gt;new&lt;/span&gt; Pilot(&lt;span &gt;null&lt;/span&gt;, 0);&#xD;
            IObjectSet result = db.QueryByExample(proto);&#xD;
            ListResult(result);&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; RetrieveAllPilots(IObjectContainer db)&#xD;
        {&#xD;
            IObjectSet result = db.QueryByExample(&lt;span &gt;typeof&lt;/span&gt;(Pilot));&#xD;
            ListResult(result);&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; RetrievePilotByName(IObjectContainer db)&#xD;
        {&#xD;
            Pilot proto = &lt;span &gt;new&lt;/span&gt; Pilot(&lt;span &gt;"Michael Schumacher"&lt;/span&gt;, 0);&#xD;
            IObjectSet result = db.QueryByExample(proto);&#xD;
            ListResult(result);&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; RetrievePilotByExactPoints(IObjectContainer db)&#xD;
        {&#xD;
            Pilot proto = &lt;span &gt;new&lt;/span&gt; Pilot(&lt;span &gt;null&lt;/span&gt;, 100);&#xD;
            IObjectSet result = db.QueryByExample(proto);&#xD;
            ListResult(result);&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; UpdatePilot(IObjectContainer db)&#xD;
        {&#xD;
            IObjectSet result = db.QueryByExample(&lt;span &gt;new&lt;/span&gt; Pilot(&lt;span &gt;"Michael Schumacher"&lt;/span&gt;, 0));&#xD;
            Pilot found = (Pilot)result.Next();&#xD;
            found.AddPoints(11);&#xD;
            db.Store(found);&#xD;
            Console.WriteLine(&lt;span &gt;"Added 11 points for {0}"&lt;/span&gt;, found);&#xD;
            RetrieveAllPilots(db);&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; DeleteFirstPilotByName(IObjectContainer db)&#xD;
        {&#xD;
            IObjectSet result = db.QueryByExample(&lt;span &gt;new&lt;/span&gt; Pilot(&lt;span &gt;"Michael Schumacher"&lt;/span&gt;, 0));&#xD;
            Pilot found = (Pilot)result.Next();&#xD;
            db.Delete(found);&#xD;
            Console.WriteLine(&lt;span &gt;"Deleted {0}"&lt;/span&gt;, found);&#xD;
            RetrieveAllPilots(db);&#xD;
        }&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; DeleteSecondPilotByName(IObjectContainer db)&#xD;
        {&#xD;
            IObjectSet result = db.QueryByExample(&lt;span &gt;new&lt;/span&gt; Pilot(&lt;span &gt;"Rubens Barrichello"&lt;/span&gt;, 0));&#xD;
            Pilot found = (Pilot)result.Next();&#xD;
            db.Delete(found);&#xD;
            Console.WriteLine(&lt;span &gt;"Deleted {0}"&lt;/span&gt;, found);&#xD;
            RetrieveAllPilots(db);&#xD;
        }&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;要使用它，其实很简单，只需要添加一个引用即可&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823039918.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/chenxizhang/201111/201111270823044030.png" width="751" height="624"&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;同时，它也提供了一个可视化的工具，可以查看数据库里面所有对象。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;XMLDatabase&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这是我在2009年设计的一个完全基于XML，面向对象的数据库。这个数据库的最终可执行的组件以及源代码，请通过下面地址访问&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://xmldatabase.codeplex.com/" href="http://xmldatabase.codeplex.com/"&gt;http://xmldatabase.codeplex.com/&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我之前有几篇文章详细介绍了设计的考虑和使用用法&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2009/08/09/1542354.html"&gt;XML数据库一睹为快&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2009/08/12/1544105.html"&gt;XML数据库的有关架构和细节说明&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2009/08/31/1557545.html"&gt;XML数据库之alpha发布&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;今年，我整理了一下，重新发布到了Nuget Gallary，所以，你要使用的话，会更加简单，如果你使用的是Visual Studio 2010的话&lt;/p&gt;&#xD;
&lt;p&gt;关于如何使用，请参考下面这篇文章的详细介绍，这里就不重复了&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/06/25/2090180.html"&gt;XMLDatabase项目已经发布到nuget gallery&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本文介绍了三款可用于本地、脱机存储应用程序开发的数据库解决方案。SQL Server Compact Edition与SQL Server一脉相承，使用关系型数据库的机制，提供了一致的数据访问体验。db4o和XMLDatabase都是开源的面向对象数据库，都支持LINQ语法，db4o是用二进制保存数据，而XMLDatabase是以XML格式存储所有数据的。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/chenxizhang/aggbug/2264826.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/chenxizhang/archive/2011/11/27/2264826.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
