Welcome to AspAdvice Sign in | Join | Help

Render User Control as String Template

Scott Guthrie has a great example of how to use an ASP.NET user control as a template which one can dynamically bind to data and then pull the results out as a string.  One place this is useful is in AJAX scenarios in which you want to replace the contents of a region of the page with the rendered output of a user control.  I'm using this very successfully in Lake Quincy Media AdSignia for our dashboard pages, to enable me to load the page instantly and then dynamically fetch the individual charts and dashboard controls asynchronously via ASP.NET AJAX.  I'll be writing up a full article on this whole process soon, but for now I just want to show my version of ScottGu's ViewManager class, which has been modified to use generics and interfaces to make it a bit more cohesive (it also no longer uses reflection).  The user control must now implement a generic interface, IRenderable<T>, where T is the data it expects to be passed in.

    public class ViewManager
    {
        public static string RenderView<D>(string path, D dataToBind)
        {
            Page pageHolder = new Page();
            UserControl viewControl = (UserControl) pageHolder.LoadControl(path);
            if(viewControl is IRenderable<D>)
            {
                if (dataToBind != null)
                {
                    ((IRenderable<D>) viewControl).PopulateData(dataToBind);
                }
            }
            pageHolder.Controls.Add(viewControl);
            StringWriter output = new StringWriter();
            HttpContext.Current.Server.Execute(pageHolder, output, false);

            return output.ToString();
        }
    }

    public interface IRenderable<T>
    {
        void PopulateData(T data);
    }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

 

A user control implementing this interface might look like this:

    public partial class View_PublisherEarningsChart : System.Web.UI.UserControl, IRenderable<DataSet>
    {
        protected DataSet chartData;
        protected void Page_Load(object sender, EventArgs e)
        {
            BindPublisherEarningsChart();
        }
        public void BindPublisherEarningsChart()
        {
          // Bind chart here
        }

        #region IRenderable<DataTable> Members
        public void PopulateData(DataSet data)
        {
            chartData = data;
        }
        #endregion
    }

With this approach, it's easy to separate the data access from the rendering, and is very similar to the Model-View-Controller (MVC) approach that is getting a lot of press time lately in the ASP.NET world.  Again, I'll show the full dynamic loading async stuff very soon in a full article.

Published Friday, October 19, 2007 1:27 PM by ssmith
Filed under: , ,

Comments

New Comments to this post are disabled