<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_namespace Ivony</title><subtitle type="text">DbUtility - XCommunity - Jumony - ?上海 - 北京 - 深圳 - ?</subtitle><id>http://feed.cnblogs.com/blog/u/17776/rss</id><updated>2012-03-14T03:50:13Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/17776/rss"/><entry><id>http://www.cnblogs.com/Ivony/archive/2011/11/03/2233847.html</id><title type="text">尝鲜Jumony for MVC，体验插件化网站开发</title><summary type="text">Jumony for MVC是这一年来Jumony项目的重头戏，Jumony for MVC是Jumony技术与ASP.NET MVC的结合，尽管现在Jumony for MVC还未发布稳定版本，但确实是非常值得一试的一个视图引擎。希望这篇文章能给大家带来眼前一亮的感觉。 在“用网站（WebSite而不是WebProject）项目构建ASP.NET MVC网站”文章中，我已经说明了如何在网站项目...</summary><published>2011-11-02T18:07:00Z</published><updated>2011-11-02T18:07:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2011/11/03/2233847.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2011/11/03/2233847.html"/><content type="html">&lt;p&gt;Jumony for MVC是这一年来Jumony项目的重头戏，Jumony for MVC是Jumony技术与ASP.NET MVC的结合，尽管现在Jumony for MVC还未发布稳定版本，但确实是非常值得一试的一个视图引擎。希望这篇文章能给大家带来眼前一亮的感觉。&lt;/p&gt;  &lt;p&gt;在“&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/10/30/2229627.html"&gt;用网站（WebSite而不是WebProject）项目构建ASP.NET MVC网站&lt;/a&gt;”文章中，我已经说明了如何在网站项目上搭建MVC框架，那么这一次，我同样在网站项目上搭建Jumony for MVC。如果您已经安装了NuGet，这一切将变得非常简单，如果还没有，那么可以到NuGet的官方网站（&lt;a href="http://www.nuget.org/"&gt;http://www.nuget.org/&lt;/a&gt;）上下载，或者通过VS2010的扩展管理器直接搜索安装。由于Jumony for MVC要求.NET 4.0的环境，所以这一篇文章将基于VS2010 + .NET Framework 4.0 + NuGet等这些高科技武器来介绍，如果你缺乏其中的任何一样，说明你该升级你的装备了。&lt;/p&gt;  &lt;p&gt;关于NuGet的使用，博客园也有很多文章介绍，例如dudu的这篇：&lt;a href="http://www.cnblogs.com/dudu/archive/2011/07/15/nuget.html"&gt;http://www.cnblogs.com/dudu/archive/2011/07/15/nuget.html&lt;/a&gt;。在这篇文章中，我假定大家了解NuGet的基本用法，其实NuGet用起来很简单的。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;一、安装Jumony for MVC&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;废话不多说，首先，当然还是要建立一个解决方案。然后，新建一个空白的网站：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205253776.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205264167.png" width="317" height="117" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;掏空web.config中多余的设置：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205284318.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/20111103020529806.png" width="433" height="175" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;然后通过NuGet安装Jumony for MVC的预览版。首先在网站上点击右键，选择Manage NuGet Packages&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205335982.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205389391.png" width="431" height="695" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;在搜索框中输入Jumony，然后选择Jumony for MVC，点击旁边的Install按钮&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205445732.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205509739.png" width="804" height="454" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;当跳出许可协议时，选择Accept（Jumony采用LGPL协议发布）。然后NuGet就会开始下载Jumony for MVC的预览版，同时安装到网站中。&lt;/p&gt;  &lt;p&gt;安装完毕后网站应该是这样的：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205537740.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030205569046.png" width="315" height="247" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;同时web.config文件会被修改，添加大量配置，这些配置已经足够在网站项目运行MVC框架了。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;二、准备Controller&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;然后我们开始来构建我们的第一个Controller，这一次我们尝试用一个独立的项目来承载Controller，这是插件化的第一步。那么新建一个项目，我命名为Demo.Test，这个项目仅仅用来测试我们的环境：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/20111103020558276.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206003666.png" width="319" height="89" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;为这个项目添加System.Web.Mvc的引用，这里可能要特别注意版本，Jumony for MVC默认是使用MVC2的，所以这里也添加MVC2的引用。&lt;/p&gt;  &lt;p&gt;当然你也可以修改web.config中的MVC程序集的版本。要确保你的Controller项目所引用MVC的版本和网站所引用的一致，否则就要添加MVC版本兼容的配置了，我在这里不详述。就用MVC2来做示范。&lt;/p&gt;  &lt;p&gt;添加引用后，就可以删除默认的cs文件，添加一个Controller，我命名为TestController，然后往里面随便塞一个Action，像这样：&lt;/p&gt;  &lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt; System;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Collections.Generic;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Linq;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Text;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Web.Mvc;&lt;br/&gt; &lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;namespace&lt;/font&gt;&lt;/span&gt; Demo.Test&lt;br/&gt;{&lt;br /&gt;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;TestController&lt;/font&gt;&lt;/span&gt; : &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Controller&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;ActionResult&lt;/font&gt;&lt;/span&gt; Index()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#008000"&gt;//这个Action就是输出一个视图&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; View();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160; }&lt;br/&gt;}&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;OK，接下来是配置路由，如果路由都在global.asax中配置，那是多么没有创意的事情，而且，这会造成所有的功能都要到那边去配置一下，不利于我们所追求的插件化。所以，这一次我在Controller程序集里面配置路由，这样，只要这个程序集的DLL放在了网站的bin文件夹，那么路由就自动被配置了，是不是很酷呢？这么酷的功能利用ASP.NET 4的新特性其实非常好实现。首先我们要添加System.Web程序集的引用，然后添加如下代码：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;[&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;assembly&lt;/font&gt;&lt;/span&gt;: System.Web.&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;PreApplicationStartMethod&lt;/font&gt;&lt;/span&gt;( &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/span&gt;( Demo.Test.&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RoutingRegister&lt;/font&gt;&lt;/span&gt; ), &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;RegisterRouting&amp;quot;&lt;/font&gt;&lt;/span&gt; )]&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;namespace&lt;/font&gt;&lt;/span&gt; Demo.Test&lt;br/&gt;{&lt;br /&gt;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RoutingRegister&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; RegisterRouting()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160; }&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;注意PreApplicationStartMethod这个特性要注册在程序集范畴（assembly），所以除了在前面要加上assembly:之外，还需要放到namespace块的外面去。&lt;/p&gt;&lt;p&gt;通过这样的代码，我们就能确保在网站应用程序启动前执行RegisterRouting这个方法了，所以，我们可以在这里添加路由注册的代码。不过在这里，我要向大家介绍一下Jumony for MVC提供的一个MVC框架改善，简单路由表（SimpleRoutingTable）。&lt;/p&gt;&lt;p&gt;首先，通过同样的方法，利用NuGet为这个项目添加Jumony for MVC的引用。然后引用Jumony for MVC的命名空间Ivony.Html.Web.Mvc，最后在RegisterRouting方法中注册一个路由：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; RegisterRouting()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MvcEnvironment&lt;/font&gt;&lt;/span&gt;.SimpleRoutingTable.MapAction( &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;~/&amp;quot;&lt;/font&gt;&lt;/span&gt;, &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Test&amp;quot;&lt;/font&gt;&lt;/span&gt;, &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Index&amp;quot;&lt;/font&gt;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;简单路由表的实例总是可以通过MvcEnvironment静态类型来获取，通过同样的手法，Jumony for MVC会自动为系统注册简单路由表为一个路由服务。在这里简单说一下简单路由表相对于ASP.NET Routing默认实现的一部分改善。&lt;/p&gt;&lt;ol&gt;  &lt;li&gt;首先是简单路由表没有RouteTable的先到先得的原则，在简单路由表中的路由规则遵循的是谁更适合就选谁的原则，这更符合使用者的直觉。也使得我们可以把路由规则注册分散到各个项目，即使这些路由规则被注册的时间不可控。（这可是插件化的关键问题之一） &lt;/li&gt;  &lt;li&gt;由于简单路由表遵循的是谁更适合的原则，所以简单路由表不允许注册存在冲突的路由规则，这样更不容易犯错。 &lt;/li&gt;  &lt;li&gt;简单路由表取消了复杂的概念，像上面那个路由规则，其实非常简单，就是在&amp;quot;~/&amp;quot;这个虚拟路径和{ controller: Test, action: Test }之间建立一个对应的关系。取消了默认值和有效值的概念，尽管牺牲了灵活性，但提高了对URL的可控性。不会产生令人惊讶的结果。 &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;简单路由表事实上只是RouteBase的一个实现（也就是一个路由），所以尽管通过简单路由表注册的路由规则没有先到先得的规则，但简单路由表与其他RouteBase实现一起在RouteTable中仍然遵循ASP.NET框架所设定的先到先得规则。关于这一点，我在后面的系列文章中再详细的讨论简单路由表。&lt;/p&gt;&lt;p&gt;最终的代码像这样：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt; System;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Collections.Generic;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Linq;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Text;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Web.Mvc;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; Ivony.Html.Web.Mvc;&lt;br/&gt; &lt;br/&gt;[&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;assembly&lt;/font&gt;&lt;/span&gt;: System.Web.&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;PreApplicationStartMethod&lt;/font&gt;&lt;/span&gt;( &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/span&gt;( Demo.Test.&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RoutingRegister&lt;/font&gt;&lt;/span&gt; ), &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;RegisterRouting&amp;quot;&lt;/font&gt;&lt;/span&gt; )]&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;namespace&lt;/font&gt;&lt;/span&gt; Demo.Test&lt;br/&gt;{&lt;br /&gt;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RoutingRegister&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; RegisterRouting()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MvcEnvironment&lt;/font&gt;&lt;/span&gt;.SimpleRoutingTable.MapAction( &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;~/&amp;quot;&lt;/font&gt;&lt;/span&gt;, &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Test&amp;quot;&lt;/font&gt;&lt;/span&gt;, &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Index&amp;quot;&lt;/font&gt;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;TestController&lt;/font&gt;&lt;/span&gt; : &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Controller&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;ActionResult&lt;/font&gt;&lt;/span&gt; Index()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#008000"&gt;//这个Action就是输出一个视图&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; View();&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160; }&lt;br/&gt;}&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;&lt;strong&gt;三、配置视图&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Controller和路由都已经配置完毕，现在回到网站，我们为网站添加刚刚Demo.Test项目的引用：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206035811.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206068022.png" width="501" height="401" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;然后生成网站，运行之，检查我们的路由和Controller是否正常运行。（记得一定要先生成网站，这样我们的Demo.Test才会被编译为DLL并放到bin文件夹）。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206122444.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206164981.png" width="611" height="633" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;如果您看到的是这个界面，就说明已经成功了。细心的您可能已经发现，查找路径中已然包含了html文件的查找，这就是JumonyViewEngine被注册的结果。这一切都是通过同样的手法（&lt;span style="color: "&gt;PreApplicationStartMethod特性）&lt;/span&gt;在悄声无息中完成的。&lt;/p&gt;&lt;p&gt;那么接下来就是弄一个视图出来，我比较习惯把所有视图页面都放在Views目录下，不要带上Controller名字的文件夹，所以我弄了一个index.html文件放在Views文件夹下：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206188196.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206191095.png" width="311" height="147" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;内容就像这样子：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;lt;!&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;DOCTYPE&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;html&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;PUBLIC&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;br/&gt; &lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;html&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;xmlns&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;head&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;title&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;Hello Jumony&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;title&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;head&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; Jumony for MVC&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;html&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;因为不是放在指定的位置，所以我们需要修改一下JumonyViewEngine的设置，打开global.asax文件，修改为下面这样：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; Application_Start( &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;object&lt;/font&gt;&lt;/span&gt; sender, &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;EventArgs&lt;/font&gt;&lt;/span&gt; e )&lt;br /&gt;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MvcEnvironment&lt;/font&gt;&lt;/span&gt;.JumonyViewEngine.ViewLocationFormats = &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;[] { &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;~/Views/{0}.html&amp;quot;&lt;/font&gt;&lt;/span&gt; };&lt;br /&gt;&amp;#160; }&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;要搜索多个路径，可以在数组中多添加几个路径模版。当修改完了后，再次打开网站应该是这样了：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206211487.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201111/20111103020622242.png" width="611" height="257" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;四、留言板&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;当然这个网站毫无意义，我们做个有意义的东西，留言板，只包含两个功能添加留言和浏览留言的留言板（尽管还是没啥意义，但是Demo，大家总不能让我弄个论坛来做示范）。&lt;/p&gt;&lt;p&gt;以前做网站都是需要先出来页面，程序才开始动手，那么这一次，我们可以先不要管页面，先构建留言板的功能实现，即Controller实现。&lt;/p&gt;&lt;p&gt;同样的，我新建了一个独立的项目：Demo.MessageController，添加引用创建Controller的过程和之前一样，在此不再赘述，最终实现的Controller像这样：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;using&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt; System;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Collections.Generic;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Linq;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Text;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Web.Mvc;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Web;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.Web.Hosting;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; System.IO;&lt;br/&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; Ivony.Html.Web.Mvc;&lt;br/&gt; &lt;br/&gt;[&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;assembly&lt;/font&gt;&lt;/span&gt;: System.Web.&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;PreApplicationStartMethod&lt;/font&gt;&lt;/span&gt;( &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/span&gt;( Demo.MessageBoard.&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RoutingRegister&lt;/font&gt;&lt;/span&gt; ), &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;RegisterRouting&amp;quot;&lt;/font&gt;&lt;/span&gt; )]&lt;br /&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;namespace&lt;/font&gt;&lt;/span&gt; Demo.MessageBoard&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;RoutingRegister&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; RegisterRouting()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MvcEnvironment&lt;/font&gt;&lt;/span&gt;.SimpleRoutingTable.MapAction( &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;~/messages&amp;quot;&lt;/font&gt;&lt;/span&gt;, &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;MessageBoard&amp;quot;&lt;/font&gt;&lt;/span&gt;, &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;List&amp;quot;&lt;/font&gt;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MvcEnvironment&lt;/font&gt;&lt;/span&gt;.SimpleRoutingTable.MapAction( &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;~/messages/add&amp;quot;&lt;/font&gt;&lt;/span&gt;, &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;MessageBoard&amp;quot;&lt;/font&gt;&lt;/span&gt;, &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;add&amp;quot;&lt;/font&gt;&lt;/span&gt; );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;MessageBoardController&lt;/font&gt;&lt;/span&gt; : &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Controller&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; {&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;const&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; dataPath = &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;~/Data&amp;quot;&lt;/font&gt;&lt;/span&gt;;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; physicalPath;&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;protected&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; OnActionExecuting( &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;ActionExecutingContext&lt;/font&gt;&lt;/span&gt; filterContext )&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; physicalPath = &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;HostingEnvironment&lt;/font&gt;&lt;/span&gt;.MapPath( dataPath );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Directory&lt;/font&gt;&lt;/span&gt;.CreateDirectory( physicalPath );&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;base&lt;/font&gt;&lt;/span&gt;.OnActionExecuting( filterContext );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;ActionResult&lt;/font&gt;&lt;/span&gt; List()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt; messages = &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;DirectoryInfo&lt;/font&gt;&lt;/span&gt;( physicalPath )&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .EnumerateFiles()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .OrderBy( file =&amp;gt; file.CreationTime )&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Select( file =&amp;gt; System.IO.&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.ReadAllText( file.FullName ) );&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; View( &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;Message_List&amp;quot;&lt;/font&gt;&lt;/span&gt;, messages );&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;ActionResult&lt;/font&gt;&lt;/span&gt; Add( &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; message )&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt; filepath = &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Path&lt;/font&gt;&lt;/span&gt;.Combine( physicalPath, &lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;Guid&lt;/font&gt;&lt;/span&gt;.NewGuid().ToString() + &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;.txt&amp;quot;&lt;/font&gt;&lt;/span&gt; );&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; System.IO.&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.WriteAllText( filepath, message );&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt; RedirectToAction( &lt;span style="color: "&gt;&lt;font color="#a31515"&gt;&amp;quot;List&amp;quot;&lt;/font&gt;&lt;/span&gt; );&lt;br /&gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt; &lt;br /&gt;&amp;#160; }&lt;br /&gt; &lt;br /&gt;}&lt;/font&gt;&lt;/font&gt;&lt;p&gt;两个Action，简单明了，为了避免配置数据库等麻烦事儿，这里直接用文件系统担任了数据库，所有的留言都以文本文件保存了下来。然后我们为网站添加这个功能，也就是让网站项目引用这个 Controller所在的项目。&lt;/p&gt;&lt;p&gt;然后要为这个留言板提供一个视图，在List这个Action中，已经显示指定了视图的名称，Message_List。所以我在Views文件夹添加了这样一个HTML文件：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206242519.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/Ivony/201111/201111030206264273.png" width="313" height="301" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;内容如下：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;lt;!&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;DOCTYPE&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;html&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;PUBLIC&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;html&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;xmlns&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;head&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;title&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;留言板&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;title&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;style&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;font-size&lt;/font&gt;&lt;/span&gt;: &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;12px&lt;/font&gt;&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;margin&lt;/font&gt;&lt;/span&gt;: &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;10px&lt;/font&gt;&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#800000"&gt;.message&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;margin&lt;/font&gt;&lt;/span&gt;: &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;15px&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;0px&lt;/font&gt;&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;border&lt;/font&gt;&lt;/span&gt;: &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;dashed&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;1px&lt;/font&gt;&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;padding&lt;/font&gt;&lt;/span&gt;: &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;10px&lt;/font&gt;&lt;/span&gt;;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;style&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;head&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt; &lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;div&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;message&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;div&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;form&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;method&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;action&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;Add&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;controller&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;div&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;textarea&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;id&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;message&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;name&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;message&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;style&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;width&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;: &lt;/span&gt;&lt;span style="color: "&gt;500px&lt;/span&gt;&lt;span style="color: "&gt;; &lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;height&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;: &lt;/span&gt;&lt;span style="color: "&gt;100px&lt;/span&gt;&lt;span style="color: "&gt;;&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;textarea&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;div&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;div&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;input&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;type&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;submit&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;value&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;提交留言&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;/&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;div&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;form&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;html&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;注意form标签里面的属性，这样写的意思就是，提交到相同Controller的名为Add的Action去。这就是Jumony视图引擎，自然流畅。由于action本来就是标准form元素的一个属性，所以加一个controller强调不是提交到Add这个URL，controller不设置值，则会从当前上下文继承。&lt;/p&gt;&lt;p&gt;接下来我们在那个测试首页添加一个链接，让我们可以访问到留言板的页面：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;lt;!&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;DOCTYPE&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;html&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;PUBLIC&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;br /&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;html&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;xmlns&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;head&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;title&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;Hello Jumony&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;title&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;head&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;action&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;List&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;controller&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;MessageBoard&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;MessageBoard&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;body&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;html&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;&amp;lt;a&amp;gt;标签中的action和controller就不解释了，这时候再打开网站，看到的应该是这样的效果：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206278808.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/Ivony/201111/201111030206286517.png" width="387" height="233" /&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/Ivony/201111/201111030206309416.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/Ivony/201111/201111030206313429.png" width="529" height="307" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;我们可以随便留言，但提交后，页面一闪而过，还是老样子。这是因为我们还没有为留言板页面绑定留言数据。&lt;/p&gt;&lt;p&gt;Jumony现阶段对这种简单重复N次的工作并不比WebForm或是Razor好，所以我决定将绑定数据外包给WebForm来做，顺便也可以看看Jumony for MVC是如何与其他视图引擎无缝兼容的。&lt;/p&gt;&lt;p&gt;WebFormViewEngine的视图查找逻辑也是可以修改的，但比较麻烦，所以这一次我决定按照他的规则，新建一个Shared文件夹，在下面创建一个部分视图。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/201111030206331627.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/Ivony/201111/201111030206343065.png" width="293" height="225" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;如何在网站创建WebFormViewEngine的视图已经在上一篇文章中探讨过，主要就是设置Inherits属性，作为用户控件（部分视图），应从ViewUserControl继承，以下是部分视图完整代码：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffff00"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;lt;%&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;@&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;Control&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;Language&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;C#&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;ClassName&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;MessageListPartial&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;Inherits&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;System.Web.Mvc.ViewUserControl&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffff00"&gt;%&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffff00"&gt;&amp;lt;%&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;&lt;/span&gt; ( &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt; message &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt;&lt;/span&gt; (&lt;span style="color: "&gt;&lt;font color="#2b91af"&gt;IEnumerable&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&amp;gt;) Model )&lt;br /&gt;&amp;#160; {&lt;br /&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffff00"&gt;%&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;div&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;message&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&amp;#160; &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffff00"&gt;&amp;lt;%&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;message &lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffff00"&gt;%&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;div&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;br /&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffff00"&gt;&amp;lt;%&lt;/font&gt;&lt;/span&gt; }&lt;/font&gt;&lt;span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%"&gt;&lt;font style="background-color: #ffff00; font-size: 9.8pt"&gt;%&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;p&gt;当然，如果用Razor，这里的代码能够更为简洁和优雅。&lt;/p&gt;&lt;p&gt;接下来是如何将这个部分视图拼合到Jumony视图引擎的html视图中去，其实也非常简单，使用partial标签，将原来的&amp;lt;div class=&amp;quot;message&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;修改为这样：&lt;/p&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;#160; &lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;partial&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;view&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;MessageListPartial&amp;quot;&lt;/span&gt;&lt;span style="color: "&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;partial&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br/&gt;&lt;/font&gt;&lt;/font&gt;&lt;p&gt;重新打开留言板看看，应该可以看到留言了：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201111/20111103020636425.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/Ivony/201111/201111030206385177.png" width="587" height="431" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Jumony for MVC，值得您关注。。。。。&lt;/p&gt;&lt;p&gt;&lt;a href="http://jumony.codeplex.com/"&gt;http://jumony.codeplex.com/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/2233847.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/11/03/2233847.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2011/10/30/2229627.html</id><title type="text">用网站（WebSite而不是WebProject）项目构建ASP.NET MVC网站</title><summary type="text">从ASP.NET MVC第一个版本开始到现在，创建ASP.NET MVC项目的官方方法只有一个，“文件”-&gt;“新建”-&gt;“项目”，然后选择ASP.NET MVC X Web应用程序。 这种方式当然有其好处，但是很多时候，网站项目（WebSite）而不是Web应用程序（WebProject）更适合大型网站，能更充分的利用ASP.NET的优势，创建可伸缩性更好的网站出来。 其实说到底，ASP....</summary><published>2011-10-30T14:30:00Z</published><updated>2011-10-30T14:30:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2011/10/30/2229627.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2011/10/30/2229627.html"/><content type="html">&lt;p&gt;从ASP.NET MVC第一个版本开始到现在，创建ASP.NET MVC项目的官方方法只有一个，“文件”-&amp;gt;“新建”-&amp;gt;“项目”，然后选择ASP.NET MVC X Web应用程序。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229102183.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229123621.png" width="471" height="417" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;这种方式当然有其好处，但是很多时候，网站项目（WebSite）而不是Web应用程序（WebProject）更适合大型网站，能更充分的利用ASP.NET的优势，创建可伸缩性更好的网站出来。&lt;/p&gt;  &lt;p&gt;其实说到底，ASP.NET MVC也不过就是一个ASP.NET的一个扩展框架而已，所以网站项目当然也能用上MVC，并且，可以用的更好。&lt;/p&gt;  &lt;p&gt;事实上，在Jumony的项目中，关于Jumony for MVC的范例就是用的网站项目而不是Web应用程序。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;接下来，我就用VS2010 + ASP.NET 4（包含 MVC 2）来演示如何在网站项目用上ASP.NET MVC。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;那么首先，我们先要创建一个解决方案和一个网站（似乎是废话），像下面这样：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229131570.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229149278.png" width="259" height="251" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;font color="#a5a5a5"&gt;因为我使用了VS的一个插件，所以解决方案浏览器可能与你电脑上的看起来不太一样，不要担心，这是正常的。&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;然后，其实除了Global.asax和web.config之外的所有东西都是多余的，删除之，我们得到了一个空白的网站：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229152244.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229168208.png" width="253" height="111" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;继续，我们为网站添加ASP.NET MVC框架的引用，这里我添加的是ASP.NET MVC 2的，其实也就一个System.Web.Mvc：&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229181108.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229195403.png" width="492" height="274" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;添加后应该在web.config中能看到这一引用：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229208368.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229204714.png" width="777" height="103" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;然后我们添加一个Controller，Controller是一个类型，我们直接为网站项目添加一个TestController类型就可以了（注意Controller类型名称必须以Controller结尾）：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229265756.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229307279.png" width="959" height="664" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;然后会提示要不要把类型文件放在App_Code，那么显然，然后网站像这样：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229314704.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229311050.png" width="259" height="113" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;注意请一定要将代码文件放在App_Code中，或者引用的第三方项目中，否则不是一个合法的网站项目，这和WebProject是完全不同的。&lt;/p&gt;  &lt;p&gt;我们修改TestController类，使其继承于Controller，删去默认的构造函数，然后随便弄一个Action出来，所谓Action就是返回ActionResult的一个方法而已：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/20111030222932428.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229333393.png" width="337" height="265" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;接下来是配置路由，先给网站添加另一个项目的引用：System.Web.Routing，方法与添加System.Web.Mvc一样，不再赘述。&lt;/p&gt;  &lt;p&gt;然后打开global.asax文件，在App_Start方法中添加路由注册的代码，像这样：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/20111030222935720.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229353129.png" width="661" height="163" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;注意上面的@Import指令，如果你没有智能提示，或是没有看到MapRoute这个扩展方法，检查一下是不是有这个Import。&lt;/p&gt;  &lt;p&gt;每个页面都添加@Import指令是非常麻烦的，所以我们可以在web.config中稍作配置：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/20111030222937489.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229383945.png" width="805" height="359" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;这是我修改后的web.config文件，我删去了其他所有的乱七八糟的东西。&lt;/p&gt;  &lt;p&gt;接下来就可以测试一下路由是不是正确了，如果你完全依照上面的方法做了的话，现在右击网站，选择在浏览器中查看，应该会看到这样一个页面：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302229553209.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302230034924.png" width="1057" height="806" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;如果是404错误或者其他错误，请检查是不是设置了什么起始页之类，或是web.config配置有误。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;OK，我现在假定你看到了和我看到的一样的错误页，这个错误页说明我们已经成功部署了MVC环境，但还缺最后一个东西，“视图”。&lt;/p&gt;  &lt;p&gt;接下来在网站根目录创建一个Views目录，接着在里面创建Test子目录，往里面添加一个Test.aspx文件：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302230075890.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302230114000.png" width="959" height="664" /&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/Ivony/201110/201110302230137771.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/20111030223015605.png" width="251" height="159" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;但这个aspx文件还不能直接当作MVC的视图，因为MVC默认的WebFormViewEngine对视图页还有一些特殊的要求，但事实上也很简单，只需要打开这个aspx文件，把@Page指令像下面这样修改就可以了：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/20111030223016996.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302230175881.png" width="871" height="219" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;没错，MVC的视图页必须从ViewPage继承。&lt;/p&gt;  &lt;p&gt;然后我还顺便修改了一下这个页面，使得它会呈现一个Hello MVC字符串。那么这时候，再选择在浏览器中查看网站，就应该呈现为下面这个样子了：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302230205550.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110302230257563.png" width="675" height="518" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;到这里，整个ASP.NET MVC框架就完全在网站项目中部署成功了。本文其实只是一篇授人以鱼的文章，大家在一步步的部署成功ASP.NET MVC网站（而不是WebProject）后，可以思考每一个步骤的必要性和目的。真正做到知其然还知其所以然。也可以尝试不要把Controller放在App_Code文件夹中，而是放在第三方引用项目中，这样能够创建出伸缩性更好的网站结构。&lt;/p&gt;  &lt;p&gt;下一篇文章我将介绍如何在网站上部署Jumony for MVC框架，Jumony for MVC为MVC提供了基于Jumony技术的视图引擎，并改善了ASP.NET MVC中一些坑爹的问题（例如路由）。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/2229627.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/10/30/2229627.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2011/10/26/2224696.html</id><title type="text">浅谈ASP.NET网站的编译模型和参数</title><summary type="text">在发布一个网站（WebSite而不是WebProject）时，我们会看到这样一个对话框：红框中的三个选项，你知道他们的具体含义和对最终发布结果的影响么？OK，如果您已然明了，这篇文章您可以忽略了，如果直到今天您还是一知半解的话，希望这篇文章对您有所帮助。页面类和代码类从ASP.NET第一个版本，就引入了CodeBehind的概念，我们既可以像ASP那样，将页面的处理代码直接放在aspx中，也可以放在另一个独立的代码文件中，通过aspx文件中的@Page指令的CodeBehind属性关联起来。到了ASP.NET 2.0时代，这一项技术进化的更为成熟。在网站项目中，使用@Page指令的CodeFi</summary><published>2011-10-26T09:13:00Z</published><updated>2011-10-26T09:13:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2011/10/26/2224696.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2011/10/26/2224696.html"/><content type="html">&lt;p&gt;在发布一个网站（WebSite而不是WebProject）时，我们会看到这样一个对话框：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/20111026084445720.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110260845407578.png" alt="image" width="644" height="502" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;红框中的三个选项，你知道他们的具体含义和对最终发布结果的影响么？OK，如果您已然明了，这篇文章您可以忽略了，如果直到今天您还是一知半解的话，希望这篇文章对您有所帮助。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;页面类和代码类&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;从ASP.NET第一个版本，就引入了CodeBehind的概念，我们既可以像ASP那样，将页面的处理代码直接放在aspx中，也可以放在另一个独立的代码文件中，通过aspx文件中的@Page指令的CodeBehind属性关联起来。到了ASP.NET 2.0时代，这一项技术进化的更为成熟。在网站项目中，使用@Page指令的CodeFile指示页面的处理代码文件，并使用Inherits属性令页面类继承于代码隐藏文件中所定义的类型。其实一个具备完整的Test.aspx和Test.aspx.cs两个文件的页面，至少存在两个类型的定义和三个代码文件。&lt;/p&gt;&lt;p&gt;第一个类型是从Test.aspx所编译出来的页面类，这个类一般放在ASP命名空间下，即ASP.Test（所以ASP命名空间在网站中不能乱用）。这个类型对应一个代码文件，在ASP.NET网站编译和发布时，这个代码文件会被临时的创建出来，当编译和发布完成后旋即被删除。&lt;/p&gt;&lt;p&gt;另一个类型是在Test.aspx.cs文件中所定义的类型，默认情况下这个类型名称是Test且没有命名空间。这个类型有两个代码文件，其一是从aspx文件分析出来的控件声明（用于声明在aspx中有ID且不在模版控件中的控件为字段，使得在aspx.cs文件中可以直接通过ID访问当这些控件）代码文件，在ASP.NET 1.x时代，这些代码是直接由IDE环境产生在Test.aspx.cs文件中的，从ASP.NET 2.0开始产生独立的代码文件并声明为partial，与Testaspx.cs中的另一部分声明合并为另一个类型Test。为了接下来的阐述方便，下文将这个类型称之为代码类。&lt;/p&gt;&lt;p&gt;事实上从ASP.NET第一个版本到现在的版本，只要你使用了代码分离模型，就一定会产生两个类型而不是一个。ASP.NET 2.0引入partial只是为了将控件声明代码从aspx.cs文件中剥离，而并没有改变根本的两个类型的模型。同时，这里所阐述的aspx文件的类型模型，同样也适用于asmx、ashx、asax等文件。&lt;/p&gt;&lt;p&gt;页面类总是继承于代码类，除非代码类不存在，此时，页面类从适合的基类（Page、UserControl或是HttpApplication）继承。&lt;/p&gt;&lt;p&gt;顺带值得一提的是，事实上代码类不局限于必须是aspx.cs中定义，只要是aspx文件代码中能访问到的任何类型（譬如网站引用的某个程序集中所定义的类型或是App_Code中定义的类型）都可以作为代码类，但这已经超出了本文的范畴，在此不做深究。&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;不勾选&lt;/strong&gt;则预编译页面类，勾选则不预编译，待到页面第一次被访问时才进行编译。特别需要注意的是，&lt;strong&gt;不勾选&lt;/strong&gt;此选项才表示预编译页面类，勾选反而会导致页面类延后编译。&lt;/p&gt;&lt;p&gt;如果不勾选此选项，则页面类不会被编译成DLL，这样发布后仍然可以修改aspx、asmx、ashx、asax等文件，这才是&amp;ldquo;允许更新此预编译站点&amp;rdquo;的真实含义。事实上这个英文更准确的翻译应该是&amp;ldquo;允许修改预编译后的页面文件&amp;rdquo;。&lt;/p&gt;&lt;p&gt;若没有勾选此选项，则正式发布后的aspx、ashx、asmx、asax文件都将是任何实质内容的壳文件，其存在的意义只是为了IIS不报404错误。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;使用固定命名和单页程序集&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这个选项很大程度上决定了编译后网站bin文件夹中DLL的数量，若勾选这个选项，则每一个页面都会被编译成独立的程序集（DLL），DLL的名称一般是App_Web_{页面文件的名称}.{页面虚拟路径的HASH}.dll，如App_Web_Test.aspx.12345678.dll。&lt;/p&gt;&lt;p&gt;如果使用了代码分离模型，并且没有勾选&amp;ldquo;允许更新此预编译站点&amp;rdquo;这个选项，则这个文件里面至少包含两个类型，页面类和代码类。若勾选了&amp;ldquo;允许更新此预编译站点&amp;rdquo;这个选项，则页面类不会在DLL中。&lt;/p&gt;&lt;p&gt;若不勾选此选项，则ASP.NET编译工具将尝试将所有的类型打包到一个程序集中。&lt;/p&gt;&lt;p&gt;注意，即使不勾选此选项，最终所有的页面都打包到一个程序集中，在网站项目中，不同的页面之间也是不能自由互访的（WebProject可以）。如果我要在Test.aspx或是Test.aspx.cs中访问Index.aspx.cs中定义的类型Index，即使最终所有的代码都会编译到一个程序集，但仍需要使用@Reference指令。&lt;/p&gt;&lt;p&gt;此选项的主要用途在于增量更新，使用固定命名和单页程序集可以使得我们修改了某个页面后，只需要更新线上环境这个页面所对应的DLL即可，而不必更新整个网站。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;发出调试信息&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这个选项简单的说就是是否为编译的DLL创建pdb文件，pdb文件可以在出现异常时给出源代码相关的信息，一般来说就是行号和相关源代码，像下面这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110261713034620.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110261713057849.png" alt="image" width="942" height="24" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;而对于没有pdb文件的程序集，则在异常信息中显示为这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110261713057882.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201110/201110261713058472.png" alt="image" width="522" height="17" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/2224696.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/10/26/2224696.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2011/05/23/2054871.html</id><title type="text">C#5纯属YY的展望</title><summary type="text">每次.NET出现新版本后，都会有大量对下个版本不靠谱的各种YY。尤其是C#，一些YY会从3开始，直到5。在这里我也不妨YY一下，谈谈我期盼了很久的一些语言特性，我尽可能会让这些YY靠谱一点，各位看官姑妄听之，姑妄看之。 1、namespace语句： namespace Ivony;令整个文件所有根定义，均在Ivony命名空间。虽然很无聊，但是的确可以减少花括号的层次。2、lambda语句块：Ex...</summary><published>2011-05-23T15:27:00Z</published><updated>2011-05-23T15:27:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2011/05/23/2054871.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2011/05/23/2054871.html"/><content type="html">&lt;p&gt;每次.NET出现新版本后，都会有大量对下个版本不靠谱的各种YY。尤其是C#，一些YY会从3开始，直到5。在这里我也不妨YY一下，谈谈我期盼了很久的一些语言特性，我尽可能会让这些YY靠谱一点，各位看官姑妄听之，姑妄看之。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;1、namespace语句：&lt;/p&gt;  namespace Ivony;&lt;p&gt;令整个文件所有根定义，均在Ivony命名空间。&lt;/p&gt;&lt;p&gt;虽然很无聊，但是的确可以减少花括号的层次。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;2、lambda语句块：&lt;/p&gt;Expression&amp;lt;Action&amp;lt;int&amp;gt;&amp;gt; e = max =&amp;gt;&lt;br/&gt;{&lt;br/&gt;  for( int i = 0; i &amp;lt; max; i++ )&lt;br/&gt;    Console.WriteLine( i );&lt;br/&gt;};&lt;p&gt;这个据说没赶上车&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;3、泛型约束支持更丰富类型：&lt;/p&gt;public class EnumHelper&amp;lt;T&amp;gt; where T : Enum&lt;br/&gt;{&lt;br/&gt;  //…&lt;br/&gt;}&lt;p&gt;这个在C#4仍然是不支持的。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;4、自定义dynamic的类型转换：&lt;/p&gt;public static dynamic operator implict ( MyType obj )&lt;br/&gt;{&lt;br/&gt;  //...&lt;br/&gt;}&lt;p&gt;C#小组是不是忘了这个重要的特性。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;5、用简单的语法获取MemberInfo：&lt;/p&gt;var member = memberof( obj.ToString );&lt;p&gt;获取一个MethodInfo对象。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;6、自动推断委托类型：&lt;/p&gt;var e = ( int i ) =&amp;gt; i + 5;&lt;br/&gt;var d = delegate( int i ) { return i + 5; };&lt;p&gt;e是一个Expression&amp;lt;Func&amp;lt;int, int&amp;gt;&amp;gt;对象，d是一个Func&amp;lt;int,int&amp;gt;对象。&lt;/p&gt;&lt;p&gt;这个可能C#团队永远不会实现。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;7、自定义类型初始化表达式行为：&lt;/p&gt;&lt;p&gt;我简单的说说，不给出代码了。&lt;/p&gt;&lt;p&gt;通过特性，设置类型的一个属性是否应当出现在类型初始化表达式中，也就是说new MyType(){ A = 1 };，通过特性可以使得A不能在出现在花括号中。&lt;/p&gt;&lt;p&gt;或者，使得{ A = 1 }编译为obj.Add( &amp;quot;A&amp;quot;, 1 )。&lt;/p&gt;&lt;p&gt;或者，使得非内置列表类型可以写出：new MyType(){ &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot; };&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;8、对匿名类型属性应用特性：&lt;/p&gt;var obj = new&lt;br/&gt;{&lt;br/&gt;  [DisplayName( &amp;quot;姓名&amp;quot; )]&lt;br/&gt;  Name = &amp;quot;abc&amp;quot;&lt;br/&gt;}&lt;img src="http://www.cnblogs.com/Ivony/aggbug/2054871.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/05/23/2054871.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2011/04/15/2017560.html</id><title type="text">Jumony for MVC现状和展望</title><summary type="text">Jumony一直在致力于成为一个优秀的ASP.NET MVC视图引擎，同时也顺便修整一下MVC的种种问题，所以，Jumony for MVC一直是Jumony一个非常重要的子项目，尽管它还没有一个公开的稳定版本，但由于Jumony是一个完全开源的项目，任何人都可以在http://jumony.codeplex.com/下载Jumony最新的源代码，当然也就包含Jumony for MVC。这篇文章...</summary><published>2011-04-15T13:51:00Z</published><updated>2011-04-15T13:51:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2011/04/15/2017560.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2011/04/15/2017560.html"/><content type="html">&lt;p&gt;Jumony一直在致力于成为一个优秀的ASP.NET MVC视图引擎，同时也顺便修整一下MVC的种种问题，所以，Jumony for MVC一直是Jumony一个非常重要的子项目，尽管它还没有一个公开的稳定版本，但由于Jumony是一个完全开源的项目，任何人都可以在&lt;a href="http://jumony.codeplex.com/"&gt;http://jumony.codeplex.com/&lt;/a&gt;下载Jumony最新的源代码，当然也就包含Jumony for MVC。这篇文章简单的介绍下Jumony for MVC的现状和将来的发展方向。&lt;/p&gt;  &lt;p&gt;那么首先，Jumony已经作为ASP.NET MVC的一个视图引擎，借助ASP.NET4的特性，Jumony for MVC并不需要任何一行多余的代码，只要你的网站或Web项目引用了Ivony.Html.Web.Mvc的项目或DLL，Jumony for MVC就会自动将自己的视图引擎JumonyViewEngine注册到系统中。默认情况下，JumonyViewEngine呈现出与默认的WebFormViewEngine相似的视图查找逻辑，只不过Jumony查找的是.html和htm文件。特别的，与Jumony for ASP.NET类似，JumonyViewEngine在找到视图文件后，会查找是否存在.html.ashx这样的文件，若存在，且该文件所定义的Handler类型继承于ViewHandler，那么这个ViewHandler就会自动被当作IView对象来返回（ViewHandler实现了IView）。ViewHandler基类提供了处理HTML视图所需要的一切环境，ViewContext或是ViewModel，还有UrlHelper。&lt;/p&gt;  &lt;p&gt;为了配合MVC的一些功能，Jumony for MVC也对HTML做了小小的扩展。可以简单的在一个链接（&amp;lt;a&amp;gt;）里面添加action和controller（可选）属性便可以直接使得这个链接变成一个ActionLink，添加其他RouteData的方式也很简单，只需要在名称前面加个下划线就可以了。像是这样：&lt;/p&gt;  &lt;p&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;action&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;controller&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;_id&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: "&gt;=&lt;/span&gt;&lt;span style="color: "&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;Home&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;/span&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;        &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;MVC中的部分视图，可以使用&amp;lt;partial&amp;gt;标签来实现，&amp;lt;partial&amp;gt;有两种格式，一种是直接指定action和controller（可选）属性，这样，Jumony for MVC会自动调用HtmlHelper.Action方法来执行指定Action并将返回的结果嵌入。另一种则可以设置view属性，指定一个视图名称，这种情况下Jumony for MVC则会调用HtmlHelper.Partial方法。&lt;/p&gt;  &lt;p&gt;上述的HTML扩展，不需要html文件附有.html.ashx的视图处理程序，只要是被JumonyViewEngine当作视图的HTML文件，这些HTML扩展便会自动应用。所以很多简单的partial（譬如说页头）或是页面（譬如说信息提示页），可以不需要ashx文件的辅助处理。&lt;/p&gt;  &lt;p&gt;Jumony for MVC的部分视图也使用标准的HTML格式，也支持附加的ashx文件支持，只是继承的类型不能是ViewHandler而必须是PartialViewHandler，在将来的版本中，将考虑统一这两者。&lt;/p&gt;  &lt;p&gt;除此之外，考虑到ASP.NET MVC行为诡异的默认路由实现。Jumony for MVC还提供了一个简单的路由实现，SimpleRoutingTable。主要针对默认Route莫名其妙的自动继承当前路由值和要命的先到先得机制做了改善。&lt;/p&gt;  &lt;p&gt;路由对象先到先得的机制是由RouteCollection的路由查找实现而决定的，所以为了解决这个问题，SimpleRoutingTable把所有的路由规则合并到一个RouteBase对象，也就是SimpleRoutingTable实例，这个实例会按照确定的规则查找最合适的规则（SimpleRoutingRule）来进行路由。任何可能冲突的规则是不能添加到一个SimpleRoutingTable对象中的。&lt;/p&gt;  &lt;p&gt;秉承Jumony的传统，Jumony for MVC不仅仅是一款足够优秀的ASP.NET MVC视图引擎，且与现有的视图引擎保持了最大的兼容，在Jumony for MVC的视图中可以嵌入WebForm视图引擎的partial，反之同样可行。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;以上，就是Jumony for MVC的现状。&lt;/p&gt;  &lt;p&gt;展望未来，Jumony for MVC还存在很多未能解决的问题。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;譬如说&amp;lt;form&amp;gt;的action属性如何指定路由的链接？当然现阶段我们可以简单的在ashx中找出这个&amp;lt;form&amp;gt;元素再调用SetAttribute方法来设置。但直接在HTML中书写显然是更惬意的事情。&lt;/p&gt;  &lt;p&gt;当然还有表单验证，尽管Jumony Forms子项目提供了有限的表单验证能力，但如何与MVC的Model验证模型结合起来，又或者有无必要结合（事实上这个依赖于DefaultModelBinder的模型本来就不是那么轻巧）。&lt;/p&gt;  &lt;p&gt;Jumony View已经为缓存做好了准备，其实现了ICachableResult接口并可以从产生一个ContentResult用于缓存，如果缓存命中，则可以直接用这个ContentResult来代替ViewResult从而提高性能。但着需要Controller层面的配合。所以Jumony正在准备自己的JumonyController。&lt;/p&gt;  &lt;p&gt;对于一些简单的数据绑定，我们也会希望是不是可以用简单的HTML扩展来完成，例如：&lt;/p&gt;  &lt;font face="Consolas"&gt;&lt;span style="color: " class="HTML Tag Delimiter"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 9.8pt"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: " class="HTML Element Name"&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: " class="HTML Attribute Name"&gt;&lt;font color="#ff0000"&gt;action&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Operator"&gt;=&lt;/span&gt;&lt;span style="color: " class="HTML Attribute Value"&gt;&amp;quot;Detail&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: " class="HTML Attribute Name"&gt;&lt;font color="#ff0000"&gt;controller&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Operator"&gt;=&lt;/span&gt;&lt;span style="color: " class="HTML Attribute Value"&gt;&amp;quot;News&amp;quot;&lt;/span&gt;&lt;span style="color: " class="HTML Tag Delimiter"&gt;&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&amp;#160; &lt;span style="color: " class="HTML Tag Delimiter"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: " class="HTML Element Name"&gt;&lt;font color="#800000"&gt;binding&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: " class="HTML Attribute Name"&gt;&lt;font color="#ff0000"&gt;source&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Operator"&gt;=&lt;/span&gt;&lt;span style="color: " class="HTML Attribute Value"&gt;&amp;quot;ViewModel&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: " class="HTML Attribute Name"&gt;&lt;font color="#ff0000"&gt;property&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Operator"&gt;=&lt;/span&gt;&lt;span style="color: " class="HTML Attribute Value"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: " class="HTML Attribute Name"&gt;&lt;font color="#ff0000"&gt;target&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Operator"&gt;=&lt;/span&gt;&lt;span style="color: " class="HTML Attribute Value"&gt;&amp;quot;:text&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: " class="HTML Tag Delimiter"&gt;&lt;font color="#0000ff"&gt;/&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&amp;#160; &lt;span style="color: " class="HTML Tag Delimiter"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;/span&gt;&lt;span style="color: " class="HTML Element Name"&gt;&lt;font color="#800000"&gt;binding&lt;/font&gt;&lt;/span&gt;&amp;#160;&lt;span style="color: " class="HTML Attribute Name"&gt;&lt;font color="#ff0000"&gt;source&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Operator"&gt;=&lt;/span&gt;&lt;span style="color: " class="HTML Attribute Value"&gt;&amp;quot;ViewModel&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: " class="HTML Attribute Name"&gt;&lt;font color="#ff0000"&gt;property&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Operator"&gt;=&lt;/span&gt;&lt;span style="color: " class="HTML Attribute Value"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;span style="color: " class="HTML Attribute Name"&gt;&lt;font color="#ff0000"&gt;target&lt;/font&gt;&lt;/span&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Operator"&gt;=&lt;/span&gt;&lt;span style="color: " class="HTML Attribute Value"&gt;&amp;quot;_id&amp;quot;&lt;/span&gt;&lt;/font&gt;&amp;#160;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;font color="#0000ff"&gt;&lt;span style="color: " class="HTML Tag Delimiter"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: " class="HTML Tag Delimiter"&gt;&amp;lt;/&lt;/span&gt;&lt;/font&gt;&lt;span style="color: " class="HTML Element Name"&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="color: " class="HTML Tag Delimiter"&gt;&lt;font style="font-size: 9.8pt" color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;最后，Jumony for MVC作为ASP.NET MVC的一款视图引擎，借助Jumony强大的HTML能力，使得ASP.NET MVC的View返璞归真，最大程度上接近原始的HTML而非代码和HTML的杂凑，是非常值得一试的一个视图引擎。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/2017560.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/04/15/2017560.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2011/01/25/aspnet-mvc-by-source-8.html</id><title type="text">通过源代码研究ASP.NET MVC（八）</title><summary type="text">通过源代码研究ASP.NET MVC中的Controller和View（一）通过源代码研究ASP.NET MVC中的Controller和View（二）通过源代码研究ASP.NET MVC中的Controller和View（三）通过源代码研究ASP.NET MVC中的Controller和View（四）通过源代码研究ASP.NET MVC中的Controller和View（五）通过源代码研究ASP.NET MVC中的Controller和View（六）通过源代码研究ASP.NET MVC（七）第八篇，上一篇发布后，有朋友说这个系列更新太慢了，不给力。有几个原因，首先是Jumony M2的计划中</summary><published>2011-01-25T12:47:00Z</published><updated>2011-01-25T12:47:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2011/01/25/aspnet-mvc-by-source-8.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2011/01/25/aspnet-mvc-by-source-8.html"/><content type="html">&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/13/aspnet-mvc-by-source-1.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（一）&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/15/aspnet-mvc-by-source-2.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（二）&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/17/aspnet-mvc-by-source-3.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（三）&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/20/aspnet-mvc-by-source-4.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（四）&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/21/aspnet-mvc-by-source-5.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（五）&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/26/aspnet-mvc-by-source-6.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（六）&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/01/06/aspnet-mvc-by-source-7.html"&gt;通过源代码研究ASP.NET MVC（七）&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;第八篇，上一篇发布后，有朋友说这个系列更新太慢了，不给力。有几个原因，首先是Jumony M2的计划中，并不包括MVC Model的支持，换言之对于Jumony而言，到第六篇的时候，所得到的结论已经足够了。其次是最近忙于Jumony的开发，以及Jumony入门系列的撰写。当然，ASP.NET MVC是一个非常优秀的框架，事实也证明通过源代码研究ASP.NET MVC并非天方夜谭，我越来越觉得，这个系列的文章以及这种实践，存在比Jumony项目更为重要的意义，所以，我会继续这个系列，也希望能获得大家的支持。&lt;/p&gt;&lt;p&gt;通过源代码来研究任何东西。用脚趾头想想都能知道是一件非常枯燥和艰难的事情，但我想这个实践却很有意义。我们常说一个好的源代码就是最好的文档，那么就让我们来真正验证一下，对于MVC如此庞大和复杂的框架，一个好的源代码是不是真的可以当作资料来学习呢？不试，又怎么知道？同时，我一直在强调程序设计语言本身对于程序的重要性，通过这个实践，也能补充不少论据。&lt;/p&gt;&lt;p&gt;在这个系列中，我尽可能的当作自己一无所知（事实上也基本是这样），仅仅通过源代码源代码的而不借助任何其他资料来研究。你会看到我在尽可能细致的考证每一个推论，每一个猜测，尽管结论是那么的明显。同时你也会看到我不可避免的犯错，卡壳。这也许是因为我的能力所限，当然也有可能是不是源代码本身出了一些毛病。&lt;/p&gt;&lt;p&gt;通过这个系列，对于如何让别人看代码的时候完整的理解自己的意图。方法名称，程序结构以及细枝末节的那些东西的重要性，通过这个不可能完成的任务旅程，是否会有更深的理解呢？&lt;/p&gt;&lt;p&gt;废话到此结束。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在上一篇中，我们进展神速的从Controller或者说ControllerActionInvoker的世界忽然穿越到了Model的世界，IModelBinder地球人都知道这将会是Model的大门。进去之前先来回顾一下。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;故事的原点，还得回到ControllerActionInvoker的核心逻辑：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;查找Action（FindAction） &lt;/li&gt;&lt;li&gt;获取参数 &lt;/li&gt;&lt;li&gt;InvokeActionMethod &lt;/li&gt;&lt;li&gt;InvokeActionResult &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;在第六篇，我们弄明白了查找Action的逻辑。接下来经过一系列的手续后，ControllerActionInvoker调用了GetPrameterValues方法，这个方法在获取了参数描述符后，转手调用GetParameterValue（没有s）来获取值。而GetParameterValue的逻辑也已经理清，其实很简单：&lt;/p&gt;&lt;ul&gt;&lt;li&gt;获取Binder &lt;/li&gt;&lt;li&gt;构造BindingContext &lt;/li&gt;&lt;li&gt;绑定Model &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;获取Binder的详细流程已经在第七篇中摸清。那么&lt;/p&gt;&lt;p&gt;GetParameterValue(s)的结果，显然是会被当作Action的参数被传入（注1），而这个结果则是通过符合条件的IModelBinder来获取。&lt;/p&gt;&lt;p&gt;&lt;em&gt;注1：具体的代码分析可以参考：&lt;/em&gt;&lt;a href="http://www.cnblogs.com/P_Chou/archive/2010/12/07/details-asp-net-mvc-08.html"&gt;&lt;em&gt;深入理解ASP.NET MVC（8）&lt;/em&gt;&lt;/a&gt;&lt;em&gt;，当ControllerActionInvoker的主线走完后，我会回过头来将过滤器的工作原理完整的分析清楚，因为事实上所有过滤器的工作原理几乎是一样的。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;一般看到接口，我立即能想到两个词，抽象和契约。事实上通过前面的分析能知道，MVC的核心抽象都是通过非常简单的接口来定义的。抽象的东西一定是简单的。Controller和View的抽象就是IController和IView接口，尽管Model部分并没有所谓的IModel接口，但事实上MVC是直接将object当作了Model的抽象。&lt;/p&gt;&lt;p&gt;那么来看看IModelBinder接口长什么样子：&lt;/p&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;namespace&lt;/span&gt;&lt;/span&gt; System.Web.Mvc&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;interface&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;IModelBinder&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;object&lt;/span&gt;&lt;/span&gt; BindModel( &lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ControllerContext&lt;/span&gt;&lt;/span&gt; controllerContext, &lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ModelBindingContext&lt;/span&gt;&lt;/span&gt; bindingContext );&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;很好，这个接口就一个方法，ControllerContext我们知道其包含了控制器和HTTP上下文的信息，而ModelBindingContext则是在GetParameterValue方法中被构建。&lt;/p&gt;&lt;p&gt;那么，IModelBinder的职责也被明确：&lt;/p&gt;&lt;p&gt;通过控制器和绑定上下文获取（绑定）模型的值。&lt;/p&gt;&lt;p&gt;ModelBindingContext从名称来看就是绑定上下文，他存放着绑定的时候需要的信息，但这些属性通过名称很难了解其具体用途，所以还是从IModelBinder入手。先来看看IModelBinder有一些什么实现：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201101/201101092305026391.png"&gt;&lt;img height="150" width="528" src="http://images.cnblogs.com/cnblogs_com/Ivony/201101/201101092305026325.png" alt="image" border="0" title="image" style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;老实说ModelBinder的实现类有点少得出乎我的意料，因为ModelBinder只有两种指定方式，在参数上通过CustomModelBinderAttribute指定或者通过类型来匹配。在参数上通过Attribute指定并不是一种特别靠谱的方式，事实上在范例和实际应用中，我们都很少看到这个特性的运用，譬如说MVC的示例网站代码：&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;HttpPost&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ActionResult&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; LogOn( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;LogOnModel&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; model, &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; returnUrl )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( ModelState.IsValid )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// 如果我们进行到这一步时某个地方出错，则重新显示表单&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt; View( model );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;这里我们看不到任何的CustomModelBinderAttribute的影子，我原想，或许是LogOnModel有在类型上用CustomModelBinderAttribute注册自己的LogOnModelBinder，因为在类型上注册比在参数上注册来的靠谱。但这样来说，对于returnUrl这样的参数，MVC至少也应该内置StringBinder或是Int32Binder之类的东西，但答案是这些都没有。仔细观察IModelBidner的这几个实现类，我发现他们大部分都是应用于特定而非一般类型的。例如HttpPostedFileBaseModelBinder，很明显这是用于创建HttpPostedFileBase实例的Binder。ByteArrayModelBinder多半是应用于byte[]类型。&lt;/p&gt;&lt;p&gt;那么，干脆随便挑一个类型来瞄一眼吧，譬如说HttpPostedFileBaseModelBinder：&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;HttpPostedFileBaseModelBinder&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; : &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;IModelBinder&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp; {&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;object&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; BindModel( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ControllerContext&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; controllerContext, &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ModelBindingContext&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; bindingContext )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( controllerContext == &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;throw&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ArgumentNullException&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #a31515;" color="#a31515"&gt;"controllerContext"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( bindingContext == &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;throw&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ArgumentNullException&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #a31515;" color="#a31515"&gt;"bindingContext"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;HttpPostedFileBase&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; theFile = controllerContext.HttpContext.Request.Files[bindingContext.ModelName];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ChooseFileOrNull( theFile );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// helper that returns the original file if there was content uploaded, null if empty&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;internal&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;static&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;HttpPostedFileBase&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ChooseFileOrNull( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;HttpPostedFileBase&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; rawFile )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// case 1: there was no &amp;lt;input type="file" ... /&amp;gt; element in the post&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( rawFile == &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// case 2: there was an &amp;lt;input type="file" ... /&amp;gt; element in the post, but it was left blank&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( rawFile.ContentLength == 0 &amp;amp;&amp;amp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;.IsNullOrEmpty( rawFile.FileName ) )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// case 3: the file was posted&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt; rawFile;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;其实现与猜测的是一样的，直接从Request中获取与ModelName相同的文件，通过前面的分析我们知道，ModelName就是参数名。最后调用的ChooseFileOrNull方法的注释非常清楚，第一种情况是为了避免我们接受的参数在页面上对应的不是一个文件上传控件，那么返回null，第二种情况是用户没有选择文件上传，同样返回null，最后一种情况则将HttpPostedFileBase对象直接返回了。&lt;/p&gt;&lt;p&gt;再来看看LogOnModel这个类型，则把我原本的设想全部推翻了。&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;LogOnModel&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;Required&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;DisplayName&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #a31515;" color="#a31515"&gt;"用户名"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; UserName { &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;Required&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;DataType&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;DataType&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;.Password )]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;DisplayName&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #a31515;" color="#a31515"&gt;"密码"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; Password { &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;DisplayName&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #a31515;" color="#a31515"&gt;"记住我?"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;bool&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; RememberMe { &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt;; }&lt;br /&gt;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;没错，事实上LogOnModel就是一个普通的object，并没有任何特别的诸如LogOnModelBinder之类的东西。那么，这是怎么实现的？&lt;/p&gt;&lt;p&gt;回想Binder的获取逻辑，没错，最后一步是，如果找不到合适的Binder，就使用ModelBinders.Binders.DefaultBinder。换言之不论是我们的LogOnModel model还是我们的string returnUrl，最终都是使用DefaultBinder来获取值的。&lt;/p&gt;&lt;p&gt;DefaultBinder是ModelBinderDictionary类型的一个属性：&lt;/p&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;IModelBinder&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; DefaultBinder&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( _defaultBinder == &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _defaultBinder = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;DefaultModelBinder&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; _defaultBinder;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _defaultBinder = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;value&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;类似的代码已经见过太多次，这说明默认情况下，他就是DefaultModelBinder类型的一个实例。&lt;/p&gt;&lt;p&gt;那么来看看DefaultModelBinder的实现：&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;virtual&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;object&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; BindModel( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ControllerContext&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; controllerContext, &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ModelBindingContext&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; bindingContext )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( bindingContext == &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;throw&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ArgumentNullException&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #a31515;" color="#a31515"&gt;"bindingContext"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;bool&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; performedFallback = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;;&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( !&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;.IsNullOrEmpty( bindingContext.ModelName ) &amp;amp;&amp;amp; !bindingContext.ValueProvider.ContainsPrefix( bindingContext.ModelName ) )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// We couldn't find any entry that began with the prefix. If this is the top-level element, fall back&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// to the empty prefix.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( bindingContext.FallbackToEmptyPrefix )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bindingContext = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ModelBindingContext&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModelMetadata = bindingContext.ModelMetadata,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModelState = bindingContext.ModelState,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PropertyFilter = bindingContext.PropertyFilter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ValueProvider = bindingContext.ValueProvider&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; performedFallback = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string))&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// or by seeing if a value in the request exactly matches the name of the model we're binding.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// Complex type = everything else.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( !performedFallback )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ValueProviderResult&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; vpResult = bindingContext.ValueProvider.GetValue( bindingContext.ModelName );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( vpResult != &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; BindSimpleModel( controllerContext, bindingContext, vpResult );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( !bindingContext.ModelMetadata.IsComplexType )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt; BindComplexModel( controllerContext, bindingContext );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;首先是一个入口检查，接下来先设置performedFallback为false，从字面上看是已经进行了回退。其实fallback到底具体是什么工作到现在还不清楚。然后是一个判断，如果ModelName不等于空，并且ValueProvider不ContainsPrefix ModelName。&lt;/p&gt;&lt;p&gt;不妨来分析一下这个判断干什么用的，首要条件是ModelName不为空，也就是至少存在一个ModelName。在我们这一路走来，ModelName几乎是不可能为空的，因为他默认就是参数的名称，那我们先假定这个条件是恒真的。继续看后面，ContainsPrefix从字面上可以理解为，不包含前缀，参数是ModelName，也就是说，ValueProvider不包含这个ModelName这个前缀。&lt;/p&gt;&lt;p&gt;再来看下面的注释下，大意是，我们不能找到任何条目是以字首开头的，如果这是顶级元素，那么回退到空白的前缀。&lt;/p&gt;&lt;p&gt;然后是再一个if判断，BindingContext.FallbackToEmptyPrefix，看来这个属性是控制DefaultModelBinder是否允许回退到空白前缀的。这个属性的值是什么？翻出上一篇来看看就知道了：&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;        FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == &lt;/span&gt;&lt;span class="kwrd"&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;), &lt;/span&gt;&lt;span class="rem"&gt;&lt;span style="color: #008000;" color="#008000"&gt;// only fall back if prefix not specified&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;p&gt;还记得上篇的话就会知道，BindingInfo.Prefix是从特性中获取的，那么这里可以简单的理解为，如果没有在参数上利用BindAttribute设置Prefix的话，那么就是允许回退到空白前缀（原来是这个意思）。如果不允许就直接绑定失败了（return null），那么如果允许回退到空白前缀，那么再创建一个ModelBindingContext，并且将performedFallback设置为true，继续下面的逻辑。这里重新创建的ModelBindingContext所有属性都是从原来的ModelBindingContext实例中获取的，创建一个新的实例其主要作用是丢弃一些属性（或者说用默认值）。那么我们来比对一下丢弃了哪些属性：&lt;/p&gt;&lt;p&gt;原本创建ModelBindingContext的逻辑大体上是这样的：&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;      ModelBindingContext bindingContext = &lt;/span&gt;&lt;span class="kwrd"&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ModelBindingContext()&lt;br/&gt;      {&lt;br/&gt;        ModelName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName,&lt;br/&gt;        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType( &lt;/span&gt;&lt;span class="kwrd"&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;, parameterDescriptor.ParameterType ),&lt;br/&gt;        ModelState = controllerContext.Controller.ViewData.ModelState,&lt;br/&gt; &lt;br/&gt;        FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == &lt;/span&gt;&lt;span class="kwrd"&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;), &lt;/span&gt;&lt;span class="rem"&gt;&lt;span style="color: #008000;" color="#008000"&gt;// only fall back if prefix not specified&lt;/span&gt;&lt;/span&gt;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt;        PropertyFilter = GetPropertyFilter( parameterDescriptor ),&lt;br/&gt;        ValueProvider = controllerContext.Controller.ValueProvider&lt;br/&gt; &lt;br/&gt;      }; &lt;/span&gt;&lt;/span&gt;&lt;p&gt;可以看出来ModelName和FallbackToEmptyPrefix被丢弃了，或者说被设置成默认值了。OK，这真是一段糟糕透顶的代码，事实上搞了这么久我们都无法猜透这里到底想干什么事情。也搞不清这两个属性是要被丢弃还是需要被设置为默认值。&lt;/p&gt;&lt;p&gt;&lt;span class="kwrd"&gt;&lt;span style="color: #000000;" color="#000000"&gt;来确定一下ModelName和FallbackToEmptyPrefix到底是被设置成了怎样的默认值，其实我觉得事实上根本就不会有设置默认值的代码，他们俩很可能简单的一个是null而另一个是false了，也就是字段被初始化的时候的值。无论怎样，来看看，首先是构造函数：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ModelBindingContext()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// copies certain values that won't change between parent and child objects,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// e.g. ValueProvider, ModelState&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ModelBindingContext( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ModelBindingContext&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; bindingContext )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( bindingContext != &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModelState = bindingContext.ModelState;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ValueProvider = bindingContext.ValueProvider;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;在构造函数里，显然没有为这两个属性设置任何默认值，那么来看看这两个属性：&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;bool&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; FallbackToEmptyPrefix&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: 12pt;"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&lt;span style="font-size: x-small;" size="2"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;果然，FallbackToEmptyPrefix默认值就是false（bool字段的默认值）。&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ModelName&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( _modelName == &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _modelName = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;String&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;.Empty;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; _modelName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _modelName = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;value&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;ModelName的默认值则是&lt;span&gt;String&lt;/span&gt;.Empty。&lt;/p&gt;&lt;p&gt;来谈谈这段坑爹的代码，第一眼看到这个方法的实现的时候就感觉非常乱。这段代码就像就是程序员为了完成某个测试而拼凑出来的一团东西。也许对于开发人员而言，这段代码是一目了然的，但对于直接看源代码的人来说，这可真是坑爹的代码。事实上，我们磕磕绊绊走了这么远，这段代码到底在干啥还是毫无头绪。&lt;/p&gt;&lt;p&gt;好吧我们不在这里纠结，因为无法预测IValueProvider的ContainsPrefix到底会产生什么结果，而现在贸然研究IValueProvider会把战线拉长。所以不妨将真假两种可能代入然后看看后面的逻辑会是怎样。&lt;/p&gt;&lt;p&gt;首先我们假定这个方法返回true，那么天下太平，第一个if里面的所有代码都不会被执行，performedFallback也会是false，然后if( !performedFallback )成立，进入内部，这时，尝试调用ValueProvider的GetValue方法，如果有结果返回，那么返回BindSimpleModel方法的结果。如果没有结果返回，那么看ModelMetadata.IsComplexType，字面意思上来看，是判断是不是复杂类型，如果不是，那么返回null（表示绑定失败）。否则返回BindComplexModel方法的结果。&lt;/p&gt;&lt;p&gt;这个流程走下来尽管还有很多不明白的地方，但我们总算搞清了一个事实，那就是performedFallback只是决定是否尝试绑定简单模型的（BindSimpleModel），如果进行了回退（performedFallback = true )，那么就不尝试进行简单模型的绑定（BindSimpleModel）。&lt;/p&gt;&lt;p&gt;再来考虑一下performedFallback取决于什么，先考虑一般情况，在一般情况下，ModelName会是参数名，所以不可能为空。其次我们也不会设置参数上的BindAttribute，所以FallbackToEmptyPrefix也会是true，因为BindingInfo.Prefix默认就是null（好吧，如果你去翻源代码，你会发现_prefix字段默认情况下根本没有被赋值。由于Model这一块的源代码质量实在太令人无语，所以这里就不在文章里深究了，否则会让读者大人头昏脑胀的）。&lt;/p&gt;&lt;p&gt;变换一下我们可以看到一般情况下是这样的：&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; &amp;amp;&amp;amp; !bindingContext.ValueProvider.ContainsPrefix( bindingContext.ModelName ) )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// We couldn't find any entry that began with the prefix. If this is the top-level element, fall back&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;" color="#008000"&gt;// to the empty prefix.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bindingContext = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ModelBindingContext&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModelMetadata = bindingContext.ModelMetadata,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModelState = bindingContext.ModelState,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PropertyFilter = bindingContext.PropertyFilter,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ValueProvider = bindingContext.ValueProvider&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; performedFallback = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;else&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;很明显，一般情况下performedFallback完全取决于ValueProvider的ContainsPrefix方法。也就是performedFallback == !bindingContext.ValueProvider.ContainsPrefix( bindingContext.ModelName )，而在接下来的SimpleModelBinder中，IValueProvider也扮演了重要角色，如果我们精简掉一些东西并将performedFallback代入，那看起来就会像是这样：&lt;/p&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( bindingContext.ValueProvider.ContainsPrefix( bindingContext.ModelName ) )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ValueProviderResult&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; vpResult = bindingContext.ValueProvider.GetValue( bindingContext.ModelName );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ( vpResult != &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt; BindSimpleModel( controllerContext, bindingContext, vpResult );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;这样，不难看出ValueProvider在BindSimpleModel流程中具有核心地位。那么，不碰它是不行的了，他是IValueProvider类型的，先来看看这个接口吧：&lt;/p&gt;&lt;span&gt;&lt;span style="color: #0000ff; font-family: Consolas; font-size: x-small;" face="Consolas" size="2" color="#0000ff"&gt;namespace&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; System.Web.Mvc&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; System;&lt;br /&gt; &lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;interface&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;IValueProvider&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;bool&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; ContainsPrefix( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;" face="Consolas"&gt;&lt;span style="font-size: x-small;" size="2"&gt;&lt;span style="color: #000000;" color="#000000"&gt; prefix );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;" color="#2b91af"&gt;ValueProviderResult&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;" color="#000000"&gt; GetValue( &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;" color="#0000ff"&gt;string&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000; font-size: x-small;" size="2" color="#000000"&gt; key );&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;源代码非常给力，这东西不单单是在BindSimpleModel流程中处于核心地位，事实上估摸着这东西就干这一件事情的。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/1931115.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/01/25/aspnet-mvc-by-source-8.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2011/01/06/aspnet-mvc-by-source-7.html</id><title type="text">通过源代码研究ASP.NET MVC（七）</title><summary type="text">通过源代码研究ASP.NET MVC中的Controller和View（一） 通过源代码研究ASP.NET MVC中的Controller和View（二） 通过源代码研究ASP.NET MVC中的Controller和View（三） 通过源代码研究ASP.NET MVC中的Controller和View（四） 通过源代码研究ASP.NET MVC中的Controller和View（五） ...</summary><published>2011-01-06T06:17:00Z</published><updated>2011-01-06T06:17:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2011/01/06/aspnet-mvc-by-source-7.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2011/01/06/aspnet-mvc-by-source-7.html"/><content type="html">&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/13/aspnet-mvc-by-source-1.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（一）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/15/aspnet-mvc-by-source-2.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（二）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/17/aspnet-mvc-by-source-3.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（三）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/20/aspnet-mvc-by-source-4.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（四）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/21/aspnet-mvc-by-source-5.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（五）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/11/26/aspnet-mvc-by-source-6.html"&gt;通过源代码研究ASP.NET MVC中的Controller和View（六）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;呃，细心的朋友可能已经发现了，到这里这个系列开始改名了，这是因为，从这一篇开始，我不得不来研究ASP.NET MVC中的Model模型了。因为我发现如果要Jumony视图引擎要充分利用ASP.NET MVC的功能的话，Model的支持是绕不过去的。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;先来温习一下之前得到的结论，过了这么久，您忘了没？&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Controller将执行Action的操作外包给了ControllerActionInvoker，其工作流程大体上是这样的：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;查找Action（FindAction） &lt;/li&gt;    &lt;li&gt;获取参数 &lt;/li&gt;    &lt;li&gt;InvokeActionMethod &lt;/li&gt;    &lt;li&gt;InvokeActionResult &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;那么在上一篇，我们已经完整的了解了查找Action的过程，按照传统，这一篇应该对查找Action的过程进行一个总结，但现在需要打破这个传统了，因为这个总结已经有人写过了：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.cnblogs.com/P_Chou/archive/2010/12/01/details-asp-net-mvc-07.html"&gt;深入理解ASP.NET MVC（7）&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;别人的东西可以拿来用的，一定要坚定的拿来用，因为软件领域的轮子已经堆积成山了——懒人原则&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;FindAction步骤找到的Action会经由授权筛选器处理，然后在真正调用Action之前，有一个关键步骤，那就是获取参数：&lt;/p&gt;              IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; parameters = GetParameterValues( controllerContext, actionDescriptor );&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;那么来看看这个方法：&lt;/p&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; GetParameterValues( ControllerContext controllerContext, ActionDescriptor actionDescriptor )&lt;br/&gt;    {&lt;br/&gt;      Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; parametersDict = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;( StringComparer.OrdinalIgnoreCase );&lt;br/&gt;      ParameterDescriptor[] parameterDescriptors = actionDescriptor.GetParameters();&lt;br/&gt; &lt;br/&gt;      &lt;span class="kwrd"&gt;foreach&lt;/span&gt; ( ParameterDescriptor parameterDescriptor &lt;span class="kwrd"&gt;in&lt;/span&gt; parameterDescriptors )&lt;br/&gt;      {&lt;br/&gt;        parametersDict[parameterDescriptor.ParameterName] = GetParameterValue( controllerContext, parameterDescriptor );&lt;br/&gt;      }&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; parametersDict;&lt;br/&gt;    }&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;首先是创建了一个Dictionary用来承载返回结果，然后通过actionDescriptor的GetParameters方法获取所有参数的参数描述符，下面是一个枚举，对每一个参数调用GetParameterValue方法来获取具体的值，最后返回。&lt;/p&gt;&lt;p&gt;从前面的研究可知，这里的actionDescriptor的实例类型显然是ReflectedActionDescriptor，其GetParameters方法实现如下：&lt;/p&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; ParameterDescriptor[] GetParameters()&lt;br/&gt;    {&lt;br/&gt;      ParameterDescriptor[] parameters = LazilyFetchParametersCollection();&lt;br/&gt; &lt;br/&gt;      &lt;span class="rem"&gt;// need to clone array so that user modifications aren't accidentally stored&lt;/span&gt;&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; (ParameterDescriptor[]) parameters.Clone();&lt;br/&gt;    }&lt;br/&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; ParameterDescriptor[] LazilyFetchParametersCollection()&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; DescriptorUtil.LazilyFetchOrCreateDescriptors&amp;lt;ParameterInfo, ParameterDescriptor&amp;gt;(&lt;br/&gt;          &lt;span class="kwrd"&gt;ref&lt;/span&gt; _parametersCache &lt;span class="rem"&gt;/* cacheLocation */&lt;/span&gt;,&lt;br/&gt;          MethodInfo.GetParameters &lt;span class="rem"&gt;/* initializer */&lt;/span&gt;,&lt;br/&gt;          parameterInfo =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ReflectedParameterDescriptor( parameterInfo, &lt;span class="kwrd"&gt;this&lt;/span&gt; ) &lt;span class="rem"&gt;/* converter */&lt;/span&gt;);&lt;br/&gt;    }&lt;p&gt;这里使用了不同于获取ControllerDescriptor的缓存体系。但从这个方法冗长的名字也能一目了然他是干什么的，或者说这里的代码去除缓存后大体上就等同于：&lt;/p&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; ParameterDescriptor[] GetParameters()&lt;br/&gt;    {&lt;br/&gt;      ParameterDescriptor[] parameters = Array.ConvertAll( MethodInfo.GetParameters(), parameterInfo =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ReflectedParameterDescriptor( parameterInfo, &lt;span class="kwrd"&gt;this&lt;/span&gt; ) );&lt;br/&gt; &lt;br/&gt;      &lt;span class="rem"&gt;// need to clone array so that user modifications aren't accidentally stored&lt;/span&gt;&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; (ParameterDescriptor[]) parameters.Clone();&lt;br/&gt;    }&lt;p&gt;注释说明了为什么要进行Clone，这样使得用户会因为意外情况而的修改缓存的母本。因为数组本质上来说不是一个安全的容器，其大小不可变，但每一个元素都可以通过简单的赋值而修改。不过Jumony在解决这种问题时，使用的是只读的容器，而非每次访问都创建副本。MVC的各个部分显然是由不同的团队完成的，从命名的风格和代码习惯上就能很明显的看出来。从源代码入手研究的确是一件非常困难的事情，但好处是你可以得到很多研究结论之外的收获。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;最后还是来瞄一眼证实一下猜测：&lt;/p&gt;  &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DescriptorUtil&lt;br/&gt;  {&lt;br/&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; TDescriptor[] LazilyFetchOrCreateDescriptors&amp;lt;TReflection, TDescriptor&amp;gt;( &lt;br /&gt;      &lt;span class="kwrd"&gt;ref&lt;/span&gt; TDescriptor[] cacheLocation, Func&amp;lt;TReflection[]&amp;gt; initializer, Func&amp;lt;TReflection, TDescriptor&amp;gt; converter )&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="rem"&gt;// did we already calculate this once?&lt;/span&gt;&lt;br/&gt;      TDescriptor[] existingCache = Interlocked.CompareExchange( &lt;span class="kwrd"&gt;ref&lt;/span&gt; cacheLocation, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt; );&lt;br/&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; ( existingCache != &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; existingCache;&lt;br/&gt;      }&lt;br/&gt; &lt;br/&gt;      TReflection[] memberInfos = initializer();&lt;br/&gt;      TDescriptor[] descriptors = memberInfos.Select( converter ).Where( descriptor =&amp;gt; descriptor != &lt;span class="kwrd"&gt;null&lt;/span&gt; ).ToArray();&lt;br/&gt;      TDescriptor[] updatedCache = Interlocked.CompareExchange( &lt;span class="kwrd"&gt;ref&lt;/span&gt; cacheLocation, descriptors, &lt;span class="kwrd"&gt;null&lt;/span&gt; );&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; updatedCache ?? descriptors;&lt;br/&gt;    }&lt;br/&gt; &lt;br/&gt;  }&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;又见到了这个Interlocked，CompareExchange是比较再决定赋值。第一个CompareExchange的逻辑是，如果cacheLocation是null，那么将null赋给它，但无论有没有被赋值，会返回cacheLocation在赋值前的引用，同时以上操作都是原子操作。&lt;/p&gt;&lt;p&gt;其实这段代码有点莫名其妙，我猜测CompareExchange的交换赋值是个幌子，原子操作取值是真，这是为了避免在取值的时候，恰好又被赋值而造成冲突，但事实上我看不到第一个CompareExchange的必要性。&lt;/p&gt;&lt;p&gt;那么第一个ExchangeCompare可以简单的理解为：&lt;/p&gt;      TDescriptor[] existingCache = cacheLocation;&lt;p&gt;然后判断这个cacheLocation不为null，那么就直接返回。否则进行创建。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;创建descriptors的过程与上面的猜测一样，只是多了一个排除空值，接下来是第二个CompareExchange，这个的目的就非常明确和有必要了，因为在创建descriptors过程中，在其他线程可能已经创建完毕了，这时候则抛弃创建出来的descriptor的值。因为第二个CompareExchange的逻辑是，如果cacheLocation仍然是null，那么将descriptors赋给它。但下面的updatedCache ?? descriptors又有点无厘头，因为似乎直接return cacheLocation就可以了。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;瞄一眼完毕，那么猜测又一次命中。这样，创建ParameterDescriptor的逻辑就是&lt;span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;/span&gt;&amp;#160;&lt;span&gt;&lt;span style="color: #2b91af"&gt;ReflectedParameterDescriptor&lt;/span&gt;&lt;/span&gt;( parameterInfo, &lt;span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;/span&gt; )，其中的parameterInfo就是MethodInfo.GetParameter()的结果，也就是Action方法的每一个参数的信息。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;继续回到GetParameterValues方法，在获取ParameterDescriptor后，会针对每一个ParameterDescriptor调用GetParameterValue方法来获取具体的值：&lt;/p&gt;      &lt;span class="kwrd"&gt;foreach&lt;/span&gt; ( ParameterDescriptor parameterDescriptor &lt;span class="kwrd"&gt;in&lt;/span&gt; parameterDescriptors ) &lt;br/&gt;      { &lt;br/&gt;        parametersDict[parameterDescriptor.ParameterName] = GetParameterValue( controllerContext, parameterDescriptor ); &lt;br/&gt;      }&lt;p&gt;那么来看看GetParameterValue方法：&lt;/p&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; GetParameterValue( ControllerContext controllerContext, ParameterDescriptor parameterDescriptor )&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="rem"&gt;// collect all of the necessary binding properties&lt;/span&gt;&lt;br/&gt;      Type parameterType = parameterDescriptor.ParameterType;&lt;br/&gt;      IModelBinder binder = GetModelBinder( parameterDescriptor );&lt;br/&gt;      IValueProvider valueProvider = controllerContext.Controller.ValueProvider;&lt;br/&gt;      &lt;span class="kwrd"&gt;string&lt;/span&gt; parameterName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;&lt;br/&gt;      Predicate&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; propertyFilter = GetPropertyFilter( parameterDescriptor );&lt;br/&gt; &lt;br/&gt;      &lt;span class="rem"&gt;// finally, call into the binder&lt;/span&gt;&lt;br/&gt;      ModelBindingContext bindingContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; ModelBindingContext()&lt;br/&gt;      {&lt;br/&gt;        FallbackToEmptyPrefix = ( parameterDescriptor.BindingInfo.Prefix == &lt;span class="kwrd"&gt;null&lt;/span&gt; ), &lt;span class="rem"&gt;// only fall back if prefix not specified&lt;/span&gt;&lt;br/&gt;        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType( &lt;span class="kwrd"&gt;null&lt;/span&gt;, parameterType ),&lt;br/&gt;        ModelName = parameterName,&lt;br/&gt;        ModelState = controllerContext.Controller.ViewData.ModelState,&lt;br/&gt;        PropertyFilter = propertyFilter,&lt;br/&gt;        ValueProvider = valueProvider&lt;br/&gt;      };&lt;br/&gt; &lt;br/&gt;      &lt;span class="kwrd"&gt;object&lt;/span&gt; result = binder.BindModel( controllerContext, bindingContext );&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; result ?? parameterDescriptor.DefaultValue;&lt;br/&gt;    }&lt;p&gt;注释写的很明白，首先是搜集所有必须的绑定属性，先是parameterType，它等于参数的类型，因为ReflectionParameterDescriptor的实现是这样的：&lt;/p&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; Type ParameterType&lt;br/&gt;    {&lt;br/&gt;      get&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; ParameterInfo.ParameterType;&lt;br/&gt;      }&lt;br/&gt;    }&lt;p&gt;然后是binder，是GetModelBinder方法的结果，我们一会儿再来看这个方法，再接下来是valueProvider，其值是Controller的ValueProvider属性。然后是parameterName，这个值先要检查parameterDescriptor.BindingInfo.Prefix，如果不为空，就使用ParameterName。当然，ParameterName的实现显然是直接把参数名返回。这个BindingInfo我也回头再来看。接下来是propertyFilter，这是一个Predicate&amp;lt;T&amp;gt;委托类型的，这个委托的定义就是接收一个T参数，返回一个布尔值。结合名称来看，这个委托应该是提供决定哪些属性要被绑定的依据。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;接下来是创建ModelBindingContext，ModelMetadata则是通过GetMetadataForType方法获得。FallbackToEmptyPrefix则是判断Prefix属性是不是null，ModelState直接获取ViewData中的ModelState。其他的属性则是使用上面定义的的变量值。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;最后，调用IModelBinder的BindModel方法，如果返回的值是null，则使用parameterDescriptor.DefaultValue。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;坦白说，对这段代码的第一印象就是乱。首先是上面定义的变量，几乎都是用于创建ModelBindingContext的，这本来没什么问题，但在创建ModelBindingContext实例的时候，又夹杂了一些初始化代码而不是简单的直接用上面定义的变量来赋值。或者说同一个行为，使用了两种方式，这不是一个良好的代码习惯。&lt;/p&gt;&lt;p&gt;事实上，Model部分的代码质量明显要比其他部分的代码质量要糟糕，这一点在后面的探索中，您就会看到。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;将代码改成如下形式，是不是更清晰：&lt;/p&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; GetParameterValue( ControllerContext controllerContext, ParameterDescriptor parameterDescriptor )&lt;br/&gt;    {&lt;br/&gt; &lt;br/&gt;      IModelBinder binder = GetModelBinder( parameterDescriptor );&lt;br/&gt; &lt;br/&gt;      ModelBindingContext bindingContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; ModelBindingContext()&lt;br/&gt;      {&lt;br/&gt;        ModelName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName,&lt;br/&gt;        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType( &lt;span class="kwrd"&gt;null&lt;/span&gt;, parameterDescriptor.ParameterType ),&lt;br/&gt;        ModelState = controllerContext.Controller.ViewData.ModelState,&lt;br/&gt; &lt;br/&gt;        FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == &lt;span class="kwrd"&gt;null&lt;/span&gt;), &lt;span class="rem"&gt;// only fall back if prefix not specified&lt;/span&gt;&lt;br/&gt;        PropertyFilter = GetPropertyFilter( parameterDescriptor ),&lt;br/&gt;        ValueProvider = controllerContext.Controller.ValueProvider&lt;br/&gt; &lt;br/&gt;      };&lt;br/&gt; &lt;br/&gt;      &lt;span class="kwrd"&gt;object&lt;/span&gt; result = binder.BindModel( controllerContext, bindingContext );&lt;br/&gt; &lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; result ?? parameterDescriptor.DefaultValue;&lt;br/&gt;    }&lt;p&gt;至少，它凸显了主线逻辑，即：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;获取Binder &lt;/li&gt;  &lt;li&gt;构造BindingContext &lt;/li&gt;  &lt;li&gt;绑定Model &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;那么，我们来看看获取Binder的逻辑是怎样的：&lt;/p&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; IModelBinder GetModelBinder( ParameterDescriptor parameterDescriptor )&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="rem"&gt;// look on the parameter itself, then look in the global table&lt;/span&gt;&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; parameterDescriptor.BindingInfo.Binder ?? Binders.GetBinder( parameterDescriptor.ParameterType );&lt;br/&gt;    }&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;首先尝试从参数的BindingInfo中来获取Binder，如果没有，那么就从Binders中来获取。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;BindingInfo今天已经出场N次了，这东西哪来的？它是ParameterDescriptor的一个属性，在ReflectionParameterDescriptor构造函数中创建了其实例：&lt;/p&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; ReflectedParameterDescriptor( ParameterInfo parameterInfo, ActionDescriptor actionDescriptor )&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; ( parameterInfo == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException( &lt;span class="str"&gt;&amp;quot;parameterInfo&amp;quot;&lt;/span&gt; );&lt;br/&gt;      }&lt;br/&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; ( actionDescriptor == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException( &lt;span class="str"&gt;&amp;quot;actionDescriptor&amp;quot;&lt;/span&gt; );&lt;br/&gt;      }&lt;br/&gt; &lt;br/&gt;      ParameterInfo = parameterInfo;&lt;br/&gt;      _actionDescriptor = actionDescriptor;&lt;br/&gt;      _bindingInfo = &lt;span class="kwrd"&gt;new&lt;/span&gt; ReflectedParameterBindingInfo( parameterInfo );&lt;br/&gt;    }&lt;br/&gt;  &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; ParameterBindingInfo BindingInfo&lt;br/&gt;    {&lt;br/&gt;      get&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; _bindingInfo;&lt;br/&gt;      }&lt;br/&gt;    }&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;span style="font-size: x-small"&gt;&lt;/span&gt;&lt;p&gt;我们继续看ReflectedParameetrBindingInfo的代码，看看Prefix和Binder属性都是怎么来的：&lt;/p&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; ReflectedParameterBindingInfo( ParameterInfo parameterInfo )&lt;br/&gt;    {&lt;br/&gt;      _parameterInfo = parameterInfo;&lt;br/&gt;      ReadSettingsFromBindAttribute();&lt;br/&gt;    }&lt;p&gt;其构造函数很简单，设置了parameterInfo后，就调用了ReadSettingsFormBindAttribute：&lt;/p&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ReadSettingsFromBindAttribute()&lt;br/&gt;    {&lt;br/&gt;      BindAttribute attr = (BindAttribute) Attribute.GetCustomAttribute( _parameterInfo, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;( BindAttribute ) );&lt;br/&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; ( attr == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;br/&gt;      }&lt;br/&gt; &lt;br/&gt;      _exclude = &lt;span class="kwrd"&gt;new&lt;/span&gt; ReadOnlyCollection&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;( AuthorizeAttribute.SplitString( attr.Exclude ) );&lt;br/&gt;      _include = &lt;span class="kwrd"&gt;new&lt;/span&gt; ReadOnlyCollection&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;( AuthorizeAttribute.SplitString( attr.Include ) );&lt;br/&gt;      _prefix = attr.Prefix;&lt;br/&gt;    }&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;ReadSettingsFromBindAttribute方法正如其名，从附加在参数上的BindAttribute特性中获取配置值。并设置自己的属性值。可是设置的值里面，还是不包括Binder属性。那么来看看Binder属性的实现：&lt;/p&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; IModelBinder Binder&lt;br/&gt;    {&lt;br/&gt;      get&lt;br/&gt;      {&lt;br/&gt;        IModelBinder binder = ModelBinders.GetBinderFromAttributes( _parameterInfo,&lt;br/&gt;            () =&amp;gt; String.Format( CultureInfo.CurrentUICulture, MvcResources.ReflectedParameterBindingInfo_MultipleConverterAttributes,&lt;br/&gt;                _parameterInfo.Name, _parameterInfo.Member ) );&lt;br/&gt; &lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; binder;&lt;br/&gt;      }&lt;br/&gt;    }&lt;p&gt;继续看GetBinderFormAttributes方法的实现，尽管从方法名已经可以知道他大概是干什么的了：&lt;/p&gt;    &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IModelBinder GetBinderFromAttributes( ICustomAttributeProvider element, Func&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; errorMessageAccessor )&lt;br/&gt;    {&lt;br/&gt;      CustomModelBinderAttribute[] attrs = (CustomModelBinderAttribute[]) element.GetCustomAttributes( &lt;span class="kwrd"&gt;typeof&lt;/span&gt;( CustomModelBinderAttribute ), &lt;span class="kwrd"&gt;true&lt;/span&gt; &lt;span class="rem"&gt;/* inherit */&lt;/span&gt;);&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; GetBinderFromAttributesImpl( attrs, errorMessageAccessor );&lt;br/&gt;    }&lt;p&gt;获取附加的CustomModelBinderAttribute特性然后继续调用GetBinderFromAttributesImpl方法：&lt;/p&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IModelBinder GetBinderFromAttributesImpl( CustomModelBinderAttribute[] attrs, Func&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; errorMessageAccessor )&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="rem"&gt;// this method is used to get a custom binder based on the attributes of the element passed to it.&lt;/span&gt;&lt;br/&gt;      &lt;span class="rem"&gt;// it will return null if a binder cannot be detected based on the attributes alone.&lt;/span&gt;&lt;br/&gt; &lt;br/&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; ( attrs == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br/&gt;      }&lt;br/&gt; &lt;br/&gt;      &lt;span class="kwrd"&gt;switch&lt;/span&gt; ( attrs.Length )&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;case&lt;/span&gt; 0:&lt;br/&gt;          &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;br/&gt; &lt;br/&gt;        &lt;span class="kwrd"&gt;case&lt;/span&gt; 1:&lt;br/&gt;          IModelBinder binder = attrs[0].GetBinder();&lt;br/&gt;          &lt;span class="kwrd"&gt;return&lt;/span&gt; binder;&lt;br/&gt; &lt;br/&gt;        &lt;span class="kwrd"&gt;default&lt;/span&gt;:&lt;br/&gt;          &lt;span class="kwrd"&gt;string&lt;/span&gt; errorMessage = errorMessageAccessor();&lt;br/&gt;          &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; InvalidOperationException( errorMessage );&lt;br/&gt;      }&lt;br/&gt;    }&lt;p&gt;逻辑很简单，如果恰好只有一个特性，那么调用特性的GetBinder返回，如果没有一个，返回null，其他情况，使用errorMessageAccessor获取异常描述，抛出异常。&lt;/p&gt;&lt;p&gt;个人感觉这里的代码风格有着浓重的外包风格，冗长的调用链，甚少意义的参数以及明显生硬的抽出公共代码的痕迹。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;简而言之，ReflectedParameterBindingInfo的Binder属性尝试利用附加在参数上的BinderAttribute特性的GetBinder方法来获取Binder。如果没有通过BinderAttribute来获取到Binder，那么：&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: consolas"&gt;&lt;span style="font-size: 10pt"&gt;?? Binders.GetBinder( parameterDescriptor.ParameterType );&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Binders是一个ControllerActionInvoker的一个属性：&lt;/p&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;internal&lt;/span&gt; ModelBinderDictionary Binders&lt;br/&gt;    {&lt;br/&gt;      get&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; ( _binders == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;br/&gt;        {&lt;br/&gt;          _binders = ModelBinders.Binders;&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; _binders;&lt;br/&gt;      }&lt;br/&gt;      set&lt;br/&gt;      {&lt;br/&gt;        _binders = &lt;span class="kwrd"&gt;value&lt;/span&gt;;&lt;br/&gt;      }&lt;br/&gt;    }&lt;p&gt;其默认值是ModelBinders.Binders。ModelBinders.Binders则是系统中所有注册的IModelBinder的集合，来看看GetBinder的实现：&lt;/p&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; IModelBinder GetBinder( Type modelType )&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; GetBinder( modelType, &lt;span class="kwrd"&gt;true&lt;/span&gt; &lt;span class="rem"&gt;/* fallbackToDefault */&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; IModelBinder GetBinder( Type modelType, &lt;span class="kwrd"&gt;bool&lt;/span&gt; fallbackToDefault )&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; ( modelType == &lt;span class="kwrd"&gt;null&lt;/span&gt; )&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentNullException( &lt;span class="str"&gt;&amp;quot;modelType&amp;quot;&lt;/span&gt; );&lt;br/&gt;      }&lt;br/&gt; &lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; GetBinder( modelType, ( fallbackToDefault ) ? DefaultBinder : &lt;span class="kwrd"&gt;null&lt;/span&gt; );&lt;br/&gt;    }&lt;br/&gt; &lt;br/&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; IModelBinder GetBinder( Type modelType, IModelBinder fallbackBinder )&lt;br/&gt;    {&lt;br/&gt;      &lt;span class="rem"&gt;// Try to look up a binder for this type. We use this order of precedence:&lt;/span&gt;&lt;br/&gt;      &lt;span class="rem"&gt;// 1. Binder registered in the global table&lt;/span&gt;&lt;br/&gt;      &lt;span class="rem"&gt;// 2. Binder attribute defined on the type&lt;/span&gt;&lt;br/&gt;      &lt;span class="rem"&gt;// 3. Supplied fallback binder&lt;/span&gt;&lt;br/&gt; &lt;br/&gt;      IModelBinder binder;&lt;br/&gt;      &lt;span class="kwrd"&gt;if&lt;/span&gt; ( _innerDictionary.TryGetValue( modelType, &lt;span class="kwrd"&gt;out&lt;/span&gt; binder ) )&lt;br/&gt;      {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; binder;&lt;br/&gt;      }&lt;br/&gt; &lt;br/&gt;      binder = ModelBinders.GetBinderFromAttributes( modelType,&lt;br/&gt;          () =&amp;gt; String.Format( CultureInfo.CurrentUICulture, MvcResources.ModelBinderDictionary_MultipleAttributes, modelType.FullName ) );&lt;br/&gt; &lt;br/&gt;      &lt;span class="kwrd"&gt;return&lt;/span&gt; binder ?? fallbackBinder;&lt;br/&gt;    }&lt;p&gt;这里首先调用的是第一个重载，也就是只有一个参数的，然后他会调用到第二个重载，fallbackToDefault参数为true，再然后，会调用到第三个重载，因为fallbackToDefault参数是true，所以fallbackBinder参数的值会是DefaultBinder。&lt;/p&gt;&lt;p&gt;第三个重载才是真正干活的方法，首先尝试从_innerDictionary中获取IModelBinder实例，以modelType为键（这里的modelType就是parameterDescriptor.ParameterType，也就是参数的类型）。如果获存在，那么将其返回，否则，调用ModelBinders.GetBinderFromAttributes方法，这个方法刚刚才看过。其作用是从附加在modelType的BinderAttribute特性上获取Binder的实例。如果这也没有获取到，那么就返回fallbackBinder（也就是DefaultBinder）。&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;那么我们可以发现IModelBinder的选择过程和原则：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;尝试从附加在参数的CustomModelBinderAttribute特性获取 &lt;/li&gt;  &lt;li&gt;尝试从ModelBinders.Binders集合中按参数类型检索 &lt;/li&gt;  &lt;li&gt;尝试从附加在参数的类型的CustomModelBinderAttribute特性获取 &lt;/li&gt;  &lt;li&gt;使用ModelBinders.Binders.DefaultBinder &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;由上自下，优先级递减，在任何一个步骤找到了合适的Binder，则立即返回。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/1927667.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2011/01/06/aspnet-mvc-by-source-7.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2010/12/24/jumony-guide-4.html</id><title type="text">Jumony入门（四）无缝体验</title><summary type="text">在这一篇里面，我会来谈谈Jumony与现有技术的结合，以及带来的无缝的体验。在前面的文章中，我们见识了Jumony种种神奇的功能，它可以拦截一个HTML文件的请求，解析文件成为DOM，用选择器找出我们感兴趣的地方，并用简单的方法来绑定数据。这些看起来很酷，但做网站需要的不是一个看起来很酷的技术，如何与现有的成果兼容，如何利用现有的经验和积累，也是非常重要的问题。</summary><published>2010-12-23T16:39:00Z</published><updated>2010-12-23T16:39:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2010/12/24/jumony-guide-4.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2010/12/24/jumony-guide-4.html"/><content type="html">&lt;p&gt;首先介绍一下Jumony是什么，Jumony是一个.NET的开源项目，项目主页位于：&lt;a href="http://jumony.codeplex.com/"&gt;http://jumony.codeplex.com/&lt;/a&gt;，采用LGPL协议发布。&lt;/p&gt;&lt;p&gt;Jumony试图提供在传统Web开发模型中许多难以解决问题的解决方案。一言蔽之，Jumony的一切基础建立在服务器端的HTML DOM之上。在服务器端将HTML（文件或动态网页技术的输出）按照客户端浏览器的处理方式解析为HTML DOM。操纵和处理HTML DOM，就像我们在客户端用JavaScript干的那些事情一样，不同的是，Jumony可以使你依托强大的.NET Framework，来解决以前用脚本和服务器端技术都难以解决的事情。&lt;/p&gt;&lt;p&gt;系列目录：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/19/jumony-guide-1.html"&gt;Jumony入门（一）从这里开始&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/19/jumony-guide-2.html"&gt;Jumony入门（二）初识选择器&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/19/jumony-guide-3.html" target="_blank"&gt;Jumony入门（三）初探解析器&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这是系列文章的第四篇，这个系列尝试一步步从一些最简单的例子开始了解怎么玩转Jumony。建议先从第一篇开始学习搭建Jumony环境，在本文的开始的时候，假设大家已经完成了前三篇的示例。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在这一篇开始之前，先告诉大家一个好消息，Jumony入门系列的所有的源代码都已经上传到了Codeplex。这样大家就可以直接下载源代码对照着文章来实验，而不需要从截图中抄代码，避免了眼花和出错。&lt;/p&gt;&lt;p&gt;项目的网页是：&lt;a href="http://JumonyGuide.codeplex.com"&gt;http://JumonyGuide.codeplex.com&lt;/a&gt;。最新的源代码可以直接用SVN客户端下载，下载地址是：&lt;a href="https://JumonyGuide.svn.codeplex.com/svn/trunk/"&gt;https://JumonyGuide.svn.codeplex.com/svn/trunk/&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;当您看到这篇文章的时候，这篇文章所出现的所有示例代码应该已经上传到SVN服务器了。&lt;/p&gt;&lt;p&gt;如果您没有SVN客户端，或者还不清楚使用或者嫌SVN麻烦，可以直接在如下地址下载打包好的源代码：&lt;/p&gt;&lt;p&gt;&lt;a href="http://jumonyguide.codeplex.com/SourceControl/list/changesets"&gt;http://jumonyguide.codeplex.com/SourceControl/list/changesets&lt;/a&gt;&lt;/p&gt;&lt;p&gt;点击如下图中所示的Download链接，即可下载最新版本的源代码包。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240037509226.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038017688.png" border="0" alt="image" width="360" height="279" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在这一篇里面，我会来谈谈Jumony与现有技术的结合，以及带来的无缝的体验。在前面的文章中，我们见识了Jumony种种神奇的功能，它可以拦截一个HTML文件的请求，解析文件成为DOM，用选择器找出我们感兴趣的地方，并用简单的方法来绑定数据。这些看起来很酷，但做网站需要的不是一个看起来很酷的技术，如何与现有的成果兼容，如何利用现有的经验和积累，也是非常重要的问题。&lt;/p&gt;&lt;p&gt;在上一篇文章中，我们使用aspx文件的DataGrid控件呈现了互联网上某个页面的链接分析结果，如下图所示：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038035081.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038047457.png" border="0" alt="image" width="862" height="263" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;显然，这太丑了。我们来把它弄漂亮点，你一定会说这用CSS很容易，也可以改改DataGrid的样式属性什么的。但这一次我不打算用这些简单的方法，尽管这听起来有点儿愚蠢。但是我们不妨假设一下场景，这是一个很糟糕的系统中的一个页面，由于源代码管理的混乱，我们已经很难找到这个页面的源代码。源代码中逻辑复杂而又纠结，页面结构也是乱七八糟，除了这个表格是DataGrid的输出所以较为标准外，其余的部分都是使用一些完全不考虑后期维护的做法，样式引用混乱不堪。而且糟糕的是这个aspx文件已经被预编译成DLL事实上我们连页面都改不了。。。。&lt;/p&gt;&lt;p&gt;当然实际情况并不一定像上面说的这样糟糕。但实际上有一个现实的问题是Jumony并不是对于所有的页面和应用场景都有最佳的解决方案（尽管我希望是这样），或者说我们不可避免的要面对一个问题：Jumony可以帮助到WebForm或者现有技术驱动的页面吗？&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;当然可以，而且，So easy！&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;从这个系列的第一篇文章中我们学到，Jumony要求首先有一个静态的html文件，然后新建一个文件名前段与其完全一致的一般处理程序（ashx文件），这样，就可以在ashx文件中对静态的html文件进行各种处理了。同样的道理，如果我们将静态的HTML文件换成aspx文件，Jumony一样能处理！&lt;/p&gt;&lt;p&gt;那么我这边用作示范的aspx文件就是在上一篇中所使用的links.aspx，我们假设他就是那个悲惨的改不了的页面了，但老板现在要看到一个漂漂的版本。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;首先，创建一个links.aspx.ashx文件：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/20101224003805149.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038061130.png" border="0" alt="image" width="299" height="376" /&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038074619.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038084520.png" border="0" alt="image" width="479" height="358" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;注意这里为了避免名称冲突（事实上在网站项目里面不会冲突），我把类名改成了links_aspx。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;那么事实上这和处理静态HTML文件是一样的，Jumony引擎会自动截获aspx文件的输出，并解析成DOM供我们操纵。&lt;/p&gt;&lt;p&gt;第一件事，我们先要找出这个表格，由于DataGrid控件的ID是"DataList"，所以生成的表格的ID也就是"DataList"了，直接用ID选择器来选择之：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038084769.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038097735.png" border="0" alt="image" width="403" height="185" /&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/Ivony/201012/201012240038104288.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038113110.png" border="0" alt="image" width="485" height="203" /&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/Ivony/201012/201012240038123567.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/20101224003812436.png" border="0" alt="image" width="445" height="276" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Tips: Elements方法看起来和XLINQ的Element方法效果差不多，都是选择指定名称的元素，但Jumony的Elements方法要比XLINQ的强大许多。因为它是支持CSS元素选择器的（不支持层叠选择器）。事实上很多Jumony的这种方法都支持选择器哦，大家慢慢去发现吧。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&amp;nbsp;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;看看效果是不是好多了：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038136434.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038154665.png" border="0" alt="image" width="675" height="310" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;非常不错，接下来我来做一个隔行变色的效果，这可以用一个循环来实现，但更简单的办法是用CSS的nth伪类：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038163694.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038179974.png" border="0" alt="image" width="794" height="303" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;呵呵，Elements真的是支持选择器的哦，使用Elements而不是Find方法可以将查找范围限定为自己的直接子集而不是所有子代元素。这些技巧在一些特殊需求中可以派上大用场。&lt;/p&gt;&lt;p&gt;关于nth系列伪类的用途和语法，网上有很多的文章，在这里我不赘述。&lt;/p&gt;&lt;p&gt;然后我觉得认为IsLiningOut这一列纯属多余，我把这一列隐藏掉，对于外链的URL，我将字体设置为红色来表示：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038221082.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038247852.png" border="0" alt="image" width="1135" height="455" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Tips:细心的你可能又发现一个支持选择器的方法了。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;最终的效果：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/20101224003825228.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038261525.png" border="0" alt="image" width="601" height="376" /&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038271393.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012240038305522.png" border="0" alt="image" width="861" height="368" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;对比还是很明显的吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;可以看得出来，Jumony可以与现有的几乎任何WebForm的技术无缝集成，最大限度的保护了现有的劳动成果，您可以使用Jumony技术来解决一些问题，而无需放弃任何你所熟悉或是喜欢的技术。&lt;/p&gt;&lt;p&gt;谢谢大家。。。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;周末陪老婆旅游，所以下一篇，可能会要让大家等的稍微久一点点。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;您想用Jumony来构建什么？您对Jumony有什么建议？您对Jumony有什么疑惑？您希望Jumony增加一个怎样的很酷的功能？&lt;/p&gt;&lt;p&gt;那么欢迎来Jumony群畅所欲言：&lt;a href="http://qun.qq.com/#jointhegroup/gid/45510432" target="_blank"&gt;45510432&lt;/a&gt;。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/1915421.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/24/jumony-guide-4.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2010/12/22/jumony-guide-3.html</id><title type="text">Jumony入门（三）初探解析器</title><summary type="text">这一次我要谈到Jumony的HTML解析器，我将直接从互联网上随便抓一个页面来分析其所有链接信息并呈现为表格。</summary><published>2010-12-21T17:28:00Z</published><updated>2010-12-21T17:28:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2010/12/22/jumony-guide-3.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2010/12/22/jumony-guide-3.html"/><content type="html">&lt;p&gt;首先介绍一下Jumony是什么，Jumony是一个.NET的开源项目，项目主页位于：&lt;a href="http://jumony.codeplex.com/"&gt;http://jumony.codeplex.com/&lt;/a&gt;，采用LGPL协议发布。&lt;/p&gt;&lt;p&gt;Jumony试图提供在传统Web开发模型中许多难以解决问题的解决方案。一言蔽之，Jumony的一切基础建立在服务器端的HTML DOM之上。在服务器端将HTML（文件或动态网页技术的输出）按照客户端浏览器的处理方式解析为HTML DOM。操纵和处理HTML DOM，就像我们在客户端用JavaScript干的那些事情一样，不同的是，Jumony可以使你依托强大的.NET Framework，来解决以前用脚本和服务器端技术都难以解决的事情。&lt;/p&gt;&lt;p&gt;系列目录：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/19/jumony-guide-1.html"&gt;Jumony入门（一）从这里开始&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/19/jumony-guide-2.html"&gt;Jumony入门（二）初识选择器&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这是系列文章的第三篇，这个系列尝试一步步从一些最简单的例子开始了解怎么玩转Jumony。建议先从第一篇开始学习搭建Jumony环境，在本文的开始的时候，假设大家已经搭建好了Jumony的运行环境。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这一次我要谈到Jumony的HTML解析器，显然我自己写的简单的符合规范的HTML并不能说明解析器的功能。所以这一次我直接从互联网上随便抓一个页面来完成示范。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;首先在项目中添加一个aspx文件，然后在上面放一个DataGrid来展示我们一会儿要抓取的成果，像是这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127089957.png"&gt;&lt;img style="padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127098222.png" border="0" alt="image" width="708" height="271" /&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127097807.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/20101222012710532.png" border="0" alt="image" width="288" height="336" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;那么接下来，我们到Code Behind里面来添加一些代码，首先是要下载一个互联网的页面，我用新浪的首页来做示范，事实上你也可以换成任何你喜欢网站（例如博客园），下载网页最简单的方式当然是WebClient，不过记得添加using System.Net哦，同时我也把Jumony的一些引用都添加上了，像这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/20101222012712400.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127138316.png" border="0" alt="image" width="727" height="448" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;然后创建JumonyParser的实例，并调用其Parse方法将html分析成一个IHtmlDocument：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127149330.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127148708.png" border="0" alt="image" width="516" height="227" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Jumony Milestone 1除了提供Jumony Parser分析HTML文档之外，还可以把HtmlAgilityPack分析的文档转换成Jumony的标准DOM模型。这使得HtmlAgilityPack也可以当作Jumony的一个Parser来使用，下面的代码展示了这一点：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127156100.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127169905.png" border="0" alt="image" width="738" height="262" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;不过，这么做之前要确保你引用了Ivony.Web.Html.HtmlAgilityPackAdaptor命名空间，AsDocument扩展方法便是在其中定义的。&lt;/p&gt;&lt;p&gt;HtmlAgilityPackAdaptor为HtmlAgilityPack的DOM对象提供了一个适配器，使得其可以满足Jumony标准DOM的要求，从而使用Jumony的方法来操作。理论上所有的HTML DOM和Parser都可以通过适配项目与Jumony适配。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这两种HTML Parser各有优劣，大家可以任选一种来完成这一次的例子。在这里我使用Jumony Parser来继续下面的例子。&lt;/p&gt;&lt;p&gt;分析了新浪的首页后，接下来就要干坏事了，首先把新浪首页上所有的链接全部取出来。由于链接都是&amp;lt;a&amp;gt;定义的，所以简单的用Find( "a" )就可以选择出来。但&amp;lt;a&amp;gt;除了可以定义链接，还可以定义锚点，我们并不需要取出页面上的锚点。所以我们用"a[href]"，即包含href属性的a标签：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127174822.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127188868.png" border="0" alt="image" width="532" height="256" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;然后我们分析这些链接，将其目标URL取出来（即href属性），由于href可能是一个相对链接，所以我们用页面的地址 "http://www.sina.com.cn/" 作为基地址，重新计算出绝对的URL，然后我用LINQ表达式来对所有URL完成这样的操作，再放在一个匿名对象中：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127192672.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127201701.png" border="0" alt="image" width="637" height="405" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;可以看得出来，这些工作在服务器端完成的时候，是多么的简洁流畅，一气呵成。如果在客户端来完成这种事情，没有强大的.NET Framework作为后盾，一个简单的URL计算就可以难倒无数英雄好汉。&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;然后再为匿名对象添加一些其他有趣的属性，对链接排序，最后绑定到DataGrid上，最终的代码像这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127217981.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127229801.png" border="0" alt="image" width="776" height="499" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;由于DataGrid有自动生成列的特性，所以我们并不需要做些什么，它会自动的弄一个表格来展现这些数据，效果像是这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127242734.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127255666.png" border="0" alt="image" width="760" height="453" /&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127255044.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127264421.png" border="0" alt="image" width="243" height="457" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;把抓取的网页换成博客园首页：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/20101222012728876.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012220127294614.png" border="0" alt="image" width="905" height="566" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;写在最后&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Jumony的确可以用来干各种各样的坏事，譬如说抓取页面，分析数据，或是新闻小偷什么的。从这一点来说，你可以说Jumony是邪恶的，但&lt;a href="http://www.cnblogs.com/Ivony/archive/2009/07/18/1526150.html"&gt;软件本来就是邪恶的&lt;/a&gt;，Jumony将一些很复杂的事情，提供了简单的解决方案，也许，这降低了干坏事的成本，但更多的时候，Jumony带来了生产力的飞跃。借助Jumony，我们能做的好玩的事情，要比这些邪恶的事情多多了不是么？&lt;/p&gt;&lt;p&gt;谢谢大家。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/1913314.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/22/jumony-guide-3.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Ivony/archive/2010/12/20/jumony-guide-2.html</id><title type="text">Jumony入门（二）初识选择器</title><summary type="text">Jumony能干什么，这一次我将从一个具体的问题提出Jumony的解决方案，展现Jumony神奇的魅力。</summary><published>2010-12-20T09:05:00Z</published><updated>2010-12-20T09:05:00Z</updated><author><name>Ivony...</name><uri>http://www.cnblogs.com/Ivony/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Ivony/archive/2010/12/20/jumony-guide-2.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Ivony/archive/2010/12/20/jumony-guide-2.html"/><content type="html">&lt;p&gt;首先介绍一下Jumony是什么，Jumony是一个.NET的开源项目，项目主页位于：&lt;a href="http://jumony.codeplex.com/"&gt;http://jumony.codeplex.com/&lt;/a&gt;，采用LGPL协议发布。&lt;/p&gt;&lt;p&gt;Jumony试图提供在传统Web开发模型中许多难以解决问题的解决方案。一言蔽之，Jumony的一切基础建立在服务器端的HTML DOM之上。在服务器端将HTML（文件或动态网页技术的输出）按照客户端浏览器的处理方式解析为HTML DOM。操纵和处理HTML DOM，就像我们在客户端用JavaScript干的那些事情一样，不同的是，Jumony可以使你依托强大的.NET Framework，来解决以前用脚本和服务器端技术都难以解决的事情。  &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;系列目录：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/19/jumony-guide-1.html"&gt;Jumony入门（一）从这里开始&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这是系列文章的第二篇，这个系列尝试一步步从一些最简单的例子开始了解怎么玩转Jumony。建议先从第一篇开始学习搭建Jumony环境，在本文的开始的时候，假设大家已经搭建好了Jumony的运行环境。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;首先我们来看一个页面：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201748355202.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201748382920.png" border="0" alt="image" width="435" height="252" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这个页面的源代码如下：&lt;/p&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;!&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;DOCTYPE&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;html&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;PUBLIC&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;"-//W3C//DTD XHTML 1.0 Transitional//EN"&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;html&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;xmlns&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"http://www.w3.org/1999/xhtml"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;head&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;title&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Ranks&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;title&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;style&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #800000;"&gt;table&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #ff0000;"&gt;font-size&lt;/span&gt;&lt;/span&gt;: &lt;span&gt;&lt;span style="color: #0000ff;"&gt;12px&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #800000;"&gt;.ranks&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #800000;"&gt;th&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #ff0000;"&gt;height&lt;/span&gt;&lt;/span&gt;: &lt;span&gt;&lt;span style="color: #0000ff;"&gt;30px&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #ff0000;"&gt;font-size&lt;/span&gt;&lt;/span&gt;: &lt;span&gt;&lt;span style="color: #0000ff;"&gt;15px&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #ff0000;"&gt;font-family&lt;/span&gt;&lt;/span&gt;: &lt;span&gt;&lt;span style="color: #0000ff;"&gt;Arial&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #800000;"&gt;.ranks&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;, &lt;span&gt;&lt;span style="color: #800000;"&gt;.ranks&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #800000;"&gt;th&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #ff0000;"&gt;border-top&lt;/span&gt;&lt;/span&gt;: &lt;span&gt;&lt;span style="color: #0000ff;"&gt;solid&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;1px&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #800000;"&gt;.ranks&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #800000;"&gt;.name&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #ff0000;"&gt;font-weight&lt;/span&gt;&lt;/span&gt;: &lt;span&gt;&lt;span style="color: #0000ff;"&gt;bold&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #800000;"&gt;.ranks&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #800000;"&gt;table&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #ff0000;"&gt;border&lt;/span&gt;&lt;/span&gt;: &lt;span&gt;&lt;span style="color: #0000ff;"&gt;0px&lt;/span&gt;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;style&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;head&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;body&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;table&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;cellpadding&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"5"&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;cellspacing&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"0"&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"ranks"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;colspan&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"2"&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"top"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;table&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;cellpadding&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"3"&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;border&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"0"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;rowspan&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"3"&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;img&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;src&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"http://pic.cnblogs.com/avatar/a14218.jpg"&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;width&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"50"&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;height&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"50"&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td &lt;span&gt;&lt;span style="color: #ff0000;"&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"name"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Jumony&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;得票数: &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;style&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;color&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;red&lt;/span&gt;&lt;span&gt;;"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;100&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;主页地址： &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;href&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"http://jumony.codeplex.com/"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;http://jumony.codeplex.com/&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;table&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;th&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; № 2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;th&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"name"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Jumony&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;( &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;style&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;color&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;red&lt;/span&gt;&lt;span&gt;;"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;100&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; ) &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;href&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"http://jumony.codeplex.com/"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;http://jumony.codeplex.com/&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;th&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; № 3&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;th&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"name"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Jumony&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;( &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;style&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;color&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;red&lt;/span&gt;&lt;span&gt;;"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;100&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;span&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; ) &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span&gt;&lt;span style="color: #ff0000;"&gt;href&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;"http://jumony.codeplex.com/"&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;http://jumony.codeplex.com/&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;td&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;tr&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;table&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;body&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="font-family: Consolas;"&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #800000;"&gt;html&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;请先将份源代码保存为一个叫做ranks.htm的文件，然后我们开始对这个页面干点儿坏事。&lt;/p&gt;&lt;p&gt;这种页面，就是一种在传统的技术下，怎么也不好处理的页面，第一名的呈现方式与后面的呈现方式完全不同。即使用模版引擎，这种模版改起来怕也是件烦心事儿。&lt;/p&gt;&lt;p&gt;但强大CSS的选择器可以完全的抹平这些区别，使得我们的逻辑变得非常简单。&lt;/p&gt;&lt;p&gt;当然，首先，我们要建立一个这个页面的处理程序，也就是ranks.htm.ashx文件。然后添加using和继承基类，完成后的样子像这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704228826.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704272135.png" border="0" alt="image" width="307" height="294" /&gt;&lt;/a&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704298623.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704317868.png" border="0" alt="image" width="535" height="340" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;那么首先，我们要选择到class为ranks的那个table，再选择其每一行，选择器像是这样的：".ranks &amp;gt; tr"。&lt;/p&gt;&lt;p&gt;中间的&amp;gt;符号表示只选择.ranks的直接子集中的tr，因为在第一名的行中，HTML里面又被嵌了一个table来做绑定，里面也有一些tr元素。所以我们使用&amp;gt;选择符来避免选择到这些：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704333210.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704352456.png" border="0" alt="image" width="362" height="150" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;关于选择器的语法，是完全遵循&lt;a href="http://www.w3.org/TR/2009/PR-css3-selectors-20091215/"&gt;CSS Selector 3&lt;/a&gt;的标准的（部分实现）。如有不清楚的地方可以移步W3C的网站：&lt;a href="http://www.w3.org/TR/2009/PR-css3-selectors-20091215/"&gt;http://www.w3.org/TR/2009/PR-css3-selectors-20091215/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;另外需要注意的是这里我们是直接用Find方法的，而不是Document.Find，嗯，这是JumonyHandler提供的一个便利，对于Document的Find操作实在是太常用了，所以，Handler上定义了一个Find方法来对Document进行查找。当然，这和Document.Find是完全一样的效果。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;然后我们编造一些数据，例如：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704372781.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704382060.png" border="0" alt="image" width="684" height="264" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;接下来是将两个列表绑定在一起，Ivony.Fluent里面提供了一个方法：BindTo，这个方法可以方便的进行两个列表的绑定，使用方法像是这样：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704402484.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704419254.png" border="0" alt="image" width="447" height="145" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这里我使用的是lambda表达式，如果你喜欢也可以写成一个额外的方法，当然，在这个例子中，由于上面的数据类型我用的是匿名类型，所以这里没有办法拆出另一个方法出来，那么，我继续用lambda来示范。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;获取了每一个绑定的元素后，我们需要进一步考察每一个项（即Name、Votes和Url）要绑定的位置。只要是有规律的界面，那么其HTML就一定是有规律的，其实这个规律并不难找：&lt;/p&gt;&lt;p&gt;Name位于class="name"的元素中，而Votes则总是在一个style="color: red"的span里面，至于url，则总是在&amp;lt;a&amp;gt;那里，因为这是一个链接。当然，这个页面也可以说是事先设计好的，因为这里才第二篇，我们只考虑一些简单的示范，在后面，我们再来看在代码中的筛选逻辑能够做到怎样的智能。那么我们可以简单的写出选择器：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704432088.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201704454713.png" border="0" alt="image" width="611" height="221" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;注意这里的element直接就有Find方法，事实上Find方法并不是Document的专利，在Jumony中，只要是一个容器（IHtmlContainer），就可以Find，这实在非常便利。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;OK，现在数据就已经全部绑定到页面了，打开页面来看看效果。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201748403213.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201748434377.png" border="0" alt="image" width="407" height="254" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;很完美不是么？看看HTML源代码：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201806033334.png"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/Ivony/201012/201012201806043758.png" border="0" alt="image" width="830" height="528" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;怎么样，有没有一种在服务器端用jQuery的感觉？&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这里有几个问题需要注意一下：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;CSS选择器的关系选择符，如"&amp;gt;"或是"+"这些，在标准中两边是不必留有空白的，即可以写成".ranks&amp;gt;tr"。但Jumony不允许，是刻意如此，并非技术所限不能支持。因为Jumony认为强制性的留白可以提高这些选择符的可读性。&lt;/li&gt;&lt;li&gt;现有的版本中，不支持CSS Selector 3标准中的:not伪类和,选择符，其余的全部支持。jQuery的私有伪类则全部不支持。&lt;/li&gt;&lt;li&gt;如果你觉得linkContainer.SetAttribute( "href" ).Value( dataItem.Url )这种写法很恶心，那么不必担心。下个版本就可以这样写了：&lt;br /&gt;linkContainer.SetAttribute( "href" ,dataItem.Url )&lt;br /&gt;还可以这样：linkContainer.href = dataItem.Url&lt;/li&gt;&lt;/ol&gt;&lt;img src="http://www.cnblogs.com/Ivony/aggbug/1911619.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Ivony/archive/2010/12/20/jumony-guide-2.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
