当前位置:首页 > mvc4自定义调用视图的方法

mvc4自定义调用视图的方法

点击次数:3890  更新日期:2014-07-02

1.正常的项目目录,如下图:

      

      我们要访问Index页面,只需要输入Home/Index就可以访问了。我们之所以能够这样访问,是因为我们在项目创建之初系统就默认配置了一个默认的路由。我们可以按照这个默认的路由规则进行访问。

2.那么我们再来看我们需要的访问方式,如下图

      如果我们要访问Admin下的TestController里面的Index页面,那么我们输入Test/Index,这个肯定不行的。因为TestController根本就不在Controllers的根目录下,而是在Controllers/Admin下,这样我们根本就找不到Test这个Controller。那么我们输入Admin/Test/Index,那么我们就需要添加一个路由配置了,因为以前的默认路由只能通过{Controller}/{Action}/{Id}这种方式访问,就是必须以Controller开头。我们重新配置的路由如下:

 View Code

 那么我们这个时候再次输入Admin/Test/Index,能找到Views/Admin/Test/Index.cshtml这个页面吗?显然是不能的,因为除了路由配置怎么访问Controller外,寻找Views里面的页面也有自己的规则。测试结果肯定是找不到页面,我们看看错误信息就知道他是怎么寻找cshtml页面了。

    

    

“The following locations were searched” 翻译过来就是"以下地址被搜索过"。那么他只搜索这些地址,这里我只写razor视图的地址,写成通配符就是:

  • Views/{1}/{0}.cshtml

  • Views/Shared/{0}.cshtml

{1}表示Controller的名称,{0}表示视图名称,Shared是存放模板页的文件夹。一看就很清楚了。这个就是寻找视图的规则,所以我们存放在Admin/Test/Index.cshtml的存放规则就不满足。那么我们修改下,如下图:

  直接将Test文件夹存放在Views下面,那么我们就满足这个寻找视图的规则了,我们输入Admin/Test/Index,也确实访问成功了。

    

但是这个方式的存储肯定不是我们需要的,既然我们Controller区分存放了,我们肯定也希望Views也能够这样存放的。

3.那么我们进入正题,修改他的寻找视图的规则,让他能够按照我们的规则来访问,就像修改路由一样。

在项目中新建立一个cs类MyViewEngine,继承RazorViewEngine。代码如下:


using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

namespace MvcRoute.MvcEx

{


    public sealed class MyViewEngine : RazorViewEngine

    {


        public MyViewEngine()

        {

            ViewLocationFormats = new[]

            {

                "~/Views/{1}/{0}.cshtml",

                "~/Views/Shared/{0}.cshtml",

                "~/Views/Admin/{1}/{0}.cshtml"//我们的规则

            };

        }

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)

        {

            return base.FindView(controllerContext, viewName, masterName, useCache);

        }


    }

}

然后将这个规则注册到系统中,在global中注册一下,这样我们就可以通过自己的方式来访问了。global注册如下:


protected void Application_Start()

{

AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);

RegisterRoutes(RouteTable.Routes);

RegisterView();//注册视图访问规则

}


protected void RegisterView()

{

ViewEngines.Engines.Clear();

ViewEngines.Engines.Add(new MyViewEngine());

}

 结果如下图: