10

I have implemented a action method to minify HTML it is giving exception "filtering is not allowed" i have searched the internet but couldn't find any suitable solution. please guide me with this how I this issue will be solved. I'm sharing my code:

MinifyAttribute Class:

public class MinifyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        var request = filterContext.HttpContext.Request;
        var response = filterContext.HttpContext.Response;

        response.Filter = new Minify(response.Filter, s =>
        {
            s = Regex.Replace(s, @"\s+", " ");
            s = Regex.Replace(s, @"\s*\n\s*", "\n");
            s = Regex.Replace(s, @"\s*\>\s*\<\s*", "><");
            s = Regex.Replace(s, @"<!--(.*?)-->", "");   //Remove comments

            var firstEndBracketPosition = s.IndexOf(">");
            if (firstEndBracketPosition >= 0)
            {
                s = s.Remove(firstEndBracketPosition, 1);
                s = s.Insert(firstEndBracketPosition, ">");
            }
            return s;
        }); // i'm getting exception here on this code block

    }
}

Minify Class

public class Minify : Stream
    {
        private Stream _shrink;
        private Func<string, string> _filter;

        public Minify(Stream shrink, Func<string, string> filter)
        {
            _shrink = shrink;
            _filter = filter;
        }


        public override bool CanRead { get { return true; } }
        public override bool CanSeek { get { return true; } }
        public override bool CanWrite { get { return true; } }
        public override void Flush() { _shrink.Flush(); }
        public override long Length { get { return 0; } }
        public override long Position { get; set; }
        public override int Read(byte[] buffer, int offset, int count)
        {
            return _shrink.Read(buffer, offset, count);
        }
        public override long Seek(long offset, SeekOrigin origin)
        {
            return _shrink.Seek(offset, origin);
        }
        public override void SetLength(long value)
        {
            _shrink.SetLength(value);
        }
        public override void Close()
        {
            _shrink.Close();
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            // capture the data and convert to string 
            byte[] data = new byte[count];
            Buffer.BlockCopy(buffer, offset, data, 0, count);
            string s = Encoding.Default.GetString(buffer);

            // filter the string
            s = _filter(s);

            // write the data to stream 
            byte[] outdata = Encoding.Default.GetBytes(s);
            _shrink.Write(outdata, 0, outdata.GetLength(0));
        }


    }

I'm calling this method on the Controller and getting the exception

arserbin3
  • 5,662
  • 8
  • 31
  • 52
DevWithSigns
  • 598
  • 12
  • 31

4 Answers4

11

Try to add null-check before apply filter:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var response = filterContext.HttpContext.Response;

    if (response.Filter == null) return; // <-----

    response.Filter = new YourFilter(response.Filter);
}
vladimir
  • 8,809
  • 2
  • 23
  • 47
3

Your code seems to be working for me when used in a brand new ASP.NET MVC 5 application created in VS2013 (the regular expressions may need to be adjusted, but that's a minor detail). I've uploaded a full solution here. Could you try it out?

To be clear, I noticed that you've tagged the question with asp.net-mvc-3 and asp.net-mvc-4, but I haven't had the opportunity to test on those version of ASP.NET MVC.

Rune
  • 8,182
  • 3
  • 32
  • 47
  • your solution has also some errors but thanks for help anyways, atleast you tried but other users on this question don't even know the abc of MVC, i'm searching for some .NET library for minification of html. – DevWithSigns May 20 '14 at 21:27
  • You're welcome. Is there any particular reason you aren't using the bundling and minification stuff that is already built into ASP.NET (in System.Web.Optimization)? – Rune May 21 '14 at 06:06
  • yes but it is just used to minify CSS and JAVA Script but not html. am i right? – DevWithSigns May 21 '14 at 06:11
  • You are right, sorry, haven't had my coffee yet :-) How about just turning on gzip compression on the webserver? – Rune May 21 '14 at 06:13
  • Check the highest rated (not the accepted) answer here: http://stackoverflow.com/questions/702124/enable-iis7-gzip. – Rune May 21 '14 at 06:24
  • i want to ask few things if you're free, it is related to MVC and AJAX – DevWithSigns May 21 '14 at 06:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/54084/discussion-between-usama-sheikh-and-rune). – DevWithSigns May 21 '14 at 06:33
0

I have encountered the same issue w/ both your custom filter and mine and I was not satisified with Rune's answer (the accepted answer). I was able to determine the issue when I stumbled upon this web page.

public class MinfyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var request = filterContext.HttpContext.Request;
        var response = filterContext.HttpContext.Response;

        if (!filterContext.IsChildAction) //<--you need to make sure context is not a child action
        {
            response.Filter = new Minify(response.Filter, s =>
            {
                s = Regex.Replace(s, @"\s+", " ");
                s = Regex.Replace(s, @"\s*\n\s*", "\n");
                s = Regex.Replace(s, @"\s*\>\s*\<\s*", "><");
                s = Regex.Replace(s, @"<!--(.*?)-->", "");   //Remove comments

                var firstEndBracketPosition = s.IndexOf(">");
                if (firstEndBracketPosition >= 0)
                {
                    s = s.Remove(firstEndBracketPosition, 1);
                    s = s.Insert(firstEndBracketPosition, ">");
                }
                return s;
            }); // i'm getting exception here on this code block
        }
    }
}
0

This may be unrelated, but I landed here searching for the "Filtering is not allowed" error. It happened to me after I installed Visual Studio 2019 (I was debugging our project in VS 2017 when I got the error).

It turns out that I had to upgrade the projects from .NET Framework 4.7.1 to .NET Framework 4.8.

After that, I no longer received the error. As a bonus, our projects then also worked in Visual Studio 2019, so we got the added benefit of upgrading our Visual Studio.

Michael Earls
  • 1,195
  • 1
  • 12
  • 22