{"id":2929,"date":"2014-03-10T12:58:33","date_gmt":"2014-03-10T12:58:33","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/03\/10\/custom-cache-not-working-at-child-actions-collection-of-common-programming-errors\/"},"modified":"2014-03-10T12:58:33","modified_gmt":"2014-03-10T12:58:33","slug":"custom-cache-not-working-at-child-actions-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/03\/10\/custom-cache-not-working-at-child-actions-collection-of-common-programming-errors\/","title":{"rendered":"Custom cache not working at Child Actions-Collection of common programming errors"},"content":{"rendered":"<li><img decoding=\"async\" src=\"http:\/\/i.stack.imgur.com\/I4JH8.jpg?s=32&amp;g=1\" \/><br \/>\njbl<\/p>\n<p>I&#8217;m working with a custom class that output cche for mobile and normal pages seperately. I only caches index page. It works perfect while caching with index page. But when using with child actions, the following error is thrown:<\/p>\n<pre><code>Server Error in '\/' Application.\n\nUnable to cast object of type 'System.IO.StringWriter' to type 'System.Web.HttpWriter'.\n\nDescription: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. \n\nException Details: System.InvalidCastException: Unable to cast object of type 'System.IO.StringWriter' to type 'System.Web.HttpWriter'.\n\nSource Error: \n\n\nLine 82:                         sw = new StringWriter(sb);\nLine 83:                         tw = new HtmlTextWriter(sw);\nLine 84:                         output = (HttpWriter)filterContext.RequestContext.HttpContext.Response.Output;\nLine 85:                         filterContext.RequestContext.HttpContext.Response.Output = tw;\nLine 86:                     }\n\nSource File: H:\\Yazilimlar\\Haber Sitesi v2\\HaberSitesiV2\\HaberSitesiV2\\Filters\\CustomCacheAttribute.cs    Line: 84 \n\nStack Trace: \n\n\n[InvalidCastException: Unable to cast object of type 'System.IO.StringWriter' to type 'System.Web.HttpWriter'.]\n   HaberSitesiV2.Filters.CustomCacheAttribute.OnActionExecuting(ActionExecutingContext filterContext) in H:\\Yazilimlar\\Haber Sitesi v2\\HaberSitesiV2\\HaberSitesiV2\\Filters\\CustomCacheAttribute.cs:84\n   System.Web.Mvc.Async.AsyncControllerActionInvoker.InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func`1 nextInChain) +69\n   System.Web.Mvc.Async.c__DisplayClass3b.b__35() +21\n   System.Web.Mvc.Async.AsyncControllerActionInvoker.InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func`1 nextInChain) +489\n   System.Web.Mvc.Async.c__DisplayClass3b.b__35() +21\n   System.Web.Mvc.Async.AsyncControllerActionInvoker.InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func`1 nextInChain) +489\n   System.Web.Mvc.Async.c__DisplayClass3b.b__35() +21\n   System.Web.Mvc.Async.c__DisplayClass37.b__31(AsyncCallback asyncCallback, Object asyncState) +191\n   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130\n   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters, AsyncCallback callback, Object state) +197\n   System.Web.Mvc.Async.c__DisplayClass25.b__1e(AsyncCallback asyncCallback, Object asyncState) +446\n   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130\n   System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302\n   System.Web.Mvc.c__DisplayClass1d.b__17(AsyncCallback asyncCallback, Object asyncState) +30\n   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130\n   System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +382\n   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130\n   System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317\n   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15\n   System.Web.Mvc.c__DisplayClass8.b__2(AsyncCallback asyncCallback, Object asyncState) +71\n   System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130\n   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249\n   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50\n   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16\n   System.Web.Mvc.c__DisplayClass7.b__6() +31\n   System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +27\n   System.Web.Mvc.ServerExecuteHttpHandlerAsyncWrapper.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +98\n   System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +2019\n   System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +76\n   System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +28\n   System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +19\n   System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +483\n   System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues) +83\n   System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName) +10\n   ASP._Page_Views_Anasayfa_Index_cshtml.Execute() in h:\\Yazilimlar\\Haber Sitesi v2\\HaberSitesiV2\\HaberSitesiV2\\Views\\Anasayfa\\Index.cshtml:29\n   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +197\n   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +97\n   System.Web.WebPages.StartPage.RunPage() +17\n   System.Web.WebPages.StartPage.ExecutePageHierarchy() +62\n   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +76\n   System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +260\n   System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115\n   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +295\n   System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13\n   System.Web.Mvc.c__DisplayClass1a.b__17() +23\n   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +242\n   System.Web.Mvc.c__DisplayClass1c.b__19() +21\n   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +242\n   System.Web.Mvc.c__DisplayClass1c.b__19() +21\n   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177\n   System.Web.Mvc.Async.c__DisplayClass2a.b__20() +89\n   System.Web.Mvc.Async.c__DisplayClass25.b__22(IAsyncResult asyncResult) +102\n   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57\n   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +43\n   System.Web.Mvc.c__DisplayClass1d.b__18(IAsyncResult asyncResult) +14\n   System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +23\n   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62\n   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +57\n   System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +23\n   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62\n   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +47\n   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10\n   System.Web.Mvc.c__DisplayClass8.b__3(IAsyncResult asyncResult) +25\n   System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +23\n   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62\n   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +47\n   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9\n   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9629708\n   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +155\n\nVersion Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.17929\n<\/code><\/pre>\n<p>And my class is follow.<\/p>\n<pre><code>using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Web;\nusing System.Web.Caching;\nusing System.Web.Mvc;\nusing System.Text.RegularExpressions;\nusing System.Reflection;\nusing System.Web.UI;\nusing System.Web.WebPages;\n\nnamespace HaberSitesiV2.Filters\n{\n    public enum CachePolicy\n    {\n        NoCache = 0,\n        Client = 1,\n        Server = 2,\n        ClientAndServer = 3\n    }\n\n    public class CustomCacheAttribute : ActionFilterAttribute\n    {\n        #region Public properties\n\n        public string VaryByParam { get; set; }\n        public CachePolicy CachePolicy { get; set; }\n\n        #endregion\n\n        #region Private members\n\n        private HtmlTextWriter tw;\n        private StringWriter sw;\n        private StringBuilder sb;\n        private HttpWriter output;\n        private bool cacheHitNormal = false;\n        private bool cacheHitMobile = false;\n        #endregion\n\n        #region ActionFilterAttribute overrides\n\n\n        public override void OnActionExecuting(ActionExecutingContext filterContext)\n        {\n            \/\/ Server-side caching?\n            if (CachePolicy == CachePolicy.Server || CachePolicy == CachePolicy.ClientAndServer)\n            {\n                if (filterContext.HttpContext.Application[\"cacheSql\"] != null)\n                {\n                    \/\/ Fetch cached data\n                    string key = GenerateKey(filterContext);\n                    object cachedData = HttpContext.Current.Cache.Get(key);\n                    if (cachedData != null)\n                    {\n                        \/\/ cache hit\n                        if (filterContext.HttpContext.GetOverriddenBrowser().IsMobileDevice)\n                            cacheHitMobile = true;\n                        else\n                        cacheHitNormal = true;\n                        \/\/ Return cached data\n                        filterContext.HttpContext.Response.Write(cachedData);\n                        filterContext.Result = new EmptyResult();\n                    }\n                    else\n                    {\n                        \/\/ Cache not hit.\n                        if (filterContext.HttpContext.GetOverriddenBrowser().IsMobileDevice)\n                            cacheHitMobile = false;\n                        else\n                        cacheHitNormal = false;\n                        \/\/\n                        sb = new StringBuilder();\n                        sw = new StringWriter(sb);\n                        tw = new HtmlTextWriter(sw);\n                        output = (HttpWriter)filterContext.RequestContext.HttpContext.Response.Output;\n                        filterContext.RequestContext.HttpContext.Response.Output = tw;\n                    }\n                }\n            }\n        }\n\n        public override void OnResultExecuted(ResultExecutedContext filterContext)\n        {\n            \/\/ Server-side caching?\n            if (CachePolicy == CachePolicy.Server|| CachePolicy == CachePolicy.ClientAndServer)\n            {\n                if (filterContext.HttpContext.Application[\"cacheSql\"] != null)\n                {\n                    if (filterContext.HttpContext.GetOverriddenBrowser().IsMobileDevice ? !cacheHitMobile : !cacheHitNormal)\n                    {\n                        int duration = 0;\n                            duration = Convert.ToInt32(filterContext.HttpContext.Application[\"cacheSql\"]);\n                        \/\/response processing\n                        output.Write(sb.ToString());\n                        \/\/ Add data to cache\n                        HttpContext.Current.Cache.Insert(\n                            GenerateKey(filterContext),\n                            sb.ToString(),\n                            null,\n                            DateTime.Now.AddMinutes(duration),\n                            Cache.NoSlidingExpiration,\n                            CacheItemPriority.Normal,\n                            null);\n                    }\n              }\n            }\n        }\n        #endregion\n\n        #region Helper methods\n        private string GenerateKey(ControllerContext filterContext)\n        {\n            StringBuilder cacheKey = new StringBuilder();\n\n            \/\/ Controller + action\n            cacheKey.Append(filterContext.Controller.GetType().FullName);\n            if (filterContext.RouteData.Values.ContainsKey(\"action\"))\n            {\n                cacheKey.Append(\"_\");\n                cacheKey.Append(filterContext.RouteData.Values[\"action\"].ToString());\n            }\n\n            \/\/ Variation by parameters\n            List varyByParam = VaryByParam.Split(';').ToList();\n\n            if (!string.IsNullOrEmpty(VaryByParam))\n            {\n                foreach (KeyValuePair pair in filterContext.RouteData.Values)\n                {\n                    if (VaryByParam == \"*\" || varyByParam.Contains(pair.Key))\n                    {\n                        cacheKey.Append(\"_\");\n                        cacheKey.Append(pair.Key);\n                        cacheKey.Append(\"=\");\n                        cacheKey.Append(pair.Value.ToString());\n                    }\n                }\n            }\n            cacheKey.Append(\"_\");\n            cacheKey.Append(filterContext.HttpContext.GetOverriddenBrowser().IsMobileDevice ? \"mobil\" : \"normal\");\n            return cacheKey.ToString();\n        }\n\n        #endregion\n    }\n}\n<\/code><\/pre>\n<\/li>\n","protected":false},"excerpt":{"rendered":"<p>jbl I&#8217;m working with a custom class that output cche for mobile and normal pages seperately. I only caches index page. It works perfect while caching with index page. But when using with child actions, the following error is thrown: Server Error in &#8216;\/&#8217; Application. Unable to cast object of type &#8216;System.IO.StringWriter&#8217; to type &#8216;System.Web.HttpWriter&#8217;. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2929","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2929","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=2929"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2929\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=2929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=2929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=2929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}