Reputation: 1047
In my ASP.NET MVC app, I have a MenuController
with an Index
method decorated with [ChildActionOnly]
:
public class MenuController : Controller
{
[OutputCache(Location=OutputCacheLocation.None, Duration=0, NoStore=true)]
[ChildActionOnly]
public PartialViewResult Index()
{
return PartialView();
}
}
It's Index.cshtml
partial view simply returns a login/logoff nav menu based on whether the user is logged in or not:
@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("logoff", "account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-at"></i> @User.Identity.GetUserName() <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="~/manage" class="dropdown" title="Manage your account"><i class="fa fa-user fa-lg"></i> Account</a></li>
<li class="divider"></li>
<li><a href="javascript:document.getElementById('logoutForm').submit()" title="Log out"><i class="fa fa-sign-out fa-lg"></i> Log out</a></li>
</ul>
</li>
</ul>
}
}
else
{
<ul class="nav navbar-nav navbar-right">
<li>@Html.ActionLink("Sign up", "register", "account", routeValues: null, htmlAttributes: new { @class = "btn btn-signup", id = "registerLink" })</li>
<li>@Html.ActionLink("Log in", "login", "account", routeValues: new { returnUrl = @Request.Path }, htmlAttributes: new { id = "loginLink" })</li>
</ul>
}
I am calling this from my shared _Layout.cshtml
file as such:
@{ Html.RenderAction("Index", "Menu"); }
What I'm trying to accomplish is for that particular menu item to never be cached so that no user information are cached. However for pages where caching takes place such as my HomeController
:
public class HomeController : Controller
{
[OutputCache(CacheProfile = "OneHour", Location=OutputCacheLocation.Server, VaryByParam = "None")]
public async Task<ActionResult> Index()
{
//..some code
return View(model);
}
[ChildActionOnly]
[OutputCache(Duration = 86400, VaryByParam = "None")]
public PartialViewResult Other()
{
//some code..
return PartialView(otherModel);
}
}
...the solution doesn't work: if I go to an uncached page, navigate to logout, then head back to /Home/Index
the menu still shows me as logged in.
What am I missing here? Should the MenuController
and it's view be in the Shared
folder instead?
Upvotes: 2
Views: 752
Reputation: 394
[ChildActionOnly]
and [OutputCache(/*with anything other than Duration*/)]
is very limited in its implementation from the framework source, you have to either implement your own cache attribute class by using : OutputCacheAttribute
base class, or create an automatic sign out when the user closes page or whatever, that's what I can think of for now.
Upvotes: 1