VirtualPathProvider in MVC 5

前端 未结 1 1669
你的背包
你的背包 2021-01-04 13:33

I can\'t seem to get a custom VirtualPathProvider working in asp.net MVC 5.

The FileExists method returns true but then the GetFile method isn\'t called. I believe t

相关标签:
1条回答
  • 2021-01-04 14:03

    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.

    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" }
    );
    

    I register my custom VirtualPathProvider before I register my routes, in globals.asax.cs.

    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
    

    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);
            }
    

    The custom virtual file will be made and returned to the browser in the GetFile method.

    Finally, a custom view engine can be created to give different virtual view paths that are sent to VirtualPathProvider.

    Hope this helps.

    0 讨论(0)
提交回复
热议问题