5

I have a load of UserControl objects (ascx files) in their own little project. I then reference this project in two projects: The REST API (which is a class library project) and the main website.

I'm sure this would be easy in the website, simply use Controls.Add in any Panel or ASP.NET control would work.

However, what about the API? Is there any way I can render the HTML of this control, simply by knowing the type of the control? The RenderControl method doesn't write any HTML to the writer as the control's life cycle hasn't even started.

Please bare in mind that I don't have the controls in the web project, so I don't have a virtual path to the ascx file. So the LoadControl method won't work here.

All the controls actually derive from the same base control. Is there anything I can do from within this base class that will allow me to load the control from a completely new instance?

1 Answer 1

8

This is what I have done recently, works well, but understand postbacks will not work if you use it inside your ASP.NET app.

 [WebMethod]
 public static string GetMyUserControlHtml()
 {
     return  RenderUserControl("Com.YourNameSpace.UI", "YourControlName");
 }

 public static string RenderUserControl(string assembly,
             string controlName)
 {
        FormlessPage pageHolder = 
                new FormlessPage() { AppRelativeTemplateSourceDirectory = HttpRuntime.AppDomainAppVirtualPath }; //allow for "~/" paths to resolve

        dynamic control = null;

        //assembly = "Com.YourNameSpace.UI"; //example
        //controlName = "YourCustomControl"
        string fullyQaulifiedAssemblyPath = string.Format("{0}.{1},{0}", assembly, controlName);

        Type type = Type.GetType(fullyQaulifiedAssemblyPath);
        if (type != null)
        {
            control = pageHolder.LoadControl(type, null);
            control.Bla1 = "test"; //bypass compile time checks on property setters if needed
            control.Blas2 = true;

        }                          

        pageHolder.Controls.Add(control);
        StringWriter output = new StringWriter();
        HttpContext.Current.Server.Execute(pageHolder, output, false);
        return output.ToString();
 }


public class FormlessPage : Page
{
    public override void VerifyRenderingInServerForm(Control control)
    {
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Looking good rick. Just trying to implement that now in my structure. One thing I've noticed though - HtmlForm form = new HtmlForm();. This variable is never used, because form.Controls.Add is commented out? Am I missing something?
I will update, there is a way to do with a regular form, but if your control doesn't have a form tag or you don't add one programatically, you will get a runtime error. That is what the FormLessPage class bypasses for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.