ASPX解析器/预编译器,用于生成临时文件

时间:2009-03-19 11:41:28

标签: asp.net

在预编译成临时文件之前,有没有办法更改ASPX文件源。

即。删除空格和新行。

5 个答案:

答案 0 :(得分:3)

是的,有,但这并不容易,可能不值得你麻烦。

这样做的一种方法是创建自己的BuildProvider并在配置文件中用它替换默认的System.Web.Compilation.PageBuildProvider:

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

您还可以创建自己的PageParser,很可能是从TemplateParser继承的。 BuildProvider负责提供PageParser。在最原始的情况下,您可以覆盖ParseFile方法,读取ASPX文件,处理它,创建副本并将其传递给基本方法。

不幸的是,所有ASPX解析代码都是密封的,并且是MS库的内部代码,因此您无法继承。重写它意味着构建整个编译引擎。

另一种方法是创建自己的页面构建器并将其放在属性中。缺点是您只能轻松访问第一级(页面)的文字(所有空间等)。要获得内部控件及其文字,您必须使用反射或(正确)操作代码dom来破解解析器。这样您就可以正确构建.cs文件和临时程序集。

以下是简化示例:

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

在我看来,这是不值得的。

已编辑拼写错误

答案 1 :(得分:1)

我建议不要在构建时但在运行时这样做。您可能有足够的处理器速度来处理HTML的生成。我的目标是节省带宽。

我肯定会将您的网络服务器设置为将页面作为压缩文件发送出去(GZip)

在应用程序方面,您可以构建过滤器,这些过滤器将获取最终呈现的HTML页面并执行您所说的过程,删除空格等。

您可以构建一个ISAPI过滤器,这是更难的方法。

或者你可以创建Stream过滤器并覆盖write方法。将HttpResponse.Filter Property设置为您的流过滤器。这是一个快速example

答案 2 :(得分:0)

如果您提供了一些关于为什么这样做的背景知识,这可能会有所帮助。

如果,正如我怀疑的那样,当用户查看源代码时,html很好地布局,你可以使用和弦ctrl + k,ctrl + d来使用Visual Studio来整理你的html。

希望这有帮助。

答案 3 :(得分:0)

ASPX文件将“编译”为HTML。 ASPX页面是声明性代码。所有内容都是用.NET可执行代码编译的。

如果要节省带宽删除空格等,请考虑使用 IIS压缩(GZIP等)。这是一个blog entry by Jeff Atwood about compression in IIS 6.0,它解释了细节。更难的选择是编写HTTPModule。

答案 4 :(得分:0)

根据您对thedorko帖子的评论,您可能希望查看GZIP / deflate来压缩渲染的HTML。

查看this example