asp.net MVC ActionFilter for remove empty lines in

2019-07-22 02:39发布

Please help me with this action filter.

I think i need to use OnResultExecuted method

How can i have access to otput html and replace something in them?

thank you.

3条回答
霸刀☆藐视天下
2楼-- · 2019-07-22 02:50

How about using a whitespace removal HTTP module? It's simple to implement, clean and reusable...

http://madskristensen.net/post/A-whitespace-removal-HTTP-module-for-ASPNET-20.aspx

As with any generic whitespace removal solution though, it can easily introduce errors by removing white space where it is required. It wouldn't take long to give it a try though. :-)

Edited after comments

This will not work with .aspx files out of the box so you'll need to change the context_BeginRequest to the following...

void context_BeginRequest(object sender, EventArgs e)
{
    HttpApplication app = sender as HttpApplication;
    if (app.Response.ContentType == "text/html"
        || app.Response.ContentType == "application/xhtml+xml")
    {
        app.Response.Filter = new WhitespaceFilter(app.Response.Filter);
    }
}
查看更多
爷、活的狠高调
3楼-- · 2019-07-22 02:53

I would like to extend Russel's solution. In MVC or i guess everywhere in beginrequest event the Response.ContentType is "text/html" since we don't know what we will answer. I founf another event where the content is defined and the filter is applyable: PostReleaseRequestState

http://www.4guysfromrolla.com/articles/120308-1.aspx

查看更多
Luminary・发光体
4楼-- · 2019-07-22 02:55

Now I see what you want to do. And I think I might have a solution. I have used parts of this approach in a output cache solution a while back, so I think it will work.

First you need your own stream class that looks like this:

private class CapturingResponseFilter : Stream
{
    private readonly Stream _sink;
    private readonly MemoryStream _mem;

    public CapturingResponseFilter(Stream sink)
    {
        _sink = sink;
        _mem = new MemoryStream();
    }

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanSeek
    {
        get { return false; }
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override long Length
    {
        get { return 0; }
    }

    public override long Position { get; set; }

    public override long Seek(long offset, SeekOrigin direction)
    {
        return 0;
    }

    public override void SetLength(long length)
    {
        _sink.SetLength(length);
    }

    public override void Close()
    {
        _sink.Close();
        _mem.Close();
    }

    public override void Flush()
    {
        _sink.Flush();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        return _sink.Read(buffer, offset, count);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        _mem.Write(buffer, 0, count);
    }

    public string GetContents(Encoding enc)
    {
        var buffer = new byte[_mem.Length];
        _mem.Position = 0;
        _mem.Read(buffer, 0, buffer.Length);
        return enc.GetString(buffer, 0, buffer.Length);
    }
}

And then you do something like this in your action filter:

private Stream _originalOutputStream;

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        _originalOutputStream = filterContext.HttpContext.Response.Filter;
        filterContext.HttpContext.Response.Flush();
        filterContext.HttpContext.Response.Filter = new CapturingResponseFilter(filterContext.HttpContext.Response.Filter);
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (_originalOutputStream == null) return;

        filterContext.HttpContext.Response.Flush();
        var capturingResponseFilter = (CapturingResponseFilter)filterContext.HttpContext.Response.Filter;
        filterContext.HttpContext.Response.Filter = _originalOutputStream;
        var textWritten = capturingResponseFilter.GetContents(filterContext.HttpContext.Response.ContentEncoding);
        //Do what you want with your text (textWritten).
        filterContext.HttpContext.Response.Write(textWritten);
    }

I would consider it a little bit of a hack solution. But I haven't seen anything that isn't.

查看更多
登录 后发表回答