Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Minify Action Filter Attribute in ASP.NET MVC

Tags:

asp.net-mvc

I have a controller action that returns a large amount of dynamic JavaScript (gets served once to the client) and I already have GZip compression enabled. One thing I'd like to do is read the executed result stream and apply JS minification on it.

Is it possible to do this using an Action Filter Attribute. I think my question boils down to - Assuming my minifier takes a string of JavaScript is there a way to pull the executed result as a string out of View(view).ExecuteResult(ControllerContext) ?

like image 481
James Hughes Avatar asked Oct 15 '22 03:10

James Hughes


1 Answers

I think the YUI Compressor for .NET will do exactly what you need.

http://yuicompressor.codeplex.com/

EDIT: Above is wrong as I misread the question. The code below will install a response filter allowing you to manipulate the output, in this case it just removes newline characters.

Hope this helps.

[HandleError]
public class HomeController : Controller
{
    [Minify]
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }
}

public class Minify : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //You can check if the content type is CSS/JS here and prevent the filter running on HTML pages 

        filterContext.HttpContext.Response.Filter = new MinifyFilter(filterContext.HttpContext.Response.Filter);

        base.OnActionExecuting(filterContext);
    }
}

public class MinifyFilter : MemoryStream
{
    private StringBuilder outputString = new StringBuilder();
    private Stream outputStream = null;

    public MinifyFilter(Stream outputStream)
    {
        this.outputStream = outputStream;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        outputString.Append(Encoding.UTF8.GetString(buffer));
    }

    public override void Close()
    {
        //Call the minifier here, your data is in outputString
        string result = outputString.ToString().Replace(Environment.NewLine, string.Empty);

        byte[] rawResult = Encoding.UTF8.GetBytes(result);
        outputStream.Write(rawResult, 0, rawResult.Length);

        base.Close();
        outputStream.Close();
    }
}
like image 135
2 revs Avatar answered Oct 19 '22 02:10

2 revs