首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Razor ViewEngine缓存呈现的HTML吗?

Razor ViewEngine缓存呈现的HTML吗?
EN

Stack Overflow用户
提问于 2018-11-27 07:03:57
回答 3查看 2.3K关注 0票数 7

我有一个二级菜单项:我有一个部门的列表,每个部门都有一个商店的列表。

我有一个菜单,PartialView,它遍历Model (部门)并构建菜单:

代码语言:javascript
复制
@model IEnumerable<Department>

<ul>
    @foreach (var department in Model)
    {
        <li>
            <a href="#">@Model.DepartmentName</a>
            <ul>
                @foreach (var store in department.Stores)
                {
                    <li><a href="some-url">@store.StoreName</a></li>
                }
            </ul>
        </li>
    }
</ul>

这就是我如何在我的PartialView中调用菜单_layout.cshtml

代码语言:javascript
复制
@Html.Partial("Shared/_Menu", MyApplicationCache.departments) 

如您所见,对于所有请求,我都将相同的模型(从缓存中)传递给PartialView。

Razor ViewEngine是否有一个内部缓存系统来确认该视图已经为该模型构建(遵从HTML )?还是对每个请求重新呈现(重新编译) PartialView?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-11-29 20:09:56

假设没有在PartialView或其操作方法上应用任何OutputCacheAttribute,则每个请求都会重新呈现Controller

如果需要输出缓存,则需要通过OutputCacheAttribute显式设置它,请参阅文档

你可以很容易地通过输出一个DateTime来检查这个问题。通过菜单项,如下图所示。

在每次请求时,它都会显示一个新的值,证明它得到了重新呈现。

代码语言:javascript
复制
<li><a href="#">@DateTime.Now</a></li>

完整菜单:

代码语言:javascript
复制
@model IEnumerable<Department>

<ul>
    @foreach (var department in Model)
    {
        <li>
            <a href="#">@Model.DepartmentName</a>
            <ul>
                <li><a href="#">@DateTime.Now</a></li>
                @foreach (var store in department.Stores)
                {
                    <li><a href="some-url">@store.StoreName</a></li>
                }                
            </ul>
        </li>
    }
</ul>
票数 5
EN

Stack Overflow用户

发布于 2018-12-06 03:32:54

在ASP.Net MVC中,重呈现和重新编译是非常不同的。虽然这里的大多数答案都是正确的,但视图只编译了一次(调试模式除外,在调试模式下,每次编译都是为了更改视图、点击刷新和查看更改,或者如果在生产中文件上的时间戳发生了更改)。它被编译成从WebViewpage(无ViewModel)或WebViewPage<T>(T类型的https://learn.microsoft.com/en-us/previous-versions/aspnet/gg402107(v%3Dvs.98%29)(has ViewModel )派生的运行时类。

为每个需要的视图实例化类(因此,如果您多次使用相同的部分,则必须每次实例化),填充模型,并调用execute()方法来创建/流HTML到客户端。每个模型都不可能缓存视图,因为这样做很复杂,相反,MVC团队选择允许配置每个控制器方法的缓存,而不是每个WebViewPage。

@ErikPhilips,非常感谢这一点--所以视图只编译了一次(不管我们是否使用OutputCache)?它是执行方法,它将运行时类呈现到HtmlString中,并且呈现将从缓存中受益?

尽管如此,但比这更先进,更容易,也更复杂。

高级-输出缓存是基于控制器方法。因此,如果输出缓存配置确定调用可以使用缓存版本,则控制器方法永远不会被称为。这就是巨大的性能收益所在。假设没有调用DB /外部API调用,就没有必要了。您可以配置缓存,以便如果它看到id=1缓存它30分钟。现在,任何通过授权和id=1调用该方法的人都会获得缓存的字符串/html。

更简单--你把你的OuputCacheAttribute放在一个方法上,配置它,你就完成了。非常容易配置。

复杂的缓存可以是更复杂,因为您可以使用Html.Action() (如果不需要部分布局的Html.Partial())或首选的Html.RenderAction(); (如果不需要布局,则使用Html.RenderPartial())来呈现其他控制器方法。过去有一个甜甜圈孔缓存问题 (推荐阅读),但它已经修复了很长时间。

票数 3
EN

Stack Overflow用户

发布于 2018-12-05 20:14:10

这个问题有一个很好的答案,这证明了PartialViews没有缓存,注释中建议的此链接解释了如何将[OutputCache]用于partialView --这可以与Html.Action() / Html.RenderAction()一起使用,并将PartialViews呈现为[ChildAction]

将PartialView缓存为子操作是有意义的,但我不想将菜单呈现为[ChildAction],因为我不想单独调用显示菜单,所以我最后做的是:

我使用RazorEngine在应用程序启动时将PartialView呈现为HtmlString,并将HtmlString保持在静态变量(缓存)中。

代码语言:javascript
复制
public static class MenuCache
{
    private static readonly MvcHtmlString _menuMvcHtmlString;

    static MenuCache()
    {
        using (var context = ApplicationDbContext.Create())
        using (var razorEngine = RazorEngineService.Create(new TemplateServiceConfiguration()))
        {
            var repository = new MyRepository(context);
            var departments = repository.GetDepartments();

            // use razorEngine to render menu partial view into html string 
            // keep the htmlString in cache: _menuMvcHtmlString
            string menuPartialView = File.ReadAllText(HostingEnvironment.MapPath("~/Views/Shared/_Menu.cshtml"));
            string menuHtmlString = razorEngine.RunCompile(menuPartialView, "menuKey", null, departments);
            _menuMvcHtmlString = new MvcHtmlString(menuHtmlString);
        }
    }

    public static MvcHtmlString GetMenuHtmlString()
    {
        return _menuMvcHtmlString;
    }
}

我还创建了一个自定义的HtmlHelper方法,它将返回菜单的HtmlString:

代码语言:javascript
复制
public static class HtmlHelperExtensions
{
    public static MvcHtmlString MyMenu(this HtmlHelper html)
    {
        return MenuCache.GetMenuHtmlString();
    }
}

现在,在我的_Layout页面中,我可以使用自定义的HtmlHelper来显示菜单:

代码语言:javascript
复制
@Html.MyMenu()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53494349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档