2009-08-12 36 views
0

我有一个aspx页面,其中包含常规html,一些uicomponents和{tokenname}形式的多个标记。加载aspx页面上的标记加载

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

我不麻烦解析字符串数据本身,(见named string formattingreplace tokens in template)我的麻烦在于,当阅读,以及如何将数据写回页面...

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

任何建议将不胜感激!

回答

0

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

重写渲染功能为每this page,除了我的解析使用正则表达式多种不同的标签页内容。

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函数中。

1

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

1

我不知道如果我回答你的问题,但是... 如果你可以从

{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"); 

希望这有助于。

+0

这是一个非常有趣的解决方案,感谢您的输入:) 问题是我需要来自我当前页面的数据以呈现替换文本 - 不确定是否可以将当前页面中的内容传递到表达式生成器? 我刚刚找到了一个解决方案......也许我应该回答我自己的问题,以防其他人想知道 – RYFN 2009-08-12 14:57:17

+0

是的,我同意你应该给你自己的解决方案。无论如何,我编辑我的建议(试图)回答你的一些担忧。 – 2009-08-17 10:55:55