Search code examples
asp.netasp.net-mvccachingdonut-cachingchild-actions

Caching in ASP.NET MVC with uncachable forms


I'm doing donut caching with the MVCDonutCaching library.

Background to donut caching using this library:
The way it works, is you can cache a view, but exclude part of it from being cached, i.e. the "donut hole". You do this by having the uncachable stuff as a partial view, which is rendered by a child action. Then in the view you call that child action Html.RenderAction(.... This way everything but that child action will be cached.

Problem:
I need to cache a view, which contains a form. Problem is the form includes an AntiForgeryToken, which obviously should not be cached.

An obvious solution is to make that form a "donut hole", and render it via a child action. But, it needs complex viewmodel data, and child actions ony accept primitive types as arguments, otherwise I get serialization errors.

What is a good way around this?


Solution

  • Found a way. Not sure if it's optimal, but it works.

    Instead of making the form the "donut hole", I make the anti forgery token itself the donut hole.

    [ChildActionOnly]                
    public virtual ContentResult GetAntiForgeryToken() {
      using (var viewPage = new ViewPage()) {
        var htmlHelper = new HtmlHelper(new ViewContext(), viewPage);
        var token = htmlHelper.AntiForgeryToken();
        return Content(token.ToHtmlString());
      }
    }
    

    This requires creation of a dummy HtmlHelper, and then manually creating the token.