文章来源:博客园
原创作者:pfdcnblogs
MVC中以Html.Action形式调用PartialView的Action,如果该Action使用了OutputCache特性,且使用了该特性的CacheProfile属性(即从WebConfig中读取缓存配置),会出现错误:Duration 必须为正数。
但是直接在代码中设置该特性的缓存配置,不会出错。如果不调用PartialView,而是调用View,无论是从WebConfig中读取还是在代码中设置缓存配置,都很正常。
在查找过程中,发现在MVC3时代,就有很多人遇到过该问题:
I'm trying to use cache profiles for caching child actions in my mvc application, but I get an exception: Duration must be a positive number.
My web.config looks like this:
<caching> <outputCache enableOutputCache="true" /> <outputCacheSettings> <outputCacheProfiles> <add name="TopCategories" duration="3600" enabled="true" varyByParam="none" /> </outputCacheProfiles> </outputCacheSettings> </caching>And my child action something like this:
[ChildActionOnly] [OutputCache(CacheProfile = "TopCategories")] //[OutputCache(Duration = 60)] public PartialViewResult TopCategories() { //... return PartialView(); }Inside a view I just call
@Html.RenderAction("TopCategories", "Category")But I get an error:
Exception Details: System.InvalidOperationException: Duration must be a positive number.If I don't use cache profile it works. Have an idea what's the problem?
经查询,这是MVC框架的问题:
Partial caching in MVC 3 doesn't use the standard ASP.NET APIs since they're insufficient for MVC's implementation. (We're looking at ways of extending these APIs in a future version of ASP.NET so that they can be used by more consumers.)
For MVC 3, set the static OutputCacheAttribute.ChildActionCache property. The property is typed as ObjectCache, with the default implementation being an instance ofMemoryCache. ObjectCache is an abstract class, and it should be fairly straightforward to implement your own backing store on top of it. If you do want to subclass ObjectCache, keep in mind that it's in the System.Runtime.Caching.dll assembly, so you'll need to reference that from your project.
有人已经提交了BUG,但是直到现在仍没有较好的解决方案,只是错误提示将更友好一些:
OutputCacheAttribute for child actions only supports Duration, VaryByCustom, and VaryByParam values. Please do not set CacheProfile, Location, NoStore, SqlDependency, VaryByContentEncoding, or VaryByHeader values for child actions.
也有些解决方案,比如实现自己的OutputCache读取WebConfig,但不知副作用如何:
public class ChildActionOutputCacheAttribute : OutputCacheAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.IsChildAction && !string.IsNullOrWhiteSpace(CacheProfile)) { lock (this.GetType()) { if (!string.IsNullOrWhiteSpace(CacheProfile)) { // OutputCacheAttribute for child actions only supports // Duration, VaryByCustom, and VaryByParam values. var outputCache = (OutputCacheSettingsSection)WebConfigurationManager.GetSection("system.web/caching/outputCacheSettings"); var profile = outputCache.OutputCacheProfiles[CacheProfile]; if (profile.Enabled) { Duration = profile.Duration > 0 ? profile.Duration : Duration; VaryByCustom = string.IsNullOrWhiteSpace(profile.VaryByCustom) ? VaryByCustom : profile.VaryByCustom; VaryByParam = string.IsNullOrWhiteSpace(profile.VaryByParam) ? VaryByParam : profile.VaryByParam; } CacheProfile = null; } } } base.OnActionExecuting(filterContext); } }
参考资料:
MVC 3 Partial View Caching Not Honoring web.config settings
http://forums.asp.net/t/1646364.aspx?MVC+3+Partial+View+Caching+Not+Honoring+web+config+settings
Extensible Partial Output Caching in ASP.NET MVC 3
http://forums.asp.net/t/1640980.aspx
Caching ChildActions using cache profiles won't work?
http://stackoverflow.com/questions/4728958/caching-childactions-using-cache-profiles-wont-work
Asp.Net MVC 3 Partial Page Output Caching Not Honoring Config Settings
http://stackoverflow.com/questions/4797968/asp-net-mvc-3-partial-page-output-caching-not-honoring-config-settings/4800140#4800140
adjust tests for outputcache error message fix
Committed by youssefm on 二月
21, 2013. Commit 1c8fcf0e34ad.
https://aspnetwebstack.codeplex.com/SourceControl/changeset/1c8fcf0e34ad
Fixing the Asp.Net MVC 3 OutputCacheAttribute for Partial Views to Honor some web config settings
How To Contribute to ASPNET Yourself
http://ardalis.com/how-to-contribute-to-aspnet-yourself
Output Caching Actions Gotcha in ASP.NET MVC 3
http://www.dotnetcurry.com/ShowArticle.aspx?ID=665