mvc4 razor中是否有VirtualPathProvider工作样本?

时间:2013-03-11 06:12:12

标签: virtualpathprovider

我已经阅读了几十个相关的线程,并从样本中提取了我非常简单的虚拟提供程序。

它不呈现虚拟文件流。只显示计划文字。

这是输出。

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

1 个答案:

答案 0 :(得分:2)

我可以看到问题有点旧,但我刚遇到同样的错误。我相信问题是测试网址。我没有时间进行全面调查,但我认为除非提供的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);
}