asp.mvc 404自定义ControllerFactory和DBProvider出错

时间:2011-01-03 19:31:06

标签: asp.net-mvc virtualpathprovider

我目前正在处理的应用程序是一个MVC3应用程序,它结合了标准视图实例化,并在物理视图不存在时从数据库中检索视图。我在实现自定义controllerfactory和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方法,并适当地返回我的genericcontroller类型。 3)再次调用FileExists方法,这次返回true。 4)调用所有控制器工厂方法,包括ControllerRelease方法。

然而,GenericController实际上从未被调用过。 IIS返回404异常。

我需要在MVC控制器实例化管道中的其他地方捕获MVC请求吗?我有更好的方法来完成我想要完成的任务吗?

感谢。

0 个答案:

没有答案