mdonatas
mdonatas

Reputation: 1768

ASPX parser/precompiler that generates temporary files

Is there a way to change ASPX file soure before it is precompiled into temporary files.

i.e. to remove empty spaces and new lines.

Upvotes: 4

Views: 920

Answers (5)

splattne
splattne

Reputation: 104040

ASPX files will not be "compiled" into HTML. ASPX pages are declarative code. All the content is compiled in .NET executable code.

If you want to save bandwidth deleting white spaces etc., consider using IIS compression (GZIP etc.). Here is a blog entry by Jeff Atwood about compression in IIS 6.0 which explains the details. A more difficult alternative would be to write a HTTPModule.

Upvotes: 0

Ruslan
Ruslan

Reputation: 1761

Yes, there is, but it is not easy and may not be worth your trouble.

One way of doing it is to create your own BuildProvider and replace the default System.Web.Compilation.PageBuildProvider with it in the config file:

<compilation debug="true">
    <buildProviders>
        <add extension=".aspx" type="MyProject.MyPageBuildProvider" />
    </buildProviders>
</compilation>

You would also create your own PageParser, most likely inherited from the TemplateParser. The BuildProvider is responsible for supplying the PageParser. In most primitive situation you could overwrite the ParseFile method, read the ASPX file, process it, create a copy and pass it to the base method.

Unfortunately, all ASPX parsing code is sealed and internal to MS libraries, so you can't inherit. Rewriting it would mean building entire compilation engine.

The alternative method is to create your own page builder and put it in the attribute. The drawback is that you get an easy access to literals (all your spaces etc) of the first level (the page) only. To get to inner controls and their literals, you have to either hack the parser using reflection or (proper) manipulate the code dom. This way you would get properly built .cs files and temporary assemblies.

Here is a simplified sample:

namespace MyProject
{
    [FileLevelControlBuilder(typeof(MyPageBuilder))]
    public partial class _Default : System.Web.UI.Page
    {
        //this is Default.aspx
    }

    //The builder of the page
    public class MyPageBuilder : FileLevelPageControlBuilder
    {
        //This is where you'd strip white space, but only of top level,
        //such as between the head and form, or form and the end of file
        public override void AppendLiteralString(string text)
        {
            //let's replace some white spaces with garbage
            base.AppendLiteralString(text.Replace(" ", "#").Replace("\t", "@").Replace("\r", "$").Replace("\n", "%"));
        }

        //Here you can manipulate the entire generated code using CodeDom
        public override void ProcessGeneratedCode(System.CodeDom.CodeCompileUnit codeCompileUnit, System.CodeDom.CodeTypeDeclaration baseType, System.CodeDom.CodeTypeDeclaration derivedType, System.CodeDom.CodeMemberMethod buildMethod, System.CodeDom.CodeMemberMethod dataBindingMethod)
        {
            base.ProcessGeneratedCode(codeCompileUnit, baseType, derivedType, buildMethod, dataBindingMethod);
        }

        //Alternatively, you can "hack" the PageParser here using reflection
        //However, the _text field at this point is irrelevant, so it can't be used
        public override void Init(TemplateParser parser, ControlBuilder parentBuilder, Type type, string tagName, string ID, System.Collections.IDictionary attribs)
        {
            FieldInfo fi = parser.GetType().BaseType.BaseType.BaseType.GetField("_text", System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            string s = (string) fi.GetValue(parser);
            fi.SetValue(parser, s.Replace("\t", "*"));

            base.Init(parser, parentBuilder, type, tagName, ID, attribs);
        }
    }
}

In my opinion, it is not worth the effort.

edited typo

Upvotes: 3

Glennular
Glennular

Reputation: 18215

I would suggest not going this at build time but at runtime. You probably have enough processor speed to deal with the generating of the HTML. I would aim to save on bandwidth.

I would definitely set your web server to send out the pages as compressed files (GZip)

On the application side, you can build in filters that will take your finalized rendered HTML pages and do the processes you speak of, removing whitespace, ect.

You could build an ISAPI filter, which is the older harder way.

Or you could create Stream filter and just override the write method. Set the HttpResponse.Filter Property to be your Stream Filter. Here's a quick example.

Upvotes: 1

TWith2Sugars
TWith2Sugars

Reputation: 3434

Going by your comments for thedorko's post you might want to look in to GZIP / deflate for compressing the rendered html.

Have a look at this example

Upvotes: 0

Paul Suart
Paul Suart

Reputation: 6713

It may help if you gave some background as to why you want to do this.

If, as I suspect, it's so the html is nicely laid-out when users view source, you can get visual studio to tidy up your html using the chord ctrl+k, ctrl+d.

Hope this helps.

Upvotes: 0

Related Questions