Загрузите Razor view из БД, но ViewBag не работает

Я извлекаю разметку вида бритвы из базы данных, как подробно описано в этом вопросе:

ASP.NET MVC загрузить Razor представление из базы данных

Я могу вытащить представление, но это не удается выполнить, потому что ViewBag не распознается.

CS0103: имя ViewBag не существует в текущем контексте

Какие-либо предложения?

Вот источник:

Глобальный:

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(new BearForce.Web.Core.DbPathProvider());
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

мой путь провайдера:

namespace BearForce.Web.Core
{
    public class DbPathProvider : VirtualPathProvider
    {
        public DbPathProvider()
            : base()
        {

        }

        public override bool FileExists(string virtualPath)
        {
            var repo = new Repository();

            var viewPage = repo.GetView(240, virtualPath);

            if (base.FileExists(virtualPath))
            {
                return true;
            }

            if (viewPage != null)
            {
                return true;
            }

            return false;

        }

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

            var repo = new Repository();
            var result = repo.GetView(240, virtualPath);

            var vf = new DbVirtualFile(virtualPath, result.Markup);
            return vf;
        }


    }
}

мой виртуальный файл:

  public class DbVirtualFile : System.Web.Hosting.VirtualFile
    {
        string _fileContents = string.Empty;
        public DbVirtualFile(string path, string fileContents)
            : base(path)
        {
            _fileContents = fileContents;
         }

        public override System.IO.Stream Open()
        {
            return new System.IO.MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(_fileContents));
        }
    }

Мой контроллер:

  public ActionResult Index()
        {
            ViewBag.Title = "aaah!!! Muppets!!! Help!!!!!";

            return View();
        }

Очевидно, это подтверждение концепции, поэтому все имена глупые, а код небрежный, как ад...

2 ответа

Решение

Вы должны убедиться, что возвращаемый вами вид соответствует бритвенному виду. Вот упрощенный рабочий пример:

public class CustomPathProvider : VirtualPathProvider
{
    private class CustomVirtualFile : VirtualFile
    {
        public CustomVirtualFile(string path)
            : base(path)
        { }

        public override Stream Open()
        {
            return new MemoryStream(Encoding.UTF8.GetBytes("Hello @ViewBag.Name"));
        }
    }

    public override bool FileExists(string virtualPath)
    {
        // This is very important: make sure that here you 
        // are returning true only for Razor view pages or
        // you won't have ViewBag.
        // In this oversimplified example we support
        // the index view for the home controller
        return virtualPath == "/Views/Home/Index.cshtml";
    }

    public override VirtualFile GetFile(string virtualPath)
    {
        return new CustomVirtualFile(virtualPath);
    }
}

который будет зарегистрирован в Application_Start:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    HostingEnvironment.RegisterVirtualPathProvider(new CustomPathProvider());
}

и, наконец, образец контроллера:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Name = "John";
        return View();
    }
}

И последнее очень важное замечание, если вы реализуете пользовательский VirtualPathProvider:

Это не работает, если ваше веб-приложение предварительно скомпилировано. Поэтому, если вы используете прекомпиляцию (например, "Опубликовать..." или "Проекты веб-развертывания"), ваш поставщик виртуальных путей никогда не будет использован.

Для будущих людей, которые получат эту ошибку, вы можете получить именно эту ошибку, если ваши файлы web.config отсутствуют в ваших представлениях и корневой папке проекта.

Другие вопросы по тегам