London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

Dynamic Content rendering outside of EPiServer Property

Vote:
 

I am trying to get my dynamic content to render in a page that uses a PropertyDataCollection instead of an EPiServer property.  Initially it was just rendering the Dynamic Content control itself instead of the content.  I found the following page that explains how to get around this issue but I am encountering a runtime exception with this method.  

http://tedgustaf.com/sv/blogg/2009/9/parse-an-episerver-xhtml-property-with-dynamic-content/

I get a null reference error on the call to SetupControl() within GetRenderedXHTMLText below when rendering Dynamic Content.  Here is the relevant code...

1- As we iterate over the properties, output the content...

protected void OnItemDatabound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        PropertyXhtmlString pd = (PropertyXhtmlString)e.Item.DataItem;
        var litContent = (Literal)e.Item.FindControl("litContent");
        //For each property, attempt to get the rendered output
        litContent.Text = GetRenderedXhtmlText(pd);
    }
}

2- Try to render the content.  This method works fine for any property that doesn't have a dynamic content control in it.

public static string GetRenderedXhtmlText(PropertyXhtmlString content)
{
    // Create a Property control which will parse the XHTML value for us
    PropertyXhtmlStringControl ctrl = new PropertyXhtmlStringControl();// PropertyLongStringControl();

    // Set the PropertyData to the property we want to parse
    ctrl.PropertyData = content;

    // Initialize the Property control
    ctrl.SetupControl();//***Fails with null reference error on dynamic content***
    
// Create a string writer... StringWriter sw = new StringWriter(); // ...and an HtmlTextWriter using that string writer HtmlTextWriter htw = new HtmlTextWriter(sw); // Render the Property control to get the markup ctrl.RenderControl(htw); // Return the parsed markup return sw.ToString(); }

My dynamic content is a user control decorated with the DynamicContentPlugin attribute.

3- Here is my custom editor user control

public partial class NewsListCustomEditor : DynamicContentEditControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                txtTags.Text = Content.Properties["TagList"].Value as string;
                IList<string> tagList = txtTags.Text.Split(new string[] { "$" }, StringSplitOptions.RemoveEmptyEntries);
                txtNumItems.Text = Content.Properties["NumberOfItemsPerPage"].Value as string;
            }
        }

        public override void PrepareForSave()
        {
            Content.Properties["TagList"].Value = txtTags.Text;
            Content.Properties["NumberOfItemsPerPage"].Value = txtNumItems.Text;
            Content.Properties["DynamicContentDisplayMode"].Value = true;
        }
    }

4- Here are the relevant parts of the dynamic content user control itself

[DynamicContentPlugIn(
        DisplayName = "The Title",
        Description = "Widget to do stuff",
        ViewUrl = "~/Absolute path to this control...",
        Url = "~/Absolute path to custom editor control",
        Area = PlugInArea.DynamicContent)]
    public partial class NewsList : UserControlBase
    {
... body of control, do stuff, get data etc.

public Control GetControl(PageBase hostPage)
        {
            //try
            //{
                if(hostPage==null)
                    hostPage=(HttpContext.Current.Handler as PageBase); 
                //Return dynamic content controls
                return (NewsList)hostPage.LoadControl("~/Templates/Responsive/Controls/NewsList.ascx");
            //}
        }

        #endregion
        

        private static string GetPropertyString(string PropertyName, PageData pageData)
        {
            return pageData[PropertyName] as string ?? String.Empty;
        }

Well, sorry for the long post, but would like to get this working and have no idea what is missing from my dynamic content control that makes SetupControl fail...

Any ideas?

#73941
Aug 14, 2013 18:29
Vote:
 

Here is the stack trace for the exception.  This only happens when it encounters a dynamic content control...

[NullReferenceException: Object reference not set to an instance of an object.]
   EPiServer.DynamicContent.DynamicContentAdapter`1.GetControl(PageBase hostPage) +236
   EPiServer.Core.Html.StringParsing.DynamicContentFragment.GetControl(PageBase hostPage) +66
   EPiServer.Web.PropertyControls.PropertyLongStringControlBase.CreateDefaultControls() +455
   EPiServer.Web.PropertyControls.PropertyDataControl.CreateChildControls() +173
   System.Web.UI.Control.EnsureChildControls() +102
   EPiServer.Web.PropertyControls.PropertyDataControl.SetupControl() +31
   EPiServer.Web.PropertyControls.PropertyLongStringControl.SetupControl() +110
   *.Web.Templates.Public.Pages.LandingPage.GetRenderedXhtmlText(PropertyXhtmlString content)
   *.Web.Templates.Public.Pages.LandingPage.OnItemDatabound(Object sender, RepeaterItemEventArgs e)
   System.Web.UI.WebControls.Repeater.OnItemDataBound(RepeaterItemEventArgs e) +115

 
#73968
Aug 15, 2013 17:33
Vote:
 

bump

#74009
Aug 16, 2013 23:12
Vote:
 

I actually figured this out.  Basically I was just decorating the UserControl with the DynamicContent attributes but this wasn't enough.  I had to implement IDynamicContent for EPiServer to recognize GetControl method.

#74374
Aug 26, 2013 18:50
This thread is locked and should be used for reference only. Please use the Episerver CMS 7 and earlier versions forum to open new discussions.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.