简单的ASP.NET MVC视图,无需编写控制器

Jak*_*son 10 spark-view-engine asp.net-mvc-2

我们正在构建一个代码非常少的网站,它主要是提供一堆静态页面.我知道随着时间的推移会发生变化,我们会想要交换更多动态信息,因此我决定继续使用ASP.NET MVC2和Spark视图引擎构建Web应用程序.将有一些控制器必须进行实际工作(如/ products区域),但大多数都是静态的.

我希望我的设计师能够构建和修改网站,而无需每次他们决定添加或移动页面时都要求我编写新的控制器或路由.因此,如果他想添加一个" http://example.com/News "页面,他只需在Views下创建一个"News"文件夹,并在其中放置一个index.spark页面.然后,如果他决定要一个/新闻/社区页面,他可以删除该文件夹中的community.spark文件并让它工作.

通过使控制器覆盖HandleUnknownAction,我可以在没有特定操作的情况下获得视图,但我仍然需要为每个文件夹创建一个控制器.每次他们决定向网站添加区域时,必须添加一个空控制器并重新编译似乎很愚蠢.

有没有办法让这更容易,所以我只需要编写一个控制器并重新编译,如果有实际的逻辑要做?某种"主"控制器将处理没有定义特定控制器的任何请求?

Tac*_*667 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
    }
Run Code Online (Sandbox Code Playgroud)