2013-04-08 11 views
9

Czy ktoś ma pojęcie o tym, jak wydrukować minified HTML i JavaScript z silnika Razor, zachowując niestandardowe style kodowania?ASP.NET MVC C# Razor Minification

Na przykład: chcę następujący kod:

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

Aby być przesyłany jako <div id="DivId"></div>.

+0

Innym rozwiązaniem byłoby przechowywanie znaczników Html jako łańcucha znaków w właściwości json i usuwanie dodatkowych znaczników HTML z tej właściwości json przy użyciu regex – Catalin

Odpowiedz

12

Spójrz http://arranmaclean.wordpress.com/2010/08/10/minify-html-with-net-mvc-actionfilter/. jest przykładem dla tworzenia niestandardowych akcji filtrowania Witch wyraźny html z whitespaces

Aktualizuj: Kod źródłowy cytowany z góry.

Klasa strumienia do usuwania "blanki"

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 klasa:

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

     } 

} 

I w końcu korzystanie z powyżej:

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

Powinieneś edytować swoją odpowiedź, aby dołączyć przykład, w którym link powinien kiedykolwiek umrzeć. –

+0

@ ashley-medway radzenie sobie z tym całym przykładem będzie trudne. Ponieważ będę musiał skopiować tekst plus obrazy. Nie sądzisz? –

+1

Może to być trudne, ale jest to słuszne, w przeciwnym razie ten wpis może stać się bezużyteczny. –

4

Nie sądzę, że jest jakikolwiek sposób, aby to osiągnąć. Aby uniknąć zupę tag zwykle preferują pisanie własnych pomocników:

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

a oto jak zwyczaj pomocnik może wyglądać następująco:

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

Ewentualnie można też zrobić zupę tag:

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

Niestandardowi pomocnicy byliby moją radą :) –

2

Może szukasz Meleze.Web

Meleze.Web to zestaw narzędzi do optymalizacji aplikacji ASP.NET MVC 3.0 i MVC 4.0.
Umożliwia minimalizację HTML, JS i CSS widoków Razor i buforowanie zwróconych stron.

Darin Dimitrov Napisz o tym tutaj: ASP.Net MVC Razor Views - Minifying HTML at build time

ale myślę, umożliwiając gzip jest lepszym rozwiązaniem, można przeczytać o tym tutaj: Minify HTML output from an ASP.Net MVC Application

+1

Meleze.web nie zminimalizuje częściowych widoków . – hiddenUser

+0

@ user2256464 wygląda jak otwarty błąd: https://github.com/meleze/Meleze.Web/issues/12 – webdeveloper

+2

@webdeveloper Zawsze widzę tę odpowiedź "_enabling gzip jest lepszym rozwiązaniem_" w tych pytaniach. Czy nie byłoby lepiej zminimalizować _and_ gzip w tym samym czasie? a nawet rzucić buforowanie po stronie klienta dla js & css etc? – snajahi

1

Dla każdego zainteresowanego w ten sposób zbudowałem prostą bibliotekę HTML, która może być używana z MVC 5:

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

Działa w czasie kompilacji zamiast wykonywania, więc nie dodawać żadnych narzut wydajności. Minifikacja jest bardzo prosta (po prostu zastępuje wiele spacji jedną spacją).

Nawet przy włączonej funkcji GZIP nad urobkiem HTML może on być still reduce the payload size.

Powiązane problemy