2010-06-09 28 views
9

我們正在構建一個網站,其代碼非常少,大多數情況下只是一堆靜態頁面。我知道隨着時間的推移,這將會改變,我們希望交換更多的動態信息,所以我決定繼續使用ASP.NET MVC2和Spark視圖引擎構建一個Web應用程序。將會有幾個控制器需要做實際的工作(如在/產品領域),但其中大部分將是靜態的。無需編寫控制器即可實現簡單的ASP.NET MVC視圖

我希望我的設計師能夠構建和修改網站,而不必在每次決定添加或移動頁面時都要求我編寫新的控制器或路由。所以如果他想添加一個「http://example.com/News」頁面,他可以在Views下創建一個「News」文件夾,並在其中放置一個index.spark頁面。然後,如果他決定他想要一個/ News/Community頁面,他可以在該文件夾中放置一個community.spark文件並使其工作。

我可以通過讓我的控制器重寫HandleUnknownAction來實現沒有特定操作的視圖,但是我仍然需要爲每個這些文件夾創建一個控制器。每次他們決定向網站添加一個區域時,必須添加一個空控制器並重新編譯似乎很愚蠢。

有什麼辦法可以讓這個更容易,所以我只需要編寫一個控制器並重新編譯,如果有實際的邏輯要完成的話?某種「主」控制器,可處理任何未定義特定控制器的請求?

+0

+1提醒HandleUnknownAction。這幫助了我。 – 2014-02-01 23:00:32

回答

6

你將不得不爲實際的控制器/操作編寫一個路由映射,並確保默認索引作爲一個動作,並且id是「catchall」,這就行了!

public class MvcApplication : System.Web.HttpApplication { 
     public static void RegisterRoutes(RouteCollection routes) { 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

      routes.MapRoute(
       "Default", // Route name 
       "{controller}/{action}/{id}", // URL with parameters 
       new { controller = "Home", action = "Index", id = "catchall" } // Parameter defaults 
      ); 

     } 

     protected void Application_Start() { 
      AreaRegistration.RegisterAllAreas(); 

      RegisterRoutes(RouteTable.Routes); 

      ControllerBuilder.Current.SetControllerFactory(new CatchallControllerFactory()); 

     } 
    } 

public class CatchallController : Controller 
    { 

     public string PageName { get; set; } 

     // 
     // GET: /Catchall/ 

     public ActionResult Index() 
     { 
      return View(PageName); 
     } 

    } 

public class CatchallControllerFactory : IControllerFactory { 
     #region IControllerFactory Members 

     public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) { 

      if (requestContext.RouteData.Values["controller"].ToString() == "catchall") { 
       DefaultControllerFactory factory = new DefaultControllerFactory(); 
       return factory.CreateController(requestContext, controllerName); 
      } 
      else { 
       CatchallController controller = new CatchallController(); 
       controller.PageName = requestContext.RouteData.Values["action"].ToString(); 
       return controller; 
      } 

     } 

     public void ReleaseController(IController controller) { 
      if (controller is IDisposable) 
       ((IDisposable)controller).Dispose(); 
     } 

     #endregion 
    } 
+0

這工作完美,謝謝! – 2010-06-11 20:54:39

1

難道你不能爲所有的靜態頁面創建一個單獨的控制器,並使用MVC路由將所有事情(除了實際工作的控制器之外)重定向到它,並且包含路徑參數嗎?然後在該控制器中,您可以根據路由發送給它的文件夾/路徑參數顯示正確的視圖。

Allthough我不知道火花視圖引擎處理的東西,它是否必須編譯視圖?我真的不確定。

0

我想你可以創建自己的控制器工廠,將始終實例相同的控制器類。

1

反思保羅的答案。我沒有使用任何特殊的視圖引擎,但這裏是我做的:

1)創建一個PublicController.cs。

// GET: /Public/ 
[AllowAnonymous] 
public ActionResult Index(string name = "") 
{ 
    ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, name, null); 
    // check if view name requested is not found 
    if (result == null || result.View == null) 
    { 
     return new HttpNotFoundResult(); 
    } 
    // otherwise just return the view 
    return View(name); 
} 

2)然後在創建視圖文件夾中的公共目錄,並把所有的你的意見那裏,你想成爲公衆。我個人需要這樣做,因爲我從來不知道客戶是否想要創建更多頁面而無需重新編譯代碼。

3)然後修改RouteConfig.cs以重定向到Public/Index操作。

routes.MapRoute(
    name: "Public", 
    url: "{name}.cshtml", // your name will be the name of the view in the Public folder 
    defaults: new { controller = "Public", action = "Index" } 
); 

4)然後,只需從你的觀點像這樣引用它:

<a href="@Url.RouteUrl("Public", new { name = "YourPublicPage" })">YourPublicPage</a> <!-- and this will point to Public/YourPublicPage.cshtml because of the routing we set up in step 3 --> 

不知道這是比任何使用工廠模式更好,但在我看來,最容易實現的,並理解。

3

link可能的幫助,

如果您在查看CSHTML \ Public目錄,它會出現在網站上有相同的名稱。我還添加了404頁面。

[HandleError] 
    public class PublicController : Controller 
    { 
     protected override void HandleUnknownAction(string actionName) 
     { 
      try 
      { 
       this.View(actionName).ExecuteResult(this.ControllerContext); 
      } 
      catch 
      { 
       this.View("404").ExecuteResult(this.ControllerContext); 
      } 
     } 
    } 
相關問題