2013-04-08 172 views
9

有沒有人有任何想法如何在保持自定義編碼風格的同時從Razor引擎輸出縮小的HTML和JavaScript?ASP.NET MVC C#剃刀縮小

例如:我想以下代碼:

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

要被輸出爲<div id="DivId"></div>

+0

另一種解決方案是將HTML標記作爲字符串存儲在一個JSON屬性,並使用正則表達式 – Catalin 2013-04-08 11:49:37

回答

12

http://arranmaclean.wordpress.com/2010/08/10/minify-html-with-net-mvc-actionfilter/。 有一個例子用於創建自定義動作過濾器從WhiteSpaces清除HTML

更新:源代碼引自上面。

用於去除 「空白」

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

你應該編輯你的答案以包含一個例子,因爲鏈接應該死掉。 – 2015-04-23 17:09:24

+0

@ ashley-medway應對這整個例子將是困難的。因爲我將不得不復制文本和圖像。你不覺得嗎? – 2015-04-23 18:09:41

+1

這可能是困難的,但其正確的做法否則這個職位可能會變得毫無用處。 – 2015-04-23 21:34:31

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

自定義助手從JSON屬性中刪除多餘的HTML標記會一直在我的建議:) – 2013-04-08 11:35:05

2

也許您在尋找Meleze.Web

Meleze.Web是優化ASP.NET MVC 3.0和MVC 4.0應用程序的工具箱。
它提供了Razor視圖的HTML,JS和CSS縮小以及返回頁面的緩存。

達林季米特洛夫寫一下這裏:ASP.Net MVC Razor Views - Minifying HTML at build time

,但我認爲讓gzip是更好的解決方案,你可以在這裏讀到它:Minify HTML output from an ASP.Net MVC Application

+1

Meleze.web不會再壓縮部分美景。 – hiddenUser 2013-04-09 09:08:52

+0

@ user2256464看起來像是開放的bug:https://github.com/meleze/Meleze.Web/issues/12 – webdeveloper 2013-04-09 10:06:40

+2

@webdeveloper在這些問題中,我總是看到這個回覆「_enabling gzip is better solution_」。在同一時間縮小_and_ gzip會不會更好?甚至拋出js和css等客戶端緩存? – snajahi 2014-04-15 06:40:29