我有一个aspx页面,其中包含常规html、一些uicomponents和多个{tokenname}形式的标记。
当页面加载时,我希望解析页面内容并将这些标记替换为正确的内容。这个想法是,将有多个模板页面使用相同的代码隐藏。
我很容易解析字符串数据本身,(参见named string formatting,replace tokens in template)我的问题在于何时读取,以及如何将数据写回页面……
重写页面内容的最佳方式是什么?我一直在使用streamreader,并将页面替换为Response.Write,但这并不好--包含其他.net组件的页面无法正确呈现。
如有任何建议,我们将不胜感激!
发布于 2009-08-20 11:16:00
非常感谢那些为这个问题做出贡献的人,但是我最终使用了一个不同的解决方案-
按照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);
}
}下面是regex标记解析器
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函数中,您可以以任何您希望的方式使用您的字段名。
发布于 2009-08-12 10:24:01
看看System.Web.UI.Adapters.PageAdapter method TransformText --通常它是用来支持多设备的,但是你可以用它来后处理你的页面。
发布于 2009-08-12 13:45:56
我不确定我是不是在回答你的问题,但是...如果您可以将您的符号从
{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");希望这能有所帮助。
https://stackoverflow.com/questions/1265300
复制相似问题