首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MVC 5中的VirtualPathProvider

MVC 5中的VirtualPathProvider
EN

Stack Overflow用户
提问于 2014-06-16 05:31:14
回答 1查看 8.1K关注 0票数 11

我似乎无法让自定义VirtualPathProvider在asp.net MVC 5中工作。

FileExists方法返回true,但不调用GetFile方法。我认为这是因为IIS接管了请求,而不让.NET处理它。

我尝试过设置RAMMFAR并创建一个自定义处理程序,就像这个解决方案中的https://stackoverflow.com/a/12151501/801189一样,但仍然没有成功。我得到一个错误404。

我的自定义提供者:

代码语言:javascript
复制
public class DbPathProvider : VirtualPathProvider
{
    public DbPathProvider() : base()
    {

    }

    private static bool IsContentPath(string virtualPath)
    {
        var checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
        return checkPath.StartsWith("~/CMS/", StringComparison.InvariantCultureIgnoreCase);
    }

    public override bool FileExists(string virtualPath)
    {
        return IsContentPath(virtualPath) || base.FileExists(virtualPath);
    }

    public override VirtualFile GetFile(string virtualPath)
    {
        return IsContentPath(virtualPath) ? new DbVirtualFile(virtualPath) : base.GetFile(virtualPath);
    }

    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
    {
        return null;

    }

    public override String GetFileHash(String virtualPath, IEnumerable virtualPathDependencies)
    {
        return Guid.NewGuid().ToString();
    }
}

我的自定义虚拟文件:

代码语言:javascript
复制
public class DbVirtualFile : VirtualFile
{
    public DbVirtualFile(string path): base(path)
    {

    }

    public override System.IO.Stream Open()
    {
        string testPage = "This is a test!";
        return new System.IO.MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(testPage));
    }
}

我尝试过使用web.config处理程序,但没有成功。它目前给出了错误500:

代码语言:javascript
复制
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
  <remove name="FormsAuthenticationModule" />
</modules>

<handlers>
  <add name="ApiURIs-ISAPI-Integrated-4.0"
 path="/CMS/*"
 verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
 type="System.Web.Handlers.TransferRequestHandler"
 preCondition="runtimeVersionv4.0" />
</handlers>

如果我尝试导航到site.com/CMS/Home/Index,则调用FileExists方法,但奇怪的是,virtualPath参数只接收~/CMS/Home。

添加断点后,对于urlsite.com/CMS/Home/Index,FileExists方法似乎一直被反复调用。这可能会导致无限递归,从而导致内部服务器错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-19 05:34:43

这实际上与IIS无关,而且实际上与事件的顺序混淆。我似乎不明白路由操作方法必须返回视图,而VirtualPathProvider将尝试解析该视图,而不是直接到VirtualPathProvider。

我创建了一个名为ContentPagesController的简单控制器,其中包含一个GetPage操作:

代码语言:javascript
复制
public class ContentPagesController : Controller
    {
        [HttpGet]
        public ActionResult GetPage(string pageName)
        {
            return View(pageName);
        }
    }

然后,我设置了服务虚拟页面的路径:

代码语言:javascript
复制
routes.MapRoute(
 name: "ContentPageRoute",
 url: "CMS/{*pageName}",
 defaults: new { controller = "ContentPages", action = "GetPage" },
 constraints: new { controller = "ContentPages", action = "GetPage" }
);

在注册路线之前,我先在VirtualPathProvider注册,然后在globals.asax.cs中注册。

现在假设我的数据库中有一个相对url /CMS/Home/AboutUs的页面。pageName参数将有值Home/AboutUs,返回视图()调用将指示VirtualPathProvider查找文件~/VirtualPathProvider/ContentPages/Home/AboutUs.cshtml的变体。

它将寻求的几个变体包括:

代码语言:javascript
复制
~/Views/ContentPages/Home/AboutUs.aspx
~/Views/ContentPages/Home/AboutUs.ascx
~/Views/ContentPages/Home/AboutUs.vbhtml

现在您需要做的就是检查传递给GetFiles方法的GetFiles,使用数据库查找或类似的方法。以下是一个简单的方法:

代码语言:javascript
复制
private bool IsCMSPath(string virtualPath)
        {
           return virtualPath == "/Views/ContentPages/Home/AboutUs.cshtml" || 
                virtualPath == "~/Views/ContentPages/Home/AboutUs.cshtml"; 
        }

        public override bool FileExists(string virtualPath)
        {
            return IsCMSPath(virtualPath) || base.FileExists(virtualPath);
        }

        public override VirtualFile GetFile(string virtualPath)
        {
            if (IsCMSPath(virtualPath))
            {
                return new DbVirtualFile(virtualPath);
            }

            return base.GetFile(virtualPath);
        }

将创建自定义虚拟文件并在GetFile方法中将其返回给浏览器。

最后,可以创建一个自定义视图引擎来提供发送到VirtualPathProvider的不同虚拟视图路径。

希望这能有所帮助。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24237123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档