OutputCache on server

2019-08-02 02:45发布

问题:

I define OutputCache attributes on top of my controller actions, so that the server can give the same response quickly to different users. Bu it caches the whole page. I mean the master page is also cached if I have cached an action that returns a View(). So the user account information on top of the master page gets shared by every user. I want to cache only the content page, not the master page, _Layout.cshtml. How can I exclude that?

Edit: The part where I'm having trouble is this:

@if(Request.IsAuthenticated) {
    <text>Hello <strong>@User.Identity.Name</strong>!</text>
    @: | 
    @Html.ActionLink("Index", "Index", "Account")
    @: |
    @Html.ActionLink("Logout", "Logout", "Account")
}
else
{
    @:|
   @Html.ActionLink("Login", "Login", "Account")
}

When I cache a controller action, the returned view also carries this userlogin part from the cache, so it gives wrong salutes to almost every user. How can I dynamically generate this part even if the page is cached?

回答1:

VaryByCustom is what you want.

Put this in your Global.asax:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    return "User".Equals(custom, StringComparison.OrdinalIgnoreCase)
        ? User.Identity.Name
        : base.GetVaryByCustomString(context, custom);
}

...then use an [OutputCache(VaryByCustom = "User")] attribute.

This will still cause the whole page to be cached separately, but a separate cache will be created for each user.

If you are looking for other options, search for MVC donut caching or MVC donut hole caching.

Reply to comment

Sounds like you want donut hole caching. See if this answer helps you.