为ASP.NET MVC 1.0添加Areas

       今天闲逛时看到MVC 2.0的一些新特性,其中一样就是:提供域划分功能(Areas)。MVC 1.0刚发布的时候,我就为这个东西纠结过一段时间,后来在老外的Blog上看到了一个简单的解决方案,一直都在用,现整理出来,给有需要的同学做个参考。
      园子里对这个功能关注的人好象不是很多,所以对此功能稍做一下解释。域划分简单的说就是按功能来划分模块。如用户模块(User)及文章模块(Article),每个模块都有好几个Controller,也许我们需要把模块分别放在独立的命名空间下。在Url上,模块划分体现为:/{Area}/{Controller}/{Action}。(可能我说的不大清楚,尚不明白的请自行到网上搜索)
以下为步骤:
1.把Controller按模块分类。

为ASP.NET MVC 1.0添加Areas_第1张图片

2.为模块设计路由

为ASP.NET MVC 1.0添加Areas_第2张图片

3.更换模板引擎(见上图)

4.将视图移至Area文件夹(路径为/{Area}/{Controller}/{Action})


为ASP.NET MVC 1.0添加Areas_第3张图片

以下为实现
1.为路由添加area

代码
using  System.Web.Routing;

namespace  Madnet.DevMvc
{
    
public   static   class  RouteHelper
    {
        
public   static   void  CreateArea( this  RouteCollection routes,  string  areaName,  string [] controllersNamespace,  params  Route[] routeEntries)
        {
            
foreach  (var route  in  routeEntries)
            {
                
if  (route.Constraints  ==   null ) route.Constraints  =   new  RouteValueDictionary();
                
if  (route.Defaults  ==   null ) route.Defaults  =   new  RouteValueDictionary();
                
if  (route.DataTokens  ==   null ) route.DataTokens  =   new  RouteValueDictionary();

                route.Constraints.Add(
" area " , areaName);
                route.Defaults.Add(
" area " , areaName);
                route.DataTokens.Add(
" namespaces " , controllersNamespace);

                
if  ( ! routes.Contains(route))  //  To support "new Route()" in addition to "routes.MapRoute()"
                    routes.Add(route);
            }
        }
    }
}

 

2.改造模板引擎,以满足基于area的模板路径搜索

代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Web.Mvc;

namespace  Madnet.DevMvc
{
    
public   class  DefaultViewEngine: WebFormViewEngine
    {
        
public  DefaultViewEngine()
            : 
base ()
        {
            ViewLocationFormats 
=   new [] { 
                
" ~/{0}.aspx " ,
                
" ~/{0}.ascx " ,
                
" ~/Views/{1}/{0}.aspx " ,
                
" ~/Views/{1}/{0}.ascx " ,
                
" ~/Views/Shared/{0}.aspx " ,
                
" ~/Views/Shared/{0}.ascx " ,
            };

            MasterLocationFormats 
=   new [] {
                
" ~/{0}.master " ,
                
" ~/Shared/{0}.master " ,
                
" ~/Views/{1}/{0}.master " ,
                
" ~/Views/Shared/{0}.master " ,
            };

            PartialViewLocationFormats 
=  ViewLocationFormats;
        }
        
#region  IViewEngine Members
        
public   override  ViewEngineResult FindPartialView(ControllerContext controllerContext,  string  partialViewName,  bool  useCache) {
            
            ViewEngineResult areaResult 
=   null ;
            
            
if  (controllerContext.RouteData.Values.ContainsKey( " area " )) {
                
string  areaPartialName  =  FormatViewName(controllerContext, partialViewName);
                areaResult 
=   base .FindPartialView(controllerContext, areaPartialName, useCache);
                
if  (areaResult  !=   null   &&  areaResult.View  !=   null ) {
                    
return  areaResult;
                }
                
string  sharedAreaPartialName  =  FormatSharedViewName(controllerContext, partialViewName);
                areaResult 
=   base .FindPartialView(controllerContext, sharedAreaPartialName, useCache);
                
if  (areaResult  !=   null   &&  areaResult.View  !=   null ) {
                    
return  areaResult;
                }
            }

            
return   base .FindPartialView(controllerContext, partialViewName, useCache);
        }

        
public   override  ViewEngineResult FindView(ControllerContext controllerContext,  string  viewName,  string  masterName,  bool  useCache) {
            ViewEngineResult areaResult 
=   null ;

            
if  (controllerContext.RouteData.Values.ContainsKey( " area " )) {
                
string  areaViewName  =  FormatViewName(controllerContext, viewName);
                
string  masterAreaViewName  =  FormatMasterViewName(controllerContext, masterName);
                areaResult 
=   base .FindView(controllerContext, areaViewName, masterAreaViewName, useCache);
                
if  (areaResult  !=   null   &&  areaResult.View  !=   null )
                {
                    
return  areaResult;
                }

                areaResult 
=   base .FindView(controllerContext, areaViewName, masterName, useCache);
                
if  (areaResult  !=   null   &&  areaResult.View  !=   null ) {
                    
return  areaResult;
                }

                
string  sharedAreaViewName  =  FormatSharedViewName(controllerContext, viewName);
                areaResult 
=   base .FindView(controllerContext, sharedAreaViewName, masterAreaViewName, useCache);
                
if  (areaResult  !=   null   &&  areaResult.View  !=   null )
                {
                    
return  areaResult;
                }
                areaResult 
=   base .FindView(controllerContext, sharedAreaViewName, masterName, useCache);
                
if  (areaResult  !=   null   &&  areaResult.View  !=   null ) {
                    
return  areaResult;
                }
            }

            
return   base .FindView(controllerContext, viewName, masterName, useCache);
        }
        
#endregion  IViewEngine Members
        
private   static   string  FormatViewName(ControllerContext controllerContext,  string  viewName)
        {
            
string  controllerName  =  controllerContext.RouteData.GetRequiredString( " controller " );
            
string  area  =  controllerContext.RouteData.Values[ " area " ].ToString();
            
return   " Views/ "   +  ( string .IsNullOrEmpty(area)  ?   ""  : (area  +   " / " ))  +   " / "   +  controllerName  +   " / "   +  viewName;
        }

        
private   static   string  FormatSharedViewName(ControllerContext controllerContext,  string  viewName)
        {
            
string  area  =  controllerContext.RouteData.Values[ " area " ].ToString();
            
return   " Views/ "   +  ( string .IsNullOrEmpty(area)  ?   ""  : (area  +   " / " ))  +   " /Shared/ "   +  viewName;
        }
        
private   static   string  FormatMasterViewName(ControllerContext controllerContext,  string  masterName)
        {
            
string  area  =  controllerContext.RouteData.Values[ " area " ].ToString();
            
return   " Views/ "   +  ( string .IsNullOrEmpty(area)  ?   ""  : (area  +   " / " ))  +   " /Masters/ "   +  masterName;
        }
    }
}

 --------------------------------------
http://www.qwolf.com/

 

你可能感兴趣的:(asp.net)