0

我想知道是否可以从转发器控件中读取 ItemTemplate 的原始标记?

考虑下面的中继器:

<asp:Repeater ID="uiReport" runat="server" EnableViewState="False">
    <HeaderTemplate>
        <table border="1">
            <thead>
                <tr>
                    <th>Product</th>
                </tr>
            </thead>
            <tbody>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td><%#((Product)Container.DataItem).ProductName%></td>
        </tr>
    </ItemTemplate>
    <FooterTemplate>
        </tbody></table>
    </FooterTemplate>
</asp:Repeater> 

我正在尝试以原始字符串格式读取项目模板,例如作为如下所示的字符串:

string itemTemplate = "<tr><td><%#((Product)Container.DataItem).ProductName%></td></tr>"

根据下面的调用堆栈屏幕抓取,使用反射器并查看调用堆栈引导我使用以下方法(请参见突出显示的第一行):

调用栈

我假设从...__BuildControl__control6()...中读取 .aspx 页面中标记的原始内容、切碎(RegEx?)并作为参数传递给以下方法:

System.Web.UI.DataBoundLiteralControl.SetStaticString(index, s);

对于本例中的 Repeater 控件,“s”(字符串)参数具有以下值:

\r\n                <tr>\r\n                    <td>

请注意,字符串已在 <%# 的第一个实例上拆分。

MSDN 搜索确认 SetStaticString 方法支持 .NET Framework 基础结构,并且不打算直接从您的代码中使用。

http://msdn.microsoft.com/en-us/library/system.web.ui.databoundliteralcontrol.setstaticstring.aspx

是否有我缺少的虚拟方法可以让我获取原始模板标记,或者是我自己读取文件内容的唯一选择(下面的代码示例)并覆盖Control 基类的必要Render()方法?

手动读取 .aspx 页面内容的详细代码示例:

string rawPageMarkUp = File.ReadAllText(physicalPathOfAspxPage);
string rawItemTemplate = RegExMethodToExtractItemTemplateFromControl(controlName, rawPageMarkUp);
4

1 回答 1

0

答案似乎是否定的,没有可用于获取未解析页面的虚拟方法。处理解析页面/控件的方法由密封类和内部方法组成。

这个问题的解决方案是问题中描述的替代建议。

下面是类的详细信息,以便您可以查看本机实现以了解代码的外观。

从以下密封类开始:

System.Web.UI.PageParser

这继承自抽象类:

System.Web.UI.TemplateControlParser

这个类继承了一个名为:

ParseFile

遵循继承的类,直到达到:

System.Web.UI.TemplateParser

您将在此处找到包含读取原始文件和解析内容的起点的方法:

internal void ParseFile(string physicalPath, VirtualPath virtualPath)
{
    string o = (physicalPath != null) ? physicalPath : virtualPath.VirtualPathString;
    if (this._circularReferenceChecker.Contains(o))
    {
        this.ProcessError(SR.GetString("Circular_include"));
    }
    else
    {
        this._circularReferenceChecker.Add(o);
        try
        {
            StreamReader reader;
            if (physicalPath != null)
            {
                using (reader = Util.ReaderFromFile(physicalPath, base.CurrentVirtualPath))
                {
                    this.ParseReader(reader, virtualPath);
                    return;
                }
            }
            using (Stream stream = virtualPath.OpenFile())
            {
                reader = Util.ReaderFromStream(stream, base.CurrentVirtualPath);
                this.ParseReader(reader, virtualPath);
            }
        }
        finally
        {
            this._circularReferenceChecker.Remove(o);
        }
    }
}
于 2012-08-13T12:51:23.860 回答