具体地说,控制器类名称必须有Controller后缀吗?如果您想要更改项目中的文件夹结构,是否可以在不破坏内容的情况下进行更改?
是否还有其他可以覆盖的约定,以及如何覆盖?
发布于 2010-01-23 15:46:20
如果您知道框架是如何操作的,那么大多数约定都是可延展的。让我们来处理两个最大的约定:
}/{
默认情况下,您创建的每个路由都与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()));现在,当路由匹配时,它会调用您自己的逻辑,您可以随心所欲地执行。顺便说一下,用于查找带有“控制器”后缀的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 (或use an entirely different view engine)并将其放入您的global.asax中:
ViewEngines.Engines.Add(new MyViewEngine());MVC框架令人惊叹的一点是它的灵活性。你几乎可以用你自己的逻辑替换它的任何部分-所有的代码都可以看到他们做了什么。
https://stackoverflow.com/questions/2122459
复制相似问题