Есть ли в бритве mvc4 рабочий образец VirtualPathProvider?
Я прочитал десятки связанных тем и сделал из моего примера очень простой виртуальный поставщик.
Но это не делает виртуальный поток файлов. просто показываю план текста.
Вот выход.
@inherits System.Web.Mvc.WebViewPage
@{ViewBag.Title = "Hellow World !";}
<h2>Hellow World !</h2>
Есть связанные темы об этом, но они не говорят, как они решили это, или решение не работает. Я не могу найти, что я сделал не так.
- VirtualPathProvider не обрабатывает разметку бритвы
- MVC3 Custom VirtualPathProvider не отображает Razor
- Вытащить представление из базы данных, а не из файла
- Как указать маршрут к общим представлениям в MVC3 при использовании Области
- ASP.NET MVC загрузить Razor представление из базы данных
- Как загрузить представления из проекта библиотеки классов?
и еще много всего...
В чем дело?
Вот мой тестовый код. (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 ответ
Я вижу, что вопрос немного устарел, но я только что столкнулся с той же ошибкой. Я считаю, что проблема в тестовом URL. У меня нет времени на полное исследование, но я думаю, что если указанный URL-адрес не находится в ожидаемом формате (механизм представления ASP.NET MVC основан на соглашениях), то он может не использовать бритву в качестве механизма просмотра; Я не уверен, является ли это причиной, но некоторые примеры используют строку "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 в конец, что заставляет меня поверить, что он не использует бритву для компиляции представления. Небольшая модификация провайдера виртуального пути увидит работающие ссылки ниже:
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");
}
URL, которые будут работать:
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);
}