Search code examples
asp.netcachingsubstitutionwebformsdonut-caching

How to use ASP.Net server controls inside of Substitution control?


while the method we use in Substitution control should return strings, so how is it possible to use a donut caching in web forms on a server control which should be rendered server side?
for example Loginview control?


Solution

  • UPDATE This is now a fully working example. There a few things happening here:

    1. Use the call back of a substitution control to render the output of the usercontrol you need.
    2. Use a custom page class that overrides the VerifyRenderingInServerForm and EnableEventValidation to load the control in order to prevent errors from being thrown when the usercontrol contains server controls that require a form tag or event validation.

    Here's the markup:

    <asp:Substitution runat="server" methodname="GetCustomersByCountry" />
    

    Here's the callback

    public string GetCustomersByCountry(string country)
    {
       CustomerCollection customers = DataContext.GetCustomersByCountry(country);
    
        if (customers.Count > 0)
            //RenderView returns the rendered HTML in the context of the callback
            return ViewManager.RenderView("customers.ascx", customers);
        else
            return ViewManager.RenderView("nocustomersfound.ascx");
    }
    

    Here's the helper class to render the user control

    public class ViewManager
    {
        private class PageForRenderingUserControl : Page
        {
            public override void VerifyRenderingInServerForm(Control control)
            { /* Do nothing */ }
    
            public override bool EnableEventValidation
            {
                get { return false; }
                set { /* Do nothing */}
            }
        }
    
        public static string RenderView(string path, object data)
        {
            PageForRenderingUserControl pageHolder = new PageForUserControlRendering();
            UserControl viewControl = (UserControl) pageHolder.LoadControl(path);
    
            if (data != null)
            {
                Type viewControlType = viewControl.GetType();
                FieldInfo field = viewControlType.GetField("Data");
                if (field != null)
                {
                    field.SetValue(viewControl, data);
                }
                else
                {
                    throw new Exception("ViewFile: " + path + "has no data property");
                }
            }
    
            pageHolder.Controls.Add(viewControl);
            StringWriter result = new StringWriter();
            HttpContext.Current.Server.Execute(pageHolder, result, false);
            return result.ToString();
        }
    }
    

    See these related questions: