2013-04-08 3 views
9

Есть ли у кого-нибудь представление о том, как выводить миниатюрные HTML и JavaScript из механизма Razor при сохранении пользовательских стилей кодирования?ASP.NET MVC C# Razor Minification

Например: я хочу следующий код:

<div 
    @if (Model.Name != string.Empty) 
     @:id="@Model.Name" 
> 
</div> 

, выдаваемый в качестве <div id="DivId"></div>.

+0

Еще одним решением было бы сохранить разметку Html как строку в свойстве json и удалить дополнительную метку html из этого свойства json с помощью regex – Catalin

ответ

12

Посмотрите на http://arranmaclean.wordpress.com/2010/08/10/minify-html-with-net-mvc-actionfilter/. есть пример для создания пользовательских действий фильтров ведьмы ясного HTML от пробельных

Update: Исходный код цитировал выше.

Класс потока для удаления "заготовок"

using System; 
using System.IO; 
using System.Text; 
using System.Web.Mvc; 
using System.Text.RegularExpressions; 

namespace RemoveWhiteSpace.ActionFilters 
{ 
    public class WhiteSpaceFilter : Stream 
    { 

     private Stream _shrink; 
     private Func<string, string> _filter; 

     public WhiteSpaceFilter(Stream shrink, Func<string, string> filter) 
     { 
      _shrink = shrink; 
      _filter = filter; 
     } 


     public override bool CanRead { get { return true; } } 
     public override bool CanSeek { get { return true; } } 
     public override bool CanWrite { get { return true; } } 
     public override void Flush() { _shrink.Flush(); } 
     public override long Length { get { return 0; } } 
     public override long Position { get; set; } 
     public override int Read(byte[] buffer, int offset, int count) 
     { 
      return _shrink.Read(buffer, offset, count); 
     } 
     public override long Seek(long offset, SeekOrigin origin) 
     { 
      return _shrink.Seek(offset, origin); 
     } 
     public override void SetLength(long value) 
     { 
      _shrink.SetLength(value); 
     } 
     public override void Close() 
     { 
      _shrink.Close(); 
     } 

     public override void Write(byte[] buffer, int offset, int count) 
     { 
      // capture the data and convert to string 
      byte[] data = new byte[count]; 
      Buffer.BlockCopy(buffer, offset, data, 0, count); 
      string s = Encoding.Default.GetString(buffer); 

      // filter the string 
      s = _filter(s); 

      // write the data to stream 
      byte[] outdata = Encoding.Default.GetBytes(s); 
      _shrink.Write(outdata, 0, outdata.GetLength(0)); 
     } 
    } 
} 

ActionFilter класс:

public class WhitespaceFilterAttribute : ActionFilterAttribute 
{ 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 

     var request = filterContext.HttpContext.Request; 
     var response = filterContext.HttpContext.Response; 

     response.Filter = new WhiteSpaceFilter(response.Filter, s => 
       { 
        s = Regex.Replace(s, @"\s+", " "); 
        s = Regex.Replace(s, @"\s*\n\s*", "\n"); 
        s = Regex.Replace(s, @"\s*\>\s*\<\s*", "><"); 
        s = Regex.Replace(s, @"<!--(.*?)-->", ""); //Remove comments 

        // single-line doctype must be preserved 
        var firstEndBracketPosition = s.IndexOf(">"); 
        if (firstEndBracketPosition >= 0) 
        { 
         s = s.Remove(firstEndBracketPosition, 1); 
         s = s.Insert(firstEndBracketPosition, ">"); 
        } 
        return s; 
       }); 

     } 

} 

И в конце концов, использование выше:

[HandleError] 
[WhitespaceFilter] 
public class HomeController : Controller 
{ 
    ... 
} 
+1

Вы должны отредактировать свой ответ, чтобы включить пример, когда ссылка должна когда-либо гаснуть. –

+0

@ Ashley-medway справиться с этим целым примером будет непросто. Потому что мне придется копировать текст плюс изображения. Вам не кажется? –

+1

Возможно, это будет сложно, но это правильно, иначе это сообщение может стать бесполезным по линии. –

4

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

@using(Html.MyDiv(Model.Name)) 
{ 
    ... put the contents of the div here 
} 

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

public static class HtmlExtensions 
{ 
    private class Div : IDisposable 
    { 
     private readonly ViewContext context; 
     private bool disposed; 

     public Div(ViewContext context) 
     { 
      this.context = context; 
     } 

     public void Dispose() 
     { 
      this.Dispose(true); 
      GC.SuppressFinalize(this); 
     } 

     protected virtual void Dispose(bool disposing) 
     { 
      if (!this.disposed) 
      { 
       this.disposed = true; 
       context.Writer.Write("</div>"); 
      } 
     } 
    } 

    public static IDisposable MyDiv(this HtmlHelper html, string id) 
    { 
     var div = new TagBuilder("div"); 
     if (!string.IsNullOrEmpty(id)) 
     { 
      div.GenerateId(id); 
     } 
     html.ViewContext.Writer.Write(div.ToString(TagRenderMode.StartTag)); 
     return new Div(html.ViewContext);    
    } 
} 

В качестве альтернативы вы можете также сделать тег суп:

<[email protected](Model.Name != string.Empty ? string.Format(" id=\"{0}\"", Html.AttributeEncode(Model.Name)) : string.Empty)> 
</div> 
+1

Пользовательские помощники были бы моим советом :) –

2

Возможно, вы ищете Meleze.Web

Meleze.Web - это инструмент для оптимизации приложений ASP.NET MVC 3.0 и MVC 4.0.
Он обеспечивает оценку HTML, JS и CSS просмотров Razor и кэширование возвращенных страниц.

Дарин Димитров написать об этом здесь: ASP.Net MVC Razor Views - Minifying HTML at build time

Но я думаю, что позволяет gzip является лучшим решением, вы можете прочитать об этом здесь: Minify HTML output from an ASP.Net MVC Application

+1

Meleze.web не уменьшает частичные виды , – hiddenUser

+0

@ user2256464 выглядит как открытая ошибка: https://github.com/meleze/Meleze.Web/issues/12 – webdeveloper

+2

@webdeveloper Я всегда вижу этот ответ «_enabling gzip - лучшее решение» в этих вопросах. Не было бы лучше минимизировать _and_ gzip одновременно? и даже бросить кеширование на стороне клиента для js & css и т. д.? – snajahi

1

Для всех, кто заинтересован в это, я построил простую библиотеку миниатюр HTML, которая может быть использована с MVC 5:

https://github.com/tompazourek/RazorHtmlMinifier.Mvc5

Он работает в компиляции вместо выполнения, поэтому он не добавляет накладные расходы на производительность. Минизация очень проста (просто заменяет множество пространств одним пространством).

Даже с включенным GZIP поверх миниатюрного HTML он может still reduce the payload size.

Смежные вопросы