3

具体来说,控制器类名称是否必须具有Controller后缀,如果您愿意,您可以更改项目中的文件夹结构,而不会破坏任何东西吗?

是否有其他可以覆盖的约定,以及如何覆盖?

4

1 回答 1

3

只要您了解框架的运作方式,大多数约定都是可延展的。让我们解决两个最大的约定:

  1. 用于从路由实例化控制器的“{controller}/{action}/”魔术关键字

  2. 框架首先在控制器目录中搜索视图的方式,然后在共享目录中。

MvcRouteHandler默认情况下,您创建的每个路由都与一个对象的实例相关联。当路由匹配时,调用该处理程序来处理传入请求。下面是 MvcHandler 的 ProcessRequest 的样子:

protected internal virtual void ProcessRequest(HttpContextBase httpContext)
{
    this.AddVersionHeader(httpContext);
    string requiredString = this.RequestContext.RouteData.GetRequiredString("controller");
    IControllerFactory controllerFactory = this.ControllerBuilder.GetControllerFactory();
    IController controller = controllerFactory.CreateController(this.RequestContext, requiredString);
    if (controller == null)
    {
        throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, MvcResources.ControllerBuilder_FactoryReturnedNull, new object[] { controllerFactory.GetType(), requiredString }));
    }
    try
    {
        controller.Execute(this.RequestContext);
    }
    finally
    {
        controllerFactory.ReleaseController(controller);
    }
}

注意硬编码的字符串“controller”。好吧,如果您想编写自己的控制器查找逻辑,您可以将这个处理程序替换为您想要的任何路由。只需做这样的事情(无耻的博客插件)

routes.Add("ImagesRoute",
                 new Route("graphics/{filename}", new ImageRouteHandler()));

现在当路由匹配时,它会调用你自己的逻辑,你可以为所欲为。顺便说一句,用于查找带有“Controller”后缀的 XXXXController 类的反射是DefaultControllerFactory对象的一部分,在上面的处理程序中调用,并且该工厂是可替换的。

因此,控制器选择是一种可以覆盖的约定。当您return View()从任何控制器方法执行“”时,它会如何查找视图?那么这是WebFormViewEngine框架的默认视图引擎的构造函数:

public WebFormViewEngine()
{
    base.MasterLocationFormats = new string[] { "~/Views/{1}/{0}.master", "~/Views/Shared/{0}.master" };
    base.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.aspx", "~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.aspx", "~/Views/Shared/{0}.ascx" };
    base.PartialViewLocationFormats = base.ViewLocationFormats;
}

因此,如果您不喜欢查看控制器目录然后共享的约定 - 您可以轻松扩展WebFormViewEngine(或使用完全不同的视图引擎)并将其放入 global.asax 中:

ViewEngines.Engines.Add(new MyViewEngine());

MVC 框架令人惊奇的事情之一是它的真正灵活性。你可以用你自己的逻辑替换它的几乎任何部分——所有代码都可以用来查看他们做了什么。

于 2010-01-23T07:46:20.053 回答