2010-02-16 2 views
2

Пожалуйста, помогите мне с этим фильтром действий.asp.net MVC ActionFilter для удаления пустых строк в результате

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

Как я могу получить доступ к HTML и Задачи и результаты заменить что-нибудь в них?

спасибо.

+0

Что вы хотите делать (и почему)? Если вы хотите удалить пустые строки, чтобы свести к минимуму вывод, вы должны, вероятно, посмотреть на сжатие результата с помощью gzip. –

+0

Как вы знаете, после рендеринга страницы в исходном коде (HTML) в местах кода, за оставшиеся пустые строки .. напр:

Теперь мы делаем веб-приложение для мобильных устройств, а также на некоторых старых устройств, которые мы имеем много проблем с пустыми строками, пробелами (!) и т. д. Мы пытаемся найти способ удалить их из html. Лучший вид - все html будут преобразованы в 1 длинную строку. – Maxim

ответ

2

Как насчет использования 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); 
    } 
} 
+0

Этот модуль делает почти то же самое, что я и предложил. Тем не менее, он не будет работать с asp.net mvc из коробки, поскольку для этого требуется расширение .aspx в вашем URL-адресе (возможно, это не так). Поэтому вам нужно будет найти другой способ проверить, следует ли удалять пробелы в ответе. Вы можете сделать это, проверив ответ на регулярное выражение и посмотрите, является ли он html. –

+0

Как просто проверить тип содержимого в ответе для text/html (или application/xhtml + xml в зависимости от того, что вы возвращаете)? См. Редактирование исходного ответа. Я думаю, что HTTP-модуль будет полезен из-за его модульности и простоты повторного использования. –

+0

Я использую этот метод и применяется в global.asax с расширением .aspx i, разрешенным таким образом: string rawUrl = Request.RawUrl.ToLower(); если (rawUrl.Contains ("/ счет /") || rawUrl.Contains ("/ обратная связь /") || rawUrl.Contains ("/ дома /")) { (по именам контроллеров) – Maxim

1

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

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

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

я считал бы немного решение для взлома. Но я не видел ничего подобного.

+0

Спасибо. Ваш метод похож на http://madskristensen.net/post/A-whitespace-removal-HTTP-module-for-ASPNET-20.aspx, , но есть некоторые проблемы. Я применил их к базовому контроллеру (все контроллеры наследуются от них), и теперь у меня проблемы с действиями Redirect: невозможно перенаправить после отправки HTTP-заголовков! – Maxim

+0

Вы не можете сделать это для всех действий, только один раз, который отображает html.Возможно, вы захотите проверить решение Рассела. Это почти то же самое, но использует модуль http вместо фильтра действий. –

1

Я хотел бы расширить решение Рассела. В MVC или я предполагаю, что везде в startrequest-событии Response.ContentType является «text/html», так как мы не знаем, на что мы ответим. я founf другого события, в котором определяется содержание и фильтр applyable: PostReleaseRequestState

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