asp.net MVC ActionFilter для удаления пустых строк в результате - PullRequest
2 голосов
/ 16 февраля 2010

Пожалуйста, помогите мне с этим фильтром действий.

Я думаю, мне нужно использовать метод OnResultExecuted

Как я могу получить доступ к otput html и заменить что-то в них?

спасибо.

Ответы [ 3 ]

2 голосов
/ 16 февраля 2010

Как насчет использования HTTP-модуля для удаления пробелов? Это просто реализовать, очистить и использовать повторно ...

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

Как и в случае любого общего решения для удаления пробелов, оно может легко привести к ошибкам, удаляя пробелы там, где это необходимо. Хотя это не займет много времени, чтобы попробовать. : -)

Отредактировано после комментариев

Это не будет работать с файлами .aspx из коробки, поэтому вам нужно изменить context_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);
    }
}
1 голос
/ 02 июля 2010

Я бы хотел расширить решение Рассела. В MVC или я думаю, везде в событии beginrequest Response.ContentType является "text / html", так как мы не знаем, что мы ответим. Я основал еще одно событие, в котором определяется контент и применяется фильтр: PostReleaseRequestState

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

1 голос
/ 16 февраля 2010

Теперь я вижу, что вы хотите сделать. И я думаю, что у меня может быть решение. Некоторое время назад я использовал части этого подхода в решении кэша вывода, поэтому думаю, что он будет работать.

Сначала вам нужен собственный класс потока, который выглядит следующим образом:

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

Я бы посчитал это немного хакерским решением. Но я не видел ничего, что не было.

...