2014-01-24 124 views
3

我们的解决方案层次结构如下所示:ASP.NET MVC自定义视图路由

控制器\目录\查看

例: 控制器\ DataAnalysis \ DataRetrieve

现在我想映射这样当用户只需在url中输入视图的名称时,它就会自动将该url映射到相应的控制器上。

IE:localhost:1234 \ DataAnalysis \ DataRetrieve

应该映射到

查看\ DataAnalysis \ DataRetrieve \ Index.cshtml

同样,任何URL请求,包括动作要获取相应的视图

IE:本地主机: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这意味着,它忽略了类别和未能归还视图。

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

- 编辑

要根据意见澄清我的问题,这是我的解决方案资源管理器

enter image description here

截图现在,如果我叫本地主机:12346/DataAnalysis/DataRetrieve,这应该带我去索引。路由这不是一个问题,因为我可以这样做:

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

但这是问题所在。我也想安排我的文件结构是这样的:

enter image description here

默认情况下,当我尝试检索dataretrieve的指数,它看起来在查看\ DataRetrieve \指数不查看\ DataAnalysis \ DataRetrieve \指数。

我该如何改变这种行为?

EDIT2 ------------------------

基于答案,我添加了一个自定义视图引擎,其注册在Application_Start,更新了我的路由。仍然有一个相同的问题。

全局。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)); 
    } 
} 
+0

所以DataAnalysis是你的控制器,或者是你的项目的名称,DataRetrieve是你的控制器? – krillgar

+0

我很困惑,或者你是。路由与视图无关。仅将路由路由至控制器操作。 –

+1

我会建议使用区域来组织你的应用程序。请参阅http://msdn.microsoft.com/en-us/library/ee671793(v=vs.100).aspx。 – Onots

回答

12

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

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

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 } 
     ); 
+0

你的答案似乎是正确的做法,但由于某种原因,它仍然无法正常工作。请求localhost/DataAnalysis/DataRetrieve结果为404,并且当我将调试点放在它们上时,自定义viewengine中的所有重写方法都不会被调用。但是,当我尝试localhost:12346/DataRetrieve/TestAction没有在前面的类别,它的工作原理。编辑:没关系,后者也不起作用。 – l46kok

+0

您是否在应用程序启动时注册了视图引擎还更新了路由配置?我在我的本地主机上试过这个,它也适用于我的调试点应该打在每个请求。 – ssilas777

+0

是的。我会暂时编辑我的问题和更新的内容。 – l46kok