【问题标题】:Is there any VirtualPathProvider working sample in mvc4 razor?mvc4 razor 中是否有任何 VirtualPathProvider 工作示例?
【发布时间】:2013-09-07 02:05:43
【问题描述】:

我已经阅读了几十个相关主题,并从示例中创建了我非常简单的虚拟提供程序。

但是它不会渲染虚拟文件流。只显示计划文本。

这是输出。

@inherits System.Web.Mvc.WebViewPage 
@{ViewBag.Title = "Hellow World !";}
<h2>Hellow World !</h2>

有关于这个的相关线程,但他们没有说他们是如何解决它或解决方案不起作用的。我找不到我做错了什么。

还有更多...

怎么了?

这是我的测试代码。 (Global.asax,这就是我所做的全部更改。)

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(
            new MyProvider());

        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();
    }
}

public class MyProvider : VirtualPathProvider
{
    public override bool FileExists(string virtualPath)
    {
        if (Previous.FileExists(virtualPath))
            return true;
        else
            //  ~/Infra is the test url
            return virtualPath.StartsWith("/Infra") || virtualPath.StartsWith("~/Infra");
    }

    public override VirtualFile GetFile(string virtualPath)
    {
        if (Previous.FileExists(virtualPath))
            return base.GetFile(virtualPath);
        else
            return new MyVirtualFile(virtualPath);
    }

    public class MyVirtualFile : VirtualFile
    {
        public MyVirtualFile(string virtualPath) : base(virtualPath) { }

        public override Stream Open()
        {
            //Loading stream from seperate dll shows just plain text
            //System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(
            //  System.IO.Path.Combine(HttpRuntime.BinDirectory, "Infra.dll"));
            //return assembly.GetManifestResourceStream("Infra.Views.Home.Index.cshtml");

            //Changed to string but also it shows plain text.
            return new System.IO.MemoryStream(System.Text.ASCIIEncoding.UTF8.GetBytes(
                "@inherits System.Web.Mvc.WebViewPage \r\n  <h2>Hellow World !</h2>"));
        }
    }
}

【问题讨论】:

    标签: virtualpathprovider


    【解决方案1】:

    我可以看到这个问题有点老了,但我刚刚遇到了同样的错误。我相信问题出在测试 URL 上。我没有时间进行全面调查,但我认为除非提供的 URL 采用预期格式(ASP.NET MVC 视图引擎基于约定),否则它可能不会使用 razor 作为视图引擎;我不确定这是否是原因,但有一些使用您正在使用的“Infra”字符串的示例:

    家庭控制器中的新 MVC 4 项目:

    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
    
        dynamic x = new ExpandoObject();
    
        return View("Infra-test.cshtml", x);
    }
    

    这调用:

    private bool IsPathVirtual(string virtualPath)
    

    virtualPath 设置为'/Views/Home/Infra-test.cshtml.aspx'。它在末尾添加了一个 aspx 扩展名,这让我相信它没有使用 razor 来编译视图。对虚拟路径提供程序进行小修改后,以下链接将起作用:

    public override bool FileExists(string virtualPath)
    {
        if (Previous.FileExists(virtualPath))
            return true;
        else
            //  prevent view start compilation errors
            return virtualPath.StartsWith("/Infra") && !virtualPath.Contains("_ViewStart");
    }
    

    有效的网址:

    return View("/Infra/test.cshtml", x);
    return View("/Infra/one/test.cshtml", x);
    return View("/Infra/one/two/test.cshtml", x);
    

    这些不起作用:

    return View("/Infra", x);
    return View("/Infra/test", x);
    

    为了使示例工作,您还需要实现GetCacheDependency;否则,当它在磁盘上找不到虚拟路径的文件时会抛出异常,下面是一个简单的例子。阅读文档以正确实施。

    private bool IsVirtualPath(string virtualPath)
    {
        return virtualPath.StartsWith("/Infra") && !virtualPath.Contains("_ViewStart");
    }
    
    public override CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
    {
        if (IsVirtualPath(virtualPath))
            return null;
    
        return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
    }
    

    【讨论】:

    • 记得在每次更改或调整后重新启动 IIS Express,因为它会缓存位置、文件和明显的结果,即使我没有设置太多,等等。我正在敲我的脑袋,然后在重新启动 IIS 后意识到,只要它有“.cshtml”并确保我也覆盖了目录位,它就可以在没有现有文件名的情况下工作,而不是嵌入式资源。谢谢你帮助我部分地创建了我的解决方案。呸!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    相关资源
    最近更新 更多