Asp.net-Mvc-2

無需編寫控制器的簡單 ASP.NET MVC 視圖

  • December 31, 2016

我們正在建構一個程式碼非常少的網站,它主要只是提供一堆靜態頁面。我知道隨著時間的推移會發生變化,我們會想要交換更多的動態資訊,所以我決定繼續使用 ASP.NET MVC2 和 Spark 視圖引擎建構一個 Web 應用程序。將有幾個控制器必須進行實際工作(例如在 /products 區域中),但其中大部分將是靜態的。

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

我可以通過讓我的控制器覆蓋 HandleUnknownAction 來獲得沒有特定操作的視圖,但我仍然必須為每個文件夾創建一個控制器。每次他們決定向站點添加區域時都必須添加一個空控制器並重新編譯,這似乎很愚蠢。

有沒有辦法讓這更容易,所以我只需要編寫一個控制器並在需要完成實際邏輯時重新編譯?某種“主”控制器將處理沒有定義特定控制器的任何請求?

您必須為實際的控制器/動作編寫路由映射,並確保預設將索引作為動作並且 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
   }

引用自:https://stackoverflow.com/questions/3008970