的物理路径.
接着在IView的Render事件中,根据物理路径创建了一个页面的object实例,注意看这一段代码:
object viewInstance = BuildManager.CreateInstanceFromVirtualPath(ViewPath, typeof (object));
if (viewInstance == null) {
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentUICulture,
MvcResources.WebFormViewEngine_ViewCouldNotBeCreated,
ViewPath));
}
ViewPage viewPage = viewInstance as ViewPage;
if (viewPage != null) {
RenderViewPage (viewContext, viewPage);
return;
}
ViewUserControl viewUserControl = viewInstance as ViewUserControl;
if (viewUserControl != null) {
RenderViewUserControl(viewContext, viewUserControl);
return;
}
viewInstance 就是通过物理路径创建的页面对象.但是他的类型是object, 而且程序尝试将其分别转 化为ViewPage对象和ViewUserControl对象.
我想很多人都看到了这里的设计不足.现在我们只能"约定": 所有的MVC中的页面对象都必 须继承自ViewPage或者ViewUserControl类, 否则程序就会出错.产生这种不足的原因就是IView接口和 ViewPage没有任何的耦合性, 完全是硬编码进去的.
为什么不让页面直接实现IView接口? 然后尝试将页面转化为IView接口对象, 而不是ViewPage, 这样 才是好的设计. 其实微软知道什么是好的设计, 我猜测他们遇到的困难是Page对象和IView接口的冲突. 因为两者都需要Render. 如果在IView中定义自己的Render名称, 那就意味着ASP.NET MVC开发小组要自己 处理页面的显示逻辑, 而现在ASP.NET WebForm模式下面的页面显示引擎又不能复用, 重新开发自己的一 套显示引擎成本又太大, 才出此下策.
以上只是猜测.这种设计的缺陷虽然可以接受, 但是真的是让我好几天陷入了看不懂代码的痛苦之中. 还好, 现在可以解脱了.
七.如何在MVC项目中使用MVC源代码项目
另外在为了跟踪实现过程, 我将ASP.NET MVC的源代码项目添加到了实例项目中, 其中有一些需要注意 的地方:
1. 将实例项目中的System.Web.Mvc引用删除, 改成项目引用.
2. 需要在Web.Config中注释掉程序集引用:
<compilation debug="true">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<!-- <add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>-->
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
注释掉的程序集存在于GAC中, 但是我们现在不希望使用GAC中的程序集, 而是引用项目.
3. 将View目录下的Web.Config中的所有System.Web.Mvc相关的 PublicKeyToken 都修改为 null:
<pages
valida
|