我目前正在开发的应用程序是一个 MVC3 应用程序,它结合了标准视图实例化以及如果物理视图不存在则从数据库中检索视图。在实现自定义控制器工厂和 virtualpathprovider 时,我遇到了 404 错误的问题,我不太确定我可能做错了什么。
我们想要的行为如下:
1)如果请求存在“物理”视图,则直接从文件系统提供它(遵循标准 mvc 行为)。在这种情况下,磁盘上会有标准的控制器/视图。2)如果控制器/视图不存在,则检查必要的信息是否存储在数据库中并从数据库中提供。将调用一个名为 GenericController 的控制器,然后从数据库中获取视图数据。
我创建了一个自定义控制器工厂:
public class ControllerFactory : DefaultControllerFactory, IControllerFactory
{
protected override Type GetControllerType(RequestContext requestContext, string controllerName)
{
// check to see if this controller name can be resolved via DI. If it can, then hand this off to the Default factory.
Type returntype = base.GetControllerType(requestContext, controllerName);
// see if this is a type that is handled via the database. If it is, then send to the generic system controller for handling.
if (returntype == null)
{
// already requested?
if (requestContext.HttpContext.Items.Contains("vc"))
{
returntype = typeof(GenericSystemController);
}
else
{
if (viewcanberetrievedfromdb())
{
// TODO: check to see if the account has access to the module.
returntype = typeof(GenericSystemController);
requestContext.HttpContext.Items["vc"] = viewcontext;
}
}
}
return returntype;
}
以及自定义虚拟路径提供程序:
public class DbPathProvider : VirtualPathProvider
{
public DbPathProvider()
: base()
{
}
public override bool FileExists(string virtualPath)
{
// first see if there is a physical version of the file. If there is, then use that. Otherwise, go to the database.
// database calls are ALWAYS overridden by physical files.
bool physicalFileExists = base.FileExists(virtualPath);
if (!physicalFileExists)
physicalFileExists = HttpContext.Current.Items.Contains("vc");
return physicalFileExists;
}
public override VirtualFile GetFile(string virtualPath)
{
if (base.FileExists(virtualPath))
return base.GetFile(virtualPath);
else
return new DbVirtualFile(virtualPath);
}
如果请求的页面在文件系统中不存在,则应用程序流程似乎可以正常工作:1) 首先调用 virtualpathprovider 中的 FileExists 返回 false,以便 IIS 不会尝试用作静态文件。2) 调用控制器工厂中的 GetControllerType 方法并适当地返回我的通用控制器类型。3) 再次调用 FileExists 方法,这次返回 true。4) 调用所有控制器工厂方法,包括 ControllerRelease 方法。
然而,GenericController 实际上从未被调用过。并且 IIS 返回 404 异常。
在 MVC 控制器实例化管道中是否有其他地方需要捕获 MVC 请求?有没有更好的方法让我完成我想要完成的事情?
谢谢。