代码改变世界

通过源代码研究ASP.NET MVC中的Controller和View(四)

2010-11-20 16:30  Ivony...  阅读(3616)  评论(9编辑  收藏  举报

通过源代码研究ASP.NET MVC中的Controller和View(一)

通过源代码研究ASP.NET MVC中的Controller和View(二)

通过源代码研究ASP.NET MVC中的Controller和View(三)

 

第四篇,在上一篇我们知道具体的Render操作是由ViewPage和ViewUserControl来负责完成的。那么到这里,我的研究已经到头了。因为已经有足够的信息来完成Jumony的ASP.NET MVC支持,这个工作正在进行,ASP.NET MVC中一些设计的原理和思想也会不同程度的渗入Jumony的架构。

在这里插句嘴谈一下Jumony View的一些设计(还在设计阶段,会陆续实现),由于Jumony建议表现完全用HTML来描述,所以对于ActionLink这样不可能用HTML描述的东西,就会采用类HTML语法,像是这样:

<a action="Index" controller="Home">主页</a>

对比一下MVC的默认视图语法:

<%: Html.ActionLink("主页", "Index", "Home")%>

或是Razor引擎:

@Html.ActionLink("主页", "Index", "Home")

当然,在生成后的HTML里面,action和controller都会消失不见的(融入href),如果需要增加一些自定义的RouteValues,则只需在名称前面加个"_"即可:

<a action="Index" controller="Home" _id="123">主页</a>

但任何时候对于没有action属性的<a>,不作任何处理(也就是说不管有没有controller或前面有下划线的属性,都会被当作普通的链接)。

 

对于ViewData和Model的绑定,也计划提供相当程度上的便利支持:

<view name="ViewDataName" /><model path="Username" />

等同于:

<%: ViewData["ViewDataName"] %><%: Model.Username %>

还有XAML类似的属性设置语法也在考虑:

<img src="{View name=ViewDataName}" /><img src="{Model path=Username}" /> 

绑定样式表中,则比较简单:

#username
{
  binding-source: $Model;
  binding-path: Username;
}

 

OK,广告到此结束。

在进入Controller的研究之前,我先来总结一下MVC的View部分的结构和HTML视图是如何呈现的:

故事的开头是ActionResult,这是View的入口。

ActionResult有许多派生类,用于对视图进行不同的改变。其中有两个类型:ViewResult和ViewResultBase,他们负责HTML视图的呈现,或者说呈现页面。

ViewResultBase重写了ActionResult的ExecuteResult方法,通过调用派生类的FindView方法来获取一个IView对象,然后调用IView对象的Render方法来执行具体的呈现工作。

ViewResultBase系统的派生类是ViewResult和PartialViewResult,这两个类型的FindView方法都是直接将逻辑外包给了ViewResultBase.ViewEngineCollection去完成,而ViewResultBase.ViewEngineCollection实际上是ViewEngines.Engines的马甲。

ViewEngines.Engines搜索所有的ViewEngine,看看谁能提供一个ViewEngineResult。

那么默认有一个ViewEngine就是WebFormViewEngine,它的基类VirtualPathProviderViewEngine实现了FindView,然后将name通过GetPath方法转换为path,再交给派生类的CreateView方法来创建IView实例返回。

全流程图如下:

image

 

这一篇比较短,画图是个体力活。从后面开始,我将从ActionResult反推Controller的实现。

 

也敬请关注Jumony项目