Question

I want to play with action filter creation and implement action filter for ETag and make caching of HomeController from mvc 4 template for say 10 seconds.

Here is my attribute:

public class EtagFilterAttribute : ActionFilterAttribute
    {
        private DateTime _currentTime = DateTime.Now;

        private string _currentEtag = string.Empty;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var httpContext = filterContext.RequestContext.HttpContext;

            string eTag = httpContext.Request.Headers["ETag"];

            string responseETag = GetEtag();

            if (!string.IsNullOrEmpty(eTag))
            {
                if (eTag.Equals(responseETag))
                {
                    filterContext.HttpContext.Response.StatusCode = 304;

                    filterContext.HttpContext.Response.StatusDescription = "Not Modified";
                }

                return;
            }

            filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);

            filterContext.HttpContext.Response.AddHeader("ETag", responseETag);

            filterContext.HttpContext.Response.Cache.SetETag(responseETag);
        }

        private string GetEtag()
        {
            if (_currentTime <= DateTime.Now.AddSeconds(10))
            {
                return _currentEtag;
            }

            _currentEtag = GenerateEtag();

            return _currentEtag;
        }

        private string GenerateEtag()
        {
            return Guid.NewGuid().ToString().Substring(0, 20);
        }
    }

Here is HomeController:

public class HomeController : Controller
    {
        [EtagFilter]
        public ActionResult Index()
        {
            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

            return View();
        }

        [EtagFilter]
        public ActionResult About()
        {
            ViewBag.Message = "Your app description page.";

            return View();
        }

        [EtagFilter]
        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }

It's compiled and runs but in Chrome Developer tools Network->Headers tab I don't see ETag:

Request URL:http://:1772/Home/About Request Method:GET Status Code:200 OK Request Headersview source Accept:text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 Connection:keep-alive Cookie:__RequestVerificationToken=q0yQrf5ee5bsOW-1OXKK754FeRZM89uNQQ1rvN2cVRXaHsPGhOTt2zw2cUyfmu-0uZGLL5-ebs-iJH1-RQ3Q7qb6z4jTHNY8yGJQ3KBYhRs1 Host:localhost:1772 Referer:http://:1772/ User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36 Response Headersview source Cache-Control:private Content-Encoding:gzip Content-Length:956 Content-Type:text/html; charset=utf-8 Date:Fri, 04 Oct 2013 15:34:02 GMT Server:Microsoft-IIS/8.0 Vary:Accept-Encoding X-AspNet-Version:4.0.30319 X-AspNetMvc-Version:4.0 X-Powered-By:ASP.NET X-SourceFiles:=?UTF-8?B?ZDpcTXlEb2N1bWVudHNcR2VuZXJhbFxDI1wuTmV0IE1lbnRvcmluZyBQcm9ncmFtXEhUVFBcRXhhbXBsZVxIdHRwRm9yRGV2ZWxvcGVyc1xIb21lXEFib3V0?=

Could you tell me where I'm mistaken?

Was it helpful?

Solution

This works:

public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var httpContext = filterContext.RequestContext.HttpContext;

            string eTag = httpContext.Request.Headers["ETag"];

            string responseETag = GetEtag();

            if (!string.IsNullOrEmpty(eTag))
            {
                if (eTag.Equals(responseETag))
                {
                    filterContext.HttpContext.Response.StatusCode = 304;

                    filterContext.HttpContext.Response.StatusDescription = "Not Modified";
                }

                return;
            }

            httpContext.Response.AddHeader("ETag", responseETag);
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top