Asp.net mvc MVC5中的VirtualPathProvider
我似乎无法在asp.net MVC 5中使用自定义VirtualPathProvider FileExists方法返回true,但不调用GetFile方法。 我相信这是因为IIS接管了请求,而不让.NET处理它 我尝试过设置RAMMFAR并创建一个自定义处理程序,就像在这个解决方案中一样,但仍然没有成功。我得到一个错误404 我的自定义提供程序:Asp.net mvc MVC5中的VirtualPathProvider,asp.net-mvc,iis,asp.net-mvc-routing,asp.net-mvc-5,Asp.net Mvc,Iis,Asp.net Mvc Routing,Asp.net Mvc 5,我似乎无法在asp.net MVC 5中使用自定义VirtualPathProvider FileExists方法返回true,但不调用GetFile方法。 我相信这是因为IIS接管了请求,而不让.NET处理它 我尝试过设置RAMMFAR并创建一个自定义处理程序,就像在这个解决方案中一样,但仍然没有成功。我得到一个错误404 我的自定义提供程序: public class DbPathProvider : VirtualPathProvider { public DbPathProvid
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();
}
}
我的自定义虚拟文件:
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:
<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
添加断点后,似乎对于url site.com/CMS/Home/Index,FileExists方法不断被重复调用。这可能会导致无限递归,导致内部服务器错误。这实际上与IIS无关,事实上,事件顺序混乱。我似乎不明白路由操作方法必须返回一个视图,VirtualPathProvider将尝试解析该视图,而不是直接转到VirtualPathProvider 我创建了一个名为ContentPagesController的简单控制器,它具有一个GetPage操作:
public class ContentPagesController : Controller
{
[HttpGet]
public ActionResult GetPage(string pageName)
{
return View(pageName);
}
}
然后,我设置了服务虚拟页面的路径:
routes.MapRoute(
name: "ContentPageRoute",
url: "CMS/{*pageName}",
defaults: new { controller = "ContentPages", action = "GetPage" },
constraints: new { controller = "ContentPages", action = "GetPage" }
);
在globals.asax.cs中注册路由之前,我先注册自定义VirtualPathProvider
现在假设我的数据库中有一个相对url/CMS/Home/AboutUs的页面。pageName参数的值为Home/AboutUs,return View()调用将指示VirtualPathProvider查找文件~/Views/ContentPages/Home/AboutUs.cshtml的变体
它将寻找的一些变体包括:
~/Views/ContentPages/Home/AboutUs.aspx
~/Views/ContentPages/Home/AboutUs.ascx
~/Views/ContentPages/Home/AboutUs.vbhtml
现在需要做的就是使用数据库查找或类似方法检查传递给GetFiles方法的virtualPath。这里有一个简单的方法:
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的不同虚拟视图路径
希望这有帮助。您的回答很有帮助。我的代码正常工作,但是视图在“System.IO.Stream Open()”之后无法呈现。你遇到过同样的问题吗?不,我不相信我遇到过。您看到了什么错误?只是在Open()之后呈现了一个空白html。Open()成功地从DBI获取视图。我建议在Open方法中只返回一个测试字符串,就像我在最初的问题中所做的那样,看看它是否正常工作。如果是的话,我相信问题在于你的数据库条目。@DavidJamesBall谢谢!!在找到你的帖子之前,我都快发疯了。我在/PathToAction.cshtml的/Controller/Action插入部分执行了文件存在性检查。。。显然,这是行不通的。