5

I am trying to implement Output caching for my action results.

In my actions depending upon some business rules response is returned. In my response I send error code. I do not want to cache the response if there is any error.

Following in the Action Result

  class Response 
  {
    public int ErrorCode { get; set; }
    public string Message { get; set; }

}


    [OutputCache(CacheProfile = "Test")]
    public ActionResult Sample()
    {
        Response response = new Response();
        return new JsonResult { Data = response, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
    }

I want cache the Result only if ErrorCode==0.

I tried overriding OutputCache, but it is not working

 public class CustomOutputCacheAttribute : OutputCacheAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {

            if (filterContext.Result is JsonResult)
            {
                var result = (JsonResult)filterContext.Result;
                BaseReponse response = result.Data as BaseReponse;
                if (!response.IsSuccess)
                {
                    filterContext.HttpContext.Response.Cache.SetNoStore();
                }
                base.OnActionExecuted(filterContext);
            }
        }


    }

Is there any other way or approach to achieve this.

Thanks

3
  • Overriding OutputCacheAttribute is the correct way of doing it. You can also cache the response object manually inside your action method. Commented Feb 18, 2015 at 9:08
  • Why are you implementing your own error response objects? OutputCache has built-in support for normal HTTP errors... Commented Feb 18, 2015 at 9:20
  • Can you give reference for the same? Commented Feb 18, 2015 at 9:24

1 Answer 1

3

You can create your own custom attribute that will ignore [OutputCache] based on the result error code, something like this:

[OutputCache(Duration=60, VaryByParam="none")]
[OutputCacheValidation]
public ActionResult Sample()
{
    var r = new Response();
    r.ErrorCode = 0;  
    return Json(r, JsonRequestBehavior.AllowGet);
}

public class OutputCacheValidationAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        base.OnResultExecuting(filterContext);
        filterContext.HttpContext.Response.Cache.AddValidationCallback(ValidatioCallback, filterContext.Result);
    }

    private static void ValidatioCallback(HttpContext context, object data, ref HttpValidationStatus validationStatus)
    {
        var jsonResult = data as JsonResult;
        if (jsonResult == null) return;

        var response = jsonResult.Data as Response;
        if (response == null) return;

        if (response.ErrorCode != 0)
        {
            //ignore [OutputCache] for this request
            validationStatus = HttpValidationStatus.IgnoreThisRequest;
            context.Response.Cache.SetNoServerCaching();
            context.Response.Cache.SetNoStore();
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, however it is still saving the data to cache but while serving it does the validation. I wanted to not store data at all in cache if error occurs
I got the idea from your code and juristr.com/blog/2012/10/output-caching-in-aspnet-mvc. Now it is working. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.