MVC 路由重定向

一般我们在MVC开发过程中,都会碰到这样的问题。页面总是写在Views文件夹下,而且还只能一个Controller的页面只能写在相应的以Controller名命名的文件夹下。如果我们写到别处呢?那么肯定会报错。这是MVC中的一个规定,必须这样写。

- i' G$ q3 R8 p% x

1、正常项目目录规则要求标准如下(图一)。我们要访问Index页面,只需要输入http://域名:端口号/Home/Index(本项目示例访问地址为http://localhost:64968/Home/Index)就可以访问了。我们之所以能够这样访问,是因为我们在项目创建之初系统就默认配置了一个默认的路由。我们可以按照这个默认的路由规则进行访问。默认的路由规则代码(路由目录:项目/App_Start/RouteConfig.cs)如下(代码一)。

; F; c: [8 g& p9 r2 [' A% V
图一
  1.     public class RouteConfig1 p; G  M* ]7 c0 |3 b
  2.     {
  3.         public static void RegisterRoutes(RouteCollection routes)+ ]8 z/ J3 w7 c9 g
  4.         {/ d8 B% ~' J* Z/ y& m
  5.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");2 s, X& o# K, Z& E* {0 q

  6.             routes.MapRoute(
  7.                 name: "Default",
  8.                 url: "{controller}/{action}/{id}",
  9.                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  10.             );# `- f2 }3 I9 m$ ^6 ~6 ~3 V
  11.         }/ l; e) x* [- w$ z2 z+ k
  12.     }
复制代码
代码一 % B; _8 I( C" Z. j! K' r. R  P8 [& E
7 o, r% `( M# Z1 S# `, \

2、那么我们要求的MVC多级目录规则如何呢?如下(图二)。如果我们要访问Admin下的DemoController里面的Index页面,那么我们输入http://域名:端口号/Demo/Index(本项目示例访问地址为http://localhost:64968/Demo/Index),通过这肯定是访问不了的(无法找到资源。)。因为DemoController根本就不在Controllers的根目录下,而是在Controllers/Admin下,这样我们根本就找不到DemoController。那么我们输入http://域名:端口号/Admin/Demo/Index(本项目示例访问地址为http://localhost:64968/Admin/Demo/Index)现在也是访问不了的(无法找到资源。),那么我们就需要添加一个路由配置了,因为以前的默认路由只能通过{Controller}/{Action}/{Id}这种方式访问,就是必须以Controller开头。我们重新配置的路由(路由目录:项目/App_Start/RouteConfig.cs)添加一条规则如下(代码二)。


图二
  1.     public class RouteConfig: r' h. `/ p3 _$ W
  2.     {% i$ d8 D6 O4 \+ s% [0 x
  3.         public static void RegisterRoutes(RouteCollection routes)6 `$ g7 r# Q2 C5 t
  4.         {& U) d( N: f3 n
  5.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

  6.             //路由规则匹配是从上到下的,优先匹配的路由一定要写在最上面。路由匹配成功以后,不会继续匹配下去。3 S0 M; d& ?0 e1 |+ s. Y
  7.             routes.MapRoute(
  8.                 name: "Admin",
  9.                 url: "Admin/{controller}/{action}/{id}",, f+ U1 ~/ o) ~% l5 a/ I! \+ ^$ c
  10.                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  11.             );

  12.             routes.MapRoute(
  13.                 name: "Default",8 s/ l1 m0 R) p* V5 L6 Y0 ?
  14.                 url: "{controller}/{action}/{id}",* z% S. E7 ?/ ~$ }; [# J
  15.                 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  16.             );
  17.         }1 B! @9 G* l3 h# F" R
  18.     }
复制代码
代码二

3、那么现在我们再次输入http://域名:端口号/Admin/Demo/Index(本项目示例访问地址为http://localhost:64968/Admin/Demo/Index),能找到Views/Admin/Demo/Index.cshtml这个页面吗?显然是不能的(未找到视图。),因为除了路由配置怎么访问Controller外,寻找Views里面的页面也有自己的规则。测试结果肯定是找不到页面,我们看看错误信息(图三)就知道他是怎么寻找cshtml页面了。



图三
1 h. Y6 [$ h2 Z( T. s2 e; T# Z

据错误信息搜索位置只搜索这些地址,这里我只写Razor视图的地址,写成通配符就是:
Views/{1}/{0}.cshtmlViews/Shared/{0}.cshtml6 v$ k* t# @" J: g
{1}表示Controller的名称,{0}表示视图名称,Shared是存放模板页的文件夹。一看就很清楚了。这个就是寻找视图的规则,所以我们存放在Admin/Demo/Index.cshtml的存放规则就不满足。所以不能正常访问。按照此规则我们创建Views/Demo文件夹,并创建文件Views/Demo/Index.cshtml(图四)。至此http://域名:端口号/Admin/Demo/Index(本项目示例访问地址为http://localhost:64968/Admin/Demo/Index)则可以访问(图五),但是不是我们所要求的,既然我们Controller区分存放了,我们肯定也希望Views也能够这样存放的。

/ ]1 i; v1 Q! r' M# x3 L2 h* e
图四

# x" t6 P7 Q8 W6 ]* r+ {
图五

4、Views存放规则如何修改呢?现在就开始修改寻找规则。第一先创建一个RouteViewEngine.cs类。类代码(代码三),规则重新定义好后将这个规则注册到系统中,将在Global.asax中注册一下,这样我们就可以通过自己的方式来访问了。


  1. using System;
  2. using System.Collections.Generic;4 a  o9 Q/ b2 f  h) ]6 |& w
  3. using System.Linq;& d4 F0 P' N1 X' z& U  {1 W+ Y
  4. using System.Web;
  5. using System.Web.Mvc;

  6. namespace MvcRouteDemo
  7. {; K3 f& k% `2 @7 C# @/ Z, e
  8.     public sealed class RouteViewEngine : RazorViewEngine$ l- K( l, S' N. T! a0 S
  9.     {
  10.         public RouteViewEngine()
  11.         {
  12.             ViewLocationFormats = new[]
  13.             {5 n, v: K* O, X+ K- ?
  14.                 "~/Views/{1}/{0}.cshtml"," D% a+ j, X, L+ p& @
  15.                 "~/Views/Shared/{0}.cshtml",& u# D, V" n  D" n
  16.                 "~/Views/Admin/{1}/{0}.cshtml"//这是我们添加的规则
  17.             };
  18.         }3 T% L. \: I5 E; V
  19.         public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
  20.         {
  21.             return base.FindView(controllerContext, viewName, masterName, useCache);9 f$ s2 D$ ?5 y' i  `* F
  22.         }- ?$ u' f6 U1 D% t# A' r& ^7 b1 }
  23.     }' X0 o4 S2 S* P( n8 d# H) s0 C5 k  T
  24. }
复制代码
代码三

5、Global.asax注册操作(代码四)。


  1.     public class MvcApplication : System.Web.HttpApplication
  2.     {
  3.         protected void Application_Start()  ~5 g: l8 _- g* b- f/ Y
  4.         {$ q( n. ?3 B( a- n
  5.             AreaRegistration.RegisterAllAreas();
  6. + A& i2 H& s, o9 d
  7.             WebApiConfig.Register(GlobalConfiguration.Configuration);( l' X+ Q; [: t. t+ B; @
  8.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  9.             RouteConfig.RegisterRoutes(RouteTable.Routes);
  10.             BundleConfig.RegisterBundles(BundleTable.Bundles);
  11. * G* P7 B* `% f6 m% i
  12.             RegisterView();//注册视图访问规则到系统中
  13.         }/ r8 o% v5 I( v- g3 B

  14.         protected void RegisterView()0 U" B" }5 |9 ]. {: O! b
  15.         {
  16.             ViewEngines.Engines.Clear();
  17.             ViewEngines.Engines.Add(new RouteViewEngine());
  18.         }9 a$ ?! {: `2 `# s8 y- d
  19.     }
复制代码
代码四
6 b  o/ R# T( a

5、最后删除(图四)之前所修改路由表测试的文件夹删除,再次访问http://域名:端口号/Admin/Demo/Index(本项目示例访问地址为http://localhost:64968/Admin/Demo/Index)就可以实现我们的目的(图六)。

& Y' o2 f( s6 ]( A+ F7 P+ E" b
图六 6 f: K, J# Z9 V' p7 _% e  B

最终送上本次示例项目。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值