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?
How to use ASP.Net server controls inside of Substitution control?
4.9k Views Asked by mhmd AtThere are 3 best solutions below

One thing Micah's answer left out is that the substitution function must be static
, accept a HttpContext
parameter, and return a string
. See this msdn page for more info.
I've also extended Micah's helper class to be a little more flexible.
Markup
<asp:Substitution ID="Substitution1" MethodName="myFunction" runat="server" />
Implemenation
public static string myFunction(HttpContext httpContext){
ViewManager vm = new ViewManager();
//example using a Button control
Button b = new Button();
b.Text = "click me"; //we can set properties like this
//we can also set properties with a Dictionary Collection
Dictionary<string,object> data = new Dictionary<string,object>();
data.add("Visible",true);
String s = vm.RenderView(b,data); //don't do anything (just for example)
//we can also use this class for UserControls
UserControl myControl = vm.GetUserControl("~mypath");
data.clear();
data.add("myProp","some value");
return vm.RenderView(myControl,data); //return for Substitution control
}
Class
using System.IO;
using System.ComponentModel;
public class ViewManager
{
private PageForRenderingUserControl pageHolder;
public ViewManager()
{
pageHolder = new PageForRenderingUserControl();
}
public UserControl GetUserControl(string path)
{
return (UserControl)pageHolder.LoadControl(path);
}
public string RenderView(Control viewControl, Dictionary<string, object> data)
{
pageHolder.Controls.Clear();
//Dim viewControl As UserControl = DirectCast(pageHolder.LoadControl(Path), UserControl)
if (data != null) {
Type viewControlType = viewControl.GetType();
dynamic properties = TypeDescriptor.GetProperties(viewControl);
foreach (string x in data.Keys) {
if ((properties.Item(x) != null)) {
properties.Item(x).SetValue(viewControl, data[x]);
}
}
}
pageHolder.Controls.Add(viewControl);
StringWriter result = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, result, false);
return result.ToString();
}
private class PageForRenderingUserControl : Page
{
public override void VerifyRenderingInServerForm(Control control)
{
// Do nothing
}
public override bool EnableEventValidation {
get { return false; }
// Do nothing
set { }
}
}
}
Thanks again to Micah for the code

I'm fairly certain you can't do this - the Substitution control will only allow you to insert a string into an outputcached page.
This makes sense if you think about the whole output of a server control, which could be a <table>
that'll disrupt all your carefully crafted markup and/or something that requires a load of <script>
injected into the page - whereas injecting a single string is something that's relatively straightforward.
UPDATE This is now a fully working example. There a few things happening here:
Here's the markup:
Here's the callback
Here's the helper class to render the user control
See these related questions: