在加载时替换 aspx 页面中的标记

发布于 2024-07-30 08:45:17 字数 562 浏览 3 评论 0原文

我有一个 aspx 页面,其中包含常规 html、一些 ui组件和 {tokenname} 形式的多个令牌。

当页面加载时,我想解析页面内容并将这些标记替换为正确的内容。 这个想法是,将有多个模板页面使用相同的代码隐藏。

我解析字符串数据本身没有问题,(请参阅 命名字符串格式替换模板中的标记)我的麻烦在于何时读取,以及如何将数据写回到页面...

重写页面内容的最佳方法是什么? 我一直在使用流读取器,并用 Response.Write 替换页面,但这不好 - 包含其他 .net 组件的页面无法正确呈现。

任何建议将不胜感激!

I have an aspx page that contains regular html, some uicomponents, and multiple tokens of the form {tokenname} .

When the page loads, I want to parse the page content and replace these tokens with the correct content. The idea is that there will be multiple template pages using the same codebehind.

I've no trouble parsing the string data itself, (see named string formatting, replace tokens in template) my trouble lies in when to read, and how to write the data back to the page...

What's the best way for me to rewrite the page content? I've been using a streamreader, and the replacing the page with Response.Write, but this is no good - a page containing other .net components does not render correctly.

Any suggestions would be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜雨飘雪 2024-08-06 08:45:17

看一下 System.Web.UI.Adapters.PageAdapter 方法 TransformText - 通常它用于多设备支持,但您可以用它来后处理您的页面。

Take a look at System.Web.UI.Adapters.PageAdapter method TransformText - generally it is used for multi device support, but you can postprocess your page with this.

携余温的黄昏 2024-08-06 08:45:17

我不确定我是否回答了你的问题,但是......
如果您可以将符号更改为

{tokenname}

类似的符号

<%$ ZeusExpression:tokenname %>

,则可以考虑创建 System.Web.Compilation.ExpressionBuilder

阅读您的评论后...

还有其他方法可以使用 ExpressionBuilder 访问当前页面:只需...创建一个表达式。 ;-)
稍微更改一下 MSDN 中的示例,假设您的页面代码包含这样的方法,

public object GetData(string token);

您可以实现这样的方法,

public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
{
    Type type1 = entry.DeclaringType;
    PropertyDescriptor descriptor1 = TypeDescriptor.GetProperties(type1)[entry.PropertyInfo.Name];
    CodeExpression[] expressionArray1 = new CodeExpression[1];
    expressionArray1[0] = new CodePrimitiveExpression(entry.Expression.Trim());

    return new CodeCastExpression(
        descriptor1.PropertyType,
        new CodeMethodInvokeExpression(
            new CodeThisReferenceExpression(),
            "GetData",
            expressionArray1));
}

这将用这样的调用替换您的占位符

(string)this.GetData("tokenname");

当然,您可以对此进行更多详细说明,也许使用“实用程序”方法”来简化和“保护”对数据的访问(对属性的访问、不涉及特殊方法、错误处理等)。

替换为(例如)的东西

(string)Utilities.GetData(this, "tokenname");

希望这会有所帮助。

I'm not sure if I'm answering your question, but...
If you can change your notation from

{tokenname}

to something like

<%$ ZeusExpression:tokenname %>

you could consider creating your System.Web.Compilation.ExpressionBuilder.

After reading your comment...

There are other ways of getting access to the current page using ExpressionBuilder: just... create an expression. ;-)
Changing just a bit the sample from MSDN and supposing the code of your pages contain a method like this

public object GetData(string token);

you could implement something like this

public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
{
    Type type1 = entry.DeclaringType;
    PropertyDescriptor descriptor1 = TypeDescriptor.GetProperties(type1)[entry.PropertyInfo.Name];
    CodeExpression[] expressionArray1 = new CodeExpression[1];
    expressionArray1[0] = new CodePrimitiveExpression(entry.Expression.Trim());

    return new CodeCastExpression(
        descriptor1.PropertyType,
        new CodeMethodInvokeExpression(
            new CodeThisReferenceExpression(),
            "GetData",
            expressionArray1));
}

This replaces your placeholder with a call like this

(string)this.GetData("tokenname");

Of course you can elaborate much more on this, perhaps using a "utility method" to simplify and "protect" access to data (access to properties, no special method involved, error handling, etc.).

Something that replaces instead with (e.g.)

(string)Utilities.GetData(this, "tokenname");

Hope this helps.

终难遇 2024-08-06 08:45:17

非常感谢那些对这个问题做出贡献的人,但是我最终使用了不同的解决方案 -

根据 此页面,除了我使用正则表达式解析多个不同标记的页面内容。

protected override void Render(HtmlTextWriter writer)
    {
         if (!Page.IsPostBack)
        {
            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
            {
                using (System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(stream))
                {
                    HtmlTextWriter htmlWriter = new HtmlTextWriter(streamWriter);
                    base.Render(htmlWriter);
                    htmlWriter.Flush();
                    stream.Position = 0;
                    using (System.IO.StreamReader oReader = new System.IO.StreamReader(stream))
                    {
                        string pageContent = oReader.ReadToEnd();
                        pageContent = ParseTagsFromPage(pageContent);
                        writer.Write(pageContent);
                        oReader.Close();
                    }
                }
            }
        }
        else
        {
            base.Render(writer);
        }
    }

这是正则表达式标记解析器

private string ParseTagsFromPage(string pageContent)
    {
        string regexPattern = "{zeus:(.*?)}"; //matches {zeus:anytagname}
        string tagName = "";
        string fieldName = "";
        string replacement = "";
        MatchCollection tagMatches = Regex.Matches(pageContent, regexPattern);
        foreach (Match match in tagMatches)
        {
            tagName = match.ToString();
            fieldName = tagName.Replace("{zeus:", "").Replace("}", "");
            //get data based on my found field name, using some other function call
            replacement = GetFieldValue(fieldName); 
            pageContent = pageContent.Replace(tagName, replacement);
        }
        return pageContent;
    }

似乎工作得很好,因为在 GetFieldValue 函数中您可以以任何您希望的方式使用字段名称。

Many thanks to those that contributed to this question, however I ended up using a different solution -

Overriding the render function as per this page, except I parsed the page content for multiple different tags using regular expressions.

protected override void Render(HtmlTextWriter writer)
    {
         if (!Page.IsPostBack)
        {
            using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
            {
                using (System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(stream))
                {
                    HtmlTextWriter htmlWriter = new HtmlTextWriter(streamWriter);
                    base.Render(htmlWriter);
                    htmlWriter.Flush();
                    stream.Position = 0;
                    using (System.IO.StreamReader oReader = new System.IO.StreamReader(stream))
                    {
                        string pageContent = oReader.ReadToEnd();
                        pageContent = ParseTagsFromPage(pageContent);
                        writer.Write(pageContent);
                        oReader.Close();
                    }
                }
            }
        }
        else
        {
            base.Render(writer);
        }
    }

Here's the regex tag parser

private string ParseTagsFromPage(string pageContent)
    {
        string regexPattern = "{zeus:(.*?)}"; //matches {zeus:anytagname}
        string tagName = "";
        string fieldName = "";
        string replacement = "";
        MatchCollection tagMatches = Regex.Matches(pageContent, regexPattern);
        foreach (Match match in tagMatches)
        {
            tagName = match.ToString();
            fieldName = tagName.Replace("{zeus:", "").Replace("}", "");
            //get data based on my found field name, using some other function call
            replacement = GetFieldValue(fieldName); 
            pageContent = pageContent.Replace(tagName, replacement);
        }
        return pageContent;
    }

Seems to work quite well, as within the GetFieldValue function you can use your field name in any way you wish.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文