使用模板的自定义控件允许子控件HTML响应被操纵

时间:2015-11-30 10:58:18

标签: asp.net custom-controls

我正在尝试创建一个使用ITemplate的ASP.NET自定义控件,允许开发人员在其中放置自己的内部ASP / HTML控件。控件的目的是解析模板内容的呈现HTML,并使用上下文特定值搜索/替换可能出现的某些占位符文本(例如[Location],[Division],[FirstName])。

我正在努力如何“捕获”生成的HTML,并在转出响应对象之前根据需要“替换”它们。

我的想法是使用RenderContents(HtmlTextWriter output)将输出替换为我自己的流并获取控件来写入。然后,我可以在发送到output之前执行我需要对渲染内容执行的操作。

但是,我不确定这是否是正确的方法。

以下是我所拥有的片段:

/// <summary>
/// This custom control allows replacement fields to be picked up
/// </summary>
[DefaultProperty("Text")]
[ToolboxData("<{0}:ReplaceableText runat=\"server\" Text=\"[Text]\"></{0}:ReplaceableText>")]
public partial class ReplaceableText : WebControl
{
    public ReplaceableText()
    {
        TokenReplacer = new TokenReplacer();
    }

    [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [TemplateInstance(TemplateInstance.Single)]
    public ITemplate Content { get; set; }

    /// <summary>
    /// The component the performs the replacement
    /// </summary>
    /// <remarks>
    /// An alternative TokenReplacer component could be installed by the caller if required.
    /// More typically, you will use the AddResolver(s) methods to apply callbacks to do the
    /// actual replacement.
    /// </remarks>
    public ITokenReplacer TokenReplacer { get; set; }



    public bool HasTokenReplacer { get { return (TokenReplacer != null && !DesignMode); } }


    protected override void RenderContents(HtmlTextWriter output)
    {
        System.Diagnostics.Debug.WriteLine("RenderContents() enter");

        if (HasTokenReplacer)
        {
            using (var memStream = new MemoryStream())
            {
                using (var sw = new StreamWriter(memStream))
                {
                    using (var htw = new HtmlTextWriter(sw))
                    {
                        base.RenderContents(htw);
                    }
                }
                // !! memStream is still empty (0 bytes) !!

                var text = Encoding.UTF8.GetString(memStream.GetBuffer());
                var text2 = TokenReplacer.Convert(text);
                output.Write(text2);
            }
        }
        else
        {
            base.RenderContents(output);
        }

        output.Write(ConvertedText);
        System.Diagnostics.Debug.WriteLine("RenderContents() exit");
    }


    protected override void CreateChildControls()
    {
        if (Content != null)
        {
            Controls.Clear();
            Content.InstantiateIn(this);    // !!! I need this to write to my own alternative temporary stream 
        }
        base.CreateChildControls();
    }

不幸的是,我似乎没有将任何标记存入我的记忆流。

1 个答案:

答案 0 :(得分:0)

我是傻香肠,我没有对我的Contents ITemplate进行任何控制。 此解决方案似乎运行良好,如果您发现Controls.Count > 0最终为0字节,请确保检查MemoryStream

相关问题