Model view controller asp.net MVC ActionFilter用于删除结果中的空行

Model view controller asp.net MVC ActionFilter用于删除结果中的空行,model-view-controller,action-filter,Model View Controller,Action Filter,请帮助我使用此操作筛选器 我想我需要使用OnResultExecuted方法 如何访问otput html并替换其中的内容 谢谢。现在我知道你想做什么了。我想我可能有个解决办法。不久前,我在一个输出缓存解决方案中使用了这种方法的一部分,所以我认为它会起作用 首先,您需要自己的流类,如下所示: private class CapturingResponseFilter : Stream { private readonly Stream _sink; private readonl

请帮助我使用此操作筛选器

我想我需要使用OnResultExecuted方法

如何访问otput html并替换其中的内容


谢谢。

现在我知道你想做什么了。我想我可能有个解决办法。不久前,我在一个输出缓存解决方案中使用了这种方法的一部分,所以我认为它会起作用

首先,您需要自己的流类,如下所示:

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);
    }
}
然后在动作过滤器中执行以下操作:

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);
    }

我认为这是一个简单的解决方案。但是我没有看到任何不存在的东西。

使用删除空白的HTTP模块怎么样?它易于实现、干净且可重用

不过,与任何通用的空白删除解决方案一样,它可以通过在需要的地方删除空白来轻松引入错误。不过,不用多久就可以尝试一下。:-)

在评论后编辑

这不适用于现成的.aspx文件,因此您需要将上下文\u BeginRequest更改为以下内容

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);
    }
}

我想扩展Russel的解决方案。在MVC或beginrequest事件中,Response.ContentType是“text/html”,因为我们不知道要回答什么。 我发现了另一个事件,其中定义了内容并且过滤器是可应用的:PostReleaseRequestState


你想做什么(为什么)?如果您想删除空行以最小化输出,您可能应该考虑使用gzip压缩结果。。例如:现在我们为移动设备制作一个web应用程序,在一些旧设备上,我们有很多空行、空格(!)等问题。。我们试图找到一种从html中删除它们的方法。最好的视图是所有html都将在一条长线中转换。该模块的功能与我建议的基本相同。但是,它不适用于asp.net mvc开箱即用,因为它要求您的url中有一个.aspx扩展名(这里可能不是这种情况)。因此,您必须找到另一种方法来检查是否应该删除响应中的空白。您可以通过对照regexp检查响应并查看它是否为html来实现这一点。只检查响应上的内容类型text/html(或application/xhtml+xml,具体取决于您返回的内容)如何?请参见编辑我的原始答案。我认为HTTP模块由于其模块化和易重用性将是有益的;如果(rawUrl.Contains(“/account/”)| | rawUrl.Contains(“/feedback/”)| | rawUrl.Contains(“/home/”){(按控制器名称)是的,检查内容类型是一个更好的主意。我同意http模块可能是此任务的更好解决方案。谢谢。您的方法与类似,但有一些问题。我将它们应用于基本控制器(所有控制器都继承自它们)现在我遇到了重定向操作的问题:在发送HTTP头之后无法重定向!您不能对所有操作执行重定向,只能对呈现html的一次操作执行重定向。您可能希望查看Russell的解决方案。这与此基本相同,但使用HTTP模块而不是操作筛选器。