连续忙了好几个月,好久没有写东西了,最近稍微有点空,空闲的时候回到了对ASP.NET MVC RC(以下简称MVC RC)的研究上来。MVC RC的“脚手架(Scaffold)”功能可以说为MVC RC的开发如虎添翼,不过应用到真实的开发环境中似乎存在一些遗憾的地方:很多时候我们并不希望把Models、Views和Controllers放在同一个项目里面,而是把它们分离到不同的项目,然后由一个项目(比如Views)统一引用其他所有的项目程序集。但是这样做了以后,Controllers项目中脚手架的功能就“消失了”。
在Web(MVC RC)项目中,我们可以这样在Web项目中使用脚手架创建View页面:
或者创建Controller文件:
甚至可以在Controller文件中自动创建或者查看对应Action的View页面:
不过这一切经历了Views和Controllers的“生死离别”之后,就再也无法在Controllers中使用了(原因会在下文中说明)。下面我们来做一个测试。
首先我们先把M、V、C三层分离,比如这样:
需要注意的是当这样做的时候,在Controllers项目中需要引用以下这三个核心的程序集:
System.Web.Abstractions.dll
System.Web.Mvc.dll
System.Web.Routing.dll
以及一些在默认的Controller.cs文件中被引用到的命名空间,如:
System.Web
System.Configuration
以下是分离M-V-C(M之所以也要分离出去是因为C需要引用M,而C不能引用V)之后,运行的默认界面,说明这样的分离是成功的:
OK,到此为止MVC工作正常,只不过……无法在MyMvc.Controllers中使用MVC的脚手架:
分析一下原因:我们在把Controller分离出来的时候是建了“类库(Class Library)”,一个普通的类库当然无法使用MVC(Web)的脚手架,于是我打开了MyMvc.Web的项目文件MyMvc.Web.csproj,用记事本打开这个文件(本质上是一个XML文件),发现了一个和其他项目与众不同的地方:
<ProjectTypeGuids>{603c0e0b-db56-11dc-be95-000d561079b0};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
这个节点中用分号分割了3段看似Guid的代码,分别是:
{603c0e0b-db56-11dc-be95-000d561079b0}
{349c5851-65df-11da-9384-00065b846f21}
{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
立刻对比了一下MyMvc.Controllers下面的MyMvc.Controllers. csproj,发现没有这个节点。喜出望外!于是马上将这个节点复制到MyMvc.Controllers. csproj对应的地方,重新加载项目以后,发现MyMvc.Controllers的脚手架功能回来了!
不过通过这样简单的添加还是发现了一些小小的瑕疵:细观MyMvc.Controller的项目图标类型,怎么和Web的时一样的(下图)?不爽。
看来这样的直接复制是把整个MVC Web Application下面的类型都一起复制过来了,为了避免日后不必要的麻烦,还是需要让Controllers变回“类库”,于是打起了那三个Guid的注意,经过两次两两搭配后({fae04ec0-301f-11d3-bf4b-00c04f79efbc}一定要保留)发现,只要删除中间的{349c5851-65df-11da-9384-00065b846f21}之后,MyMvc.Controllers项目又回到了“类库”的状态:
于是猜测{fae04ec0-301f-11d3-bf4b-00c04f79efbc}对应了Web Application的项目类型,而{603c0e0b-db56-11dc-be95-000d561079b0}对应了MVC RC的模板。
注意:{603c0e0b-db56-11dc-be95-000d561079b0}对应了MVC RC(v1.0)的项目代码,
如果您使用的是MVC 2.0(包括Preview版本在内),对应的编码为:{F85E285D-A4E0-4152-9332-AB1D724D3325} !
如果您使用的是MVC 3.0(包括Beta和RC版本在内),对应的编码为:{E53F8FEA-EAE0-44A6-8774-FFD645390401} !
通过以上这些操作,分离了M-V-C结构,并且在Controllers中“完整”保留了MVC RC的脚手架的功能。
上面的“完整”之所以要突出一下,是因为这种保留实在是太“完整”了,以至于在Controller中自动添加View页面会添加到Controller项目中,而不是我们所希望的MyMvc.View项目中(查看对应View页面也存在相同的问题)。这倒是个大问题,如果这个问题不解决,那么“脚手架”反而成了“绊脚石”,这个问题如何解决呢?
请看下一篇《为ASP.NET MVC RC分离C-V项目后添加“脚手架”功能(二)》
(本文的实例也在《ASP.NET MVC RC分离C-V项目后添加“脚手架”功能(二)》中提供下载。)