Support for MVC Areas?

Jun 4, 2012 at 7:21 PM

I tried following the example but when I run it all I get is a blank white page. If I remove the DonutOutputCache attribute the page renders fine.

I can think of two possible reasons for this. The first it that my site is divided into Areas and the second is that my site uses Castle Windsor for dependency Injection. Perhaps one or both of these things short-circuits the process?

My code looks a lot like the example:

 [DonutOutputCache(Duration = 60)]
 public ActionResult Index()
 {

   ... // Build a viewModel

  return View(viewModel);

 }

[ChildActionOnly]
        public ActionResult FeatureRotation()
        {
            var goldFeatureShowList = ...
            return this.PartialView(new ViewModel());
        }

The View Created By Index contains the line:

<%= Html.Action("FeatureRotation", "Home", true) %>

Any ideas?

Thanks,

Rob.

Jun 5, 2012 at 4:13 PM

You need to add the following namespace to the area web.config:

<add namespace="DevTrends.MvcDonutCaching" />

This should go under <system.web.webPages.razor> <pages... <namespaces>

This is added automatically by the NuGet package for the main site but not for areas. You can look at the web.config in the root Views folder for further clarification.

Without this namespace, the call to Html.Action is assumed to be the built-in overload where true is the routeValues argument

Jun 5, 2012 at 6:47 PM

Thanks, but that is not the problem. I did add that to each web.config (each area has it's own Views folder and web.config and I added it to all of them). I also added it to the:

<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
            <namespaces>
                <add namespace="System.Web.Mvc" />
                <add namespace="System.Web.Mvc.Html" />
                <add namespace="System.Web.Routing" />
                ....
                <add namespace="DevTrends.MvcDonutCaching" />
            </namespaces>
        </pages>

of the root web.config since not all of my views are Razor.

Before I did this, it wouldn't compile (I have it set to compile the views too) as it couldn't resolve the overload, so I know this is not the issue.

My best guess at this point is that an exception is being thrown somewhere but even stepping through the code I can't find it. There is nothing in the IIS logs, nothing in Elmah, nothing in the Windows Event logs. I can step through all the code in Both of the controller actions, it just always returns a completely empty result. View Source on the page and all you get is:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=windows-1252" http-equiv=Content-Type></HEAD>
<BODY></BODY></HTML>

and I think the browser probably generates that html because if I turn on Fiddler, all I get is the response headers:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 05 Jun 2012 17:45:29 GMT
Content-Length: 0

Comment out the attribute  [DonutOutputCache(Duration = 60)] and the page loads normally.

Any other ideas?

Jun 5, 2012 at 10:44 PM

I applied the attribute to a controller in one of the other areas on my site and it works fine there. Therefore, it does work with Areas and Castle Windsor. There must be something unique to the area I am trying to apply it (bad code in a view, bad routing, an exception being thrown but then being caught somewhere so I don't see it...) in any case, I don't think there is a problem with your library, so I'll keep looking. Thank you for your help.

Jun 6, 2012 at 7:03 PM

In case anyone else encounters this issue I thought I would share my findings: Testing the DonutOutputCache attribute on a number of different actions in different controllers I realized that it was something in the master page that was causing the problem. I commented out everything but the structural html in the master page and it worked fine. So then I slowly restored sections until the problem came back. What I found was that in the sections that caused it to break we are creating hyperlinks like this:

Url.Action("Index", "Home", new { culturePath = "en" })

and that if I removed the route values:

Url.Action("Index", "Home")

the page would render correctly. So I traced it through and found that one of our extension methods was later removing this route value:

url.RequestContext.RouteData.Values.Remove("culturePath");

I don't know why we felt the need to do this, as it is unnecessary, but removing this line of code resolved the issue. This will probably never happen to anyone else, but you never know...

Thanks again for your help and for writing such a useful tool.

Dec 14, 2012 at 5:57 PM

I just ran into an issue similar to what williarob encountered, involving RouteData.  We have a Filter (say RouteValueFilter) that adds a value to the RouteValueDictionary in OnActionExecuting like below:

filterContext.RequestContext.RouteData.Values.Add("someValue", someVar);

When the DonutOutputCaching attribute was applied to an action that used this filter, I would get a blank page for that route.  However, if I removed RouteValueFilter, the page would render properly.

The issue related to when the change to the RouteValueDictionary is made.  If I updated the attributes on the class as follows:

[RouteValueFilter(someVar = "test", Order = 0)]
[DonutOutputCache(CacheProfile = "Default", Order = 1)]
public virtual ViewResult Index()
{
    return View();
}

Everything would function properly.  Seems that it is important that modifications to the RouteDataDictionary are not made after the DonutOutputCaching's OnActionExecuting method.

I'm looking into this further, but I thought it was worth mentioning.