动态自定义RazorViewEngine?

时间:2019-02-05 03:38:15

标签: asp.net asp.net-mvc razor

我们有一个基于主题的自定义RazorViewEngine

public CustomViewEngine(string theme)
{
  PartialViewLocationFormats = new[]
  {
    "~/Views/PartialViews/" + theme + "/{0}.cshtml",
    "~/Views/PartialViews/Base/{0}.cshtml"
  };  // This is simplified, we actually have some themes falling back to some other themes before falling back to Base
}

protected void Application_Start()
{
  string theme = GetTheme(); // read from config file
  ViewEngines.Engines.Clear();
  ViewEngines.Engines.Add(new CustomViewEngine(theme));
}

当主题为静态时(例如,来自配置文件且从不更改),这一切都

但是现在我们需要使主题具有动态(用户可以对其进行更改)。
最好的方法是什么?

如果一次发送一个请求,则可以在页面加载中设置ViewEngine(在Controller中,而不是在Application_Start中),但是我担心它可能会加载错误的主题当人们同时点击页面时。

public class HomeController : Controller
{
  public ActionResult Index()
  {
    string selectedTheme = GetUserTheme(); // eg. HttpContext.Current.Request["theme"]

    // Reset ViewEngine every page load because selectedTheme may have changed
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new CustomViewEngine(selectedTheme));

    // Putting Thread.Sleep here (to simulate concurrent requests) and opening multiple
    // tabs with different theme selections will make some tabs load the wrong theme :(

    return View();
  }
}

您如何正确地获得CustomViewEngine来选择正确的主题并在并发请求中保持强大?

还是有一种方法可以替代 ViewEngine逻辑,以便我们可以编写自己的函数来定位.cshtml文件(而不是仅传递可能的文件位置数组)?

编辑:

显然,解决方案是覆盖FileExists,尽管它会使页面加载速度变慢。

protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
    // Do your own logic here, look up Request and return true or false
    return base.FileExists(controllerContext, virtualPath);
}

http://robhead89.blogspot.com/2014/01/aspnet-viewengine-caching-and-how-to.html

0 个答案:

没有答案