Asp.net mvc 2 不编写控制器的简单ASP.NET MVC视图
我们正在建立一个网站,它将有非常少的代码,它将主要是一堆静态页面提供。我知道随着时间的推移,情况会发生变化,我们希望交换更多的动态信息,因此我决定继续使用ASP.NET MVC2和Spark view引擎构建一个web应用程序。将有两个控制器必须执行实际工作(如在/products区域),但大多数控制器都是静态的 我希望我的设计师能够构建和修改网站,而不必在每次他们决定添加或移动页面时要求我编写新的控制器或路由。因此,如果他想添加一个“”页面,他可以在“视图”下创建一个“新闻”文件夹,并在其中放置一个index.spark页面。然后,如果他决定要一个/News/Community页面,他可以将Community.spark文件放到该文件夹中,并让它工作 通过使控制器覆盖HandleUnknownAction,我可以在没有特定操作的情况下拥有视图,但我仍然必须为每个文件夹创建一个控制器。每次他们决定向站点添加一个区域时,都必须添加一个空的控制器并重新编译,这似乎很愚蠢Asp.net mvc 2 不编写控制器的简单ASP.NET MVC视图,asp.net-mvc-2,spark-view-engine,Asp.net Mvc 2,Spark View Engine,我们正在建立一个网站,它将有非常少的代码,它将主要是一堆静态页面提供。我知道随着时间的推移,情况会发生变化,我们希望交换更多的动态信息,因此我决定继续使用ASP.NET MVC2和Spark view引擎构建一个web应用程序。将有两个控制器必须执行实际工作(如在/products区域),但大多数控制器都是静态的 我希望我的设计师能够构建和修改网站,而不必在每次他们决定添加或移动页面时要求我编写新的控制器或路由。因此,如果他想添加一个“”页面,他可以在“视图”下创建一个“新闻”文件夹,并在其中放
有没有办法让这更容易,所以我只需要写一个控制器,并重新编译,如果有实际的逻辑要做?某种类型的“主”控制器,可以处理没有定义特定控制器的任何请求?您不能为所有静态页面创建一个单独的控制器,并使用MVC路由将所有内容(实际工作的控制器除外)重定向到它,并包括路径参数吗?然后,在该控制器中,您可以根据路由发送给它的文件夹/路径参数显示正确的视图
虽然我不知道spark view引擎可以处理事情,但它必须编译视图吗?我真的不确定 您必须为实际的控制器/操作编写一个路由映射,并确保默认的操作具有索引,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
}
我认为您可以创建自己的控制器工厂,它将始终实例化相同的控制器类。反映Paul的答案。我没有使用任何特殊的视图引擎,但我的工作如下: 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) 然后在Views文件夹中创建一个公共目录,并将所有要公开的视图放在那里。我个人需要这样做,因为我不知道客户机是否希望在不重新编译代码的情况下创建更多页面
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 -->
不确定这是否比使用工厂模式更好,但在我看来,这是最容易实现和理解的模式。这可能会有所帮助
如果在View\Public目录中创建cshtml,它将以相同的名称显示在网站上。我还添加了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);
}
}
}
+1用于提及HandleUnknownAction。这对我很有帮助。