ASP.NET MVC自定义视图路由

我们的解决方案层次结构如下:

控制器\目录\查看

例如:Controllers \ DataAnalysis \ DataRetrieve

现在我想映射路由,以便当用户只在URL中键入视图的名称时,它会自动将url映射到相应的控制器

IE:localhost:1234 \ DataAnalysis \ DataRetrieve

应映射到

查看\ DataAnalysis \ DataRetrieve \ Index.cshtml

同样,任何包含操作的url请求都应检索相应的视图

IE:localhost:1234 \ DataAnalysis \ DataRetrieve \ TestAction

应映射到

查看\ DataAnalysis \ DataRetrieve \ TestAction.cshtml

目前,我们正在使用默认路由

public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional } ); } 

这意味着如果我键入上面显示的URL,它将忽略该类别并且无法返回视图。

有没有办法自定义路由以获得上述行为?

– 编辑

为了根据评论澄清我的问题,这里是我的解决方案资源管理器的屏幕截图

在此处输入图像描述

现在,如果我调用localhost:12346 / DataAnalysis / DataRetrieve,这应该将我带到索引。 路由这不是问题,因为我可以做这样的事情:

  routes.MapRoute( name: "ExampleRouting", url: "{category}/{controller}/{action}" ); 

但这是问题所在。 我还想组织我的文件结构:

在此处输入图像描述

默认情况下,当我尝试检索dataretrieve的索引时,它会在Views \ DataRetrieve \ Index而不是Views \ DataAnalysis \ DataRetrieve \ Index下查找。

我该如何改变这种行为?

EDIT2 ————————

根据答案,我添加了一个自定义视图引擎,在Application_Start中注册,更新了我的路由。 还有一个相同的问题。

Global.asax中

 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); ViewEngines.Engines.Add(new SPCViewEngine()); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); } } 

RouteConfig.cs

  public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{category}/{action}/{id}", defaults: new { controller = "Login", action = "Index", category = "Login", id = UrlParameter.Optional } ); } 

SPCViewEngine(自定义视图引擎)

 public class SPCViewEngine : RazorViewEngine { public SPCViewEngine() : base() { ViewLocationFormats = new[] { "~/Views/{1}/%1/{0}.cshtml", "~/Views/{1}/%1/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" }; PartialViewLocationFormats = new[] { "~/Views/%1/{1}/{0}.cshtml", "~/Views/%1/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" }; } protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { var categoryName = controllerContext.RouteData.Values["category"].ToString(); return base.CreatePartialView(controllerContext, partialPath.Replace("%1", categoryName)); } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var categoryName = controllerContext.RouteData.Values["category"].ToString(); return base.CreateView(controllerContext, viewPath.Replace("%1", categoryName), masterPath); } protected override bool FileExists(ControllerContext controllerContext, string virtualPath) { var categoryName = controllerContext.RouteData.Values["category"].ToString(); return base.FileExists(controllerContext, virtualPath.Replace("%1", categoryName)); } } 

如果我正确理解了您的问题,您可以创建自己的视图引擎,该引擎在运行时解析视图位置并插入您的应用程序。

创建自己的自定义视图引擎。

  public class MyViewEngine : RazorViewEngine { public MyViewEngine() : base() { ViewLocationFormats = new[] { "~/Views/{1}/%1/{0}.cshtml", "~/Views/{1}/%1/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" }; PartialViewLocationFormats = new[] { "~/Views/%1/{1}/{0}.cshtml", "~/Views/%1/{1}/{0}.vbhtml", "~/Views/Shared/{0}.cshtml", "~/Views/Shared/{0}.vbhtml" }; } protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) { var catagoryName = controllerContext.RouteData.Values["category"].ToString(); return base.CreatePartialView(controllerContext, partialPath.Replace("%1", catagoryName)); } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var catagoryName = controllerContext.RouteData.Values["category"].ToString(); return base.CreateView(controllerContext, viewPath.Replace("%1", catagoryName),masterPath); } protected override bool FileExists(ControllerContext controllerContext, string virtualPath) { var catagoryName = controllerContext.RouteData.Values["category"].ToString(); return base.FileExists(controllerContext, virtualPath.Replace("%1", catagoryName)); } } 

并在这里注册

 protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); //Register your View Engine Here. ViewEngines.Engines.Add(new MyViewEngine()); } 

更新路由配置,默认应该是

  routes.MapRoute( name: "Default", url: "{controller}/{category}/{action}/{id}", defaults: new { controller = "Home", action = "Index", category = "DefaultCategoryName", id = UrlParameter.Optional } );