Tridion ASCX DCP does not render child control
Asked Answered
F

1

5

When publishing dynamic component presentations using SDL Tridion 2011 SP1, I mostly use REL as the output format, however I now want to publish a DCP that contains an ASP.NET control tag. I therefore changed the output format of the template to ASCX, and configured the storage for ASCX component presentations to go to the file system within my web application. I can see the ascx files on disk, and as expected, I can see the control tag inside.

If I create an aspx page that contains the same control tag, the output is as I expect, however, when the ASCX component presentation is executed by the component presentation assembler, instead of rendering the output from the control tag, it comes up blank. Plain text within the DCP does show up.

The functionality I need is very similar to a Tridion Dynamic Component link control, and I had already tried one of these with this architecture, and succeeded. I've even gone as far as putting both my tag and the tridion one, one after the other, in the template. In this case I see the output from the tridion tag, but not from my own, even though the references are wired up in the same web.config.

So I can see that it is possible to have Tridion's component presentation assembler execute an ASCX DCP and successfully render its child controls. Are there perhaps requirements when authoring such a control to ensure that it can be rendered in this way?

UPDATE:

The DCP is published to an ascx file within my site. For test purposes, I am now publishing the tridion control in the same DCP, so the output on disk looks like this:

<tridion:DynamicComponentLink PageURI="tcm:34-667-64" ComponentURI="tcm:34-876" 
           TemplateURI="tcm:34-864-32" LinkText="Some page" runat="server" />
<xxx:ComponentLinkQS runat="server" ComponentUri="tcm:34-945" 
                                   QueryString="item=876" Text="Some page" />

When the DCP is published like this, and executed by the ComponentPresentationAssembler the first control produces the expected output, and the second one doesn't. If I place a <xxx:ComponentLinkQS/> tag directly on an ASPX page, it renders fine.

Ferdinande answered 1/2, 2013 at 14:10 Comment(2)
Have you tried writing a simple "hello world" control to see if there might be some issues with your new linking control being executed without being directly on a page?Perithecium
Are the ASCX DCPs stored inside the web application?Raymonraymond
F
7

I think that I've seen this before (full credit for the solution goes to Neil Gibbons and Hoang Chu).

The problem is caused by the ComponentPresentation server control inside the Tridion.ContentDelivery DLL and in particular the way this control loads in the DCP user control during it's Render method:

protected override void Render(HtmlTextWriter writer)
{
    if (HttpContext.Current != null && HttpContext.Current.Application != null)
    {
        ComponentPresentationAssembler componentPresentationAssembler = new ComponentPresentationAssembler(this.pageUri, base.Page);
        writer.Write(componentPresentationAssembler.GetContent(this.componentUri, this.templateUri));
        base.RenderChildren(writer);
    }
}

The Render method is too late in the control life-cycle for any other controls to have their events wired up - hence my user controls Page_load is never triggered.

There is a solution proposed for this on the Tridion forums on the link below which involves overriding the standard Content Delivery user controls to execute your embedded controls earlier in the life cycle: https://forum.tridion.com/topic.asp?TOPIC_ID=5709&whichpage=3&SearchTerms=Page_Load (I am not sure about the legalities of copying code from the forums and adding it here. If someone from Tridion gives me the nod then I can add it in.)

Fernand answered 1/2, 2013 at 15:15 Comment(1)
Hi Jonathon, Thanks for the pointer (Hoang is a former colleague and an ace hacker!) Unfortunately, his solution is for a different problem. I think it's related to the control life-cycle. As far as I know, the ComponentPresentationAssembler loads the ASCX from disk, and then renders it. Should that work for the child controls, or do they have to be explicitly wired up as well? You'll see from my update to the question that a Tridion control executed the same way works. I wish I knew what was different.Ferdinande

© 2022 - 2024 — McMap. All rights reserved.