为ASP.NET MVC 1.0添加Areas

原创|其它|编辑:郝浩|2010-02-08 10:32:03.000|阅读 1198 次

概述:今天闲逛时看到MVC 2.0的一些新特性,其中一样就是:提供域划分功能(Areas)。MVC 1.0刚发布的时候,我就为这个东西纠结过一段时间,后来在老外的Blog上看到了一个简单的解决方案,一直都在用,现整理出来,给有需要的同学做个参考。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

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

2.为模块设计路由

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

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


以下为实现
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;
        }
    }
}

标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:博客园

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP