Create ETag filter in ASP.NET MVC

前端 未结 4 1924
梦毁少年i
梦毁少年i 2020-12-12 15:35

I would like to create an ETag filter in MVC. The problem is that I can\'t control the Response.OutputStream, if I was able to do that I would simply calculate the ETag acco

4条回答
  •  有刺的猬
    2020-12-12 16:12

    Thanks a lot it is exactly what I was looking for. Just made a small fix to the ETagFilter that will handle 304 in case that the content wasn't changed

    public class ETagAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Filter = new ETagFilter(filterContext.HttpContext.Response, filterContext.RequestContext.HttpContext.Request);
        }
    }
    
    public class ETagFilter : MemoryStream
    {
        private HttpResponseBase _response = null;
        private HttpRequestBase _request;
        private Stream _filter = null;
    
        public ETagFilter(HttpResponseBase response, HttpRequestBase request)
        {
            _response = response;
            _request = request;
            _filter = response.Filter;
        }
    
        private string GetToken(Stream stream)
        {
            byte[] checksum = new byte[0];
            checksum = MD5.Create().ComputeHash(stream);
            return Convert.ToBase64String(checksum, 0, checksum.Length);
        }
    
        public override void Write(byte[] buffer, int offset, int count)
        {
            byte[] data = new byte[count];
            Buffer.BlockCopy(buffer, offset, data, 0, count);
            var token = GetToken(new MemoryStream(data));
    
            string clientToken = _request.Headers["If-None-Match"];
    
            if (token != clientToken)
            {
                _response.Headers["ETag"] = token;
                _filter.Write(data, 0, count);
            }
            else
            {
                _response.SuppressContent = true;
                _response.StatusCode = 304;
                _response.StatusDescription = "Not Modified";
                _response.Headers["Content-Length"] = "0";
            }
        }
    }
    

提交回复
热议问题