中的VirtualPathProvider 5 MVC [英] VirtualPathProvider in MVC 5
问题描述
我似乎无法得到一个自定义的VirtualPathProvider在asp.net MVC的5个工作。
I can't seem to get a custom VirtualPathProvider working in asp.net MVC 5.
该FILEEXISTS方法返回true,但随后的GetFile方法没有被调用。
我相信这是因为IIS接管该请求,并没有让.NET处理。
The FileExists method returns true but then the GetFile method isn't called. I believe this is because IIS takes over the request and does not let .NET handle it.
我已经尝试设置RAMMFAR并创建一个自定义处理程序,在这种解决方案 http://stackoverflow.com/a/12151501/ 801189 但仍没有运气。我得到一个404错误。
I have tried setting RAMMFAR and creating a custom handler, as in this solution http://stackoverflow.com/a/12151501/801189 but still no luck. I get a error 404.
我的自定义提供者:
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();
}
}
我的自定义虚拟文件:
My Custom Virtual File:
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:
web.config handler I have tried to use, without success. It currently gives error 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 /主页。
If I try to navigate to site.com/CMS/Home/Index, the FileExists method is called but strangely, the virtualPath parameter recieves only ~/CMS/Home.
添加断点,似乎为URL site.com/CMS/Home/Index,该方法FILEEXISTS得到不断重复调用。这可能会导致一个无限递归,给内部服务器错误。
Adding breakpoints, it seems that for the url site.com/CMS/Home/Index, the FileExists method keeps getting repeatedly called. This may be causing an infinite recursion, giving the internal server error.
推荐答案
这实际上无关的IIS,并在事件的顺序上的事实混淆。看来我不明白,一个路由操作方法必须返回一个观点,即的VirtualPathProvider将尽力解决,而不是直接去的VirtualPathProvider。
It was actually nothing to do with IIS, and in fact confusion on the order of events. It seems I didn't understand that a routed action method must return a view, that the VirtualPathProvider will try to resolve, rather than going to the VirtualPathProvider directly.
我创建了一个名为ContentPagesController用一个动作GETPAGE简单的控制器:
I create a simple controller called ContentPagesController with a single GetPage action:
public class ContentPagesController : Controller
{
[HttpGet]
public ActionResult GetPage(string pageName)
{
return View(pageName);
}
}
然后我建立了我的路线,以满足虚拟页面:
I then set up my route to serve virtual pages:
routes.MapRoute(
name: "ContentPageRoute",
url: "CMS/{*pageName}",
defaults: new { controller = "ContentPages", action = "GetPage" },
constraints: new { controller = "ContentPages", action = "GetPage" }
);
我登记我的自定义的VirtualPathProvider之前注册我的路线,在globals.asax.cs。
I register my custom VirtualPathProvider before I register my routes, in globals.asax.cs.
现在假设我在与相对URL / CMS /主页/关于我们的数据库有一个页面。页面名参数将值主页/公司简介和返回视图()调用将指示的VirtualPathProvider查找文件的变化〜/查看/内容网页/主页/ AboutUs.cshtml。
Now suppose I have a page in my database with the relative url /CMS/Home/AboutUs. The pageName parameter will have value Home/AboutUs and the return View() call will instruct the VirtualPathProvider to look for variations of the file ~/Views/ContentPages/Home/AboutUs.cshtml.
有几个变化将是寻找包括:
A few of the variations it will be look for include:
~/Views/ContentPages/Home/AboutUs.aspx
~/Views/ContentPages/Home/AboutUs.ascx
~/Views/ContentPages/Home/AboutUs.vbhtml
你现在需要做的是检查传递给GetFiles方法,使用数据库查询或类似的virtualPath。这里有一个简单的方法:
All you now need to do is check the virtualPath that is passed to the GetFiles method, using a database lookup or similar. Here is a simple way:
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方法的浏览器。
The custom virtual file will be made and returned to the browser in the GetFile method.
最后,一个自定义视图引擎可以创建给发送到不同的VirtualPathProvider虚拟视图的路径。
Finally, a custom view engine can be created to give different virtual view paths that are sent to VirtualPathProvider.
希望这有助于。
这篇关于中的VirtualPathProvider 5 MVC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!