VirtualPathProvider in MVC 5

瘦欲@ 提交于 2019-11-30 18:43:21

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!