2014-01-24 172 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