Render HtmlGenericControl from a HttpHandler - c#

I have a set of code (noted below) in ProcessRequest(HttpContext context) in a generic handler .ashx file.
HtmlGenericControl holder = new HtmlGenericControl("div");
//Set holder's properties and customization
HtmlGenericControl button1 = new HtmlGenericControl("input");
//Set button1's properties and customization
holder.Controls.Add(button1);
HtmlGenericControl button2 = new HtmlGenericControl("input");
//Set button2's properties and customization
holder.Controls.Add(button2);
HtmlGenericControl button2 = new HtmlGenericControl("input");
//Set button2's properties and customization
holder.Controls.Add(button2);
Now as I am in a HttpHander, I want to get the HTML of holder control and write it through context.Respose.Write().
Please help me through this.
Thanks in advance
Munim

I have figured out the way by myself.
using (StringWriter stringWriter = new StringWriter())
{
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
holder.RenderControl(htmlTextWriter);
HttpContext.Response.Write(stringWriter.ToString());
htmlTextWriter.Close();
stringWriter.Close();
}

Related

Unable to find control with id when using the panel RenderControl Method

I am trying to dynamically create a form in asp.net and render it out on the page by performing a text replace on the rendered controls.
(I cannot just push the controls to a panel on the page, that would be the ideal situation and I wouldn't be having this problem right now)
I create a label, textbox and a button and add them all to a panel. This panel is then rendered into a string using a TextWriter, which I then to use perform my replace on my copy.
Label lbl = new Label();
lbl.Text = "Enter Amount";
lbl.Attributes.Add("style", "width:25%; vertical-align:middle;");
lbl.CssClass = "donate-label";
lbl.ID = "lblAmount";
TextBox tb = new TextBox();
tb.ID = "tbAmount";
tb.Attributes.Add("style", "padding-left:25px; width:50%;");
lbl.AssociatedControlID = tb.ID;
Button b = new Button();
b.ID = "btnDonate";
b.Text = "Make a Donation";
b.CssClass="block-btn right-arrow red-bg right";
b.Click += new EventHandler(btnDonate_Click);
b.Attributes.Add("style", "display:table-cell; margin-top:0; width:40% !important;");
Panel pnlForm = new Panel();
pnlForm.CssClass="form clearfix donate-form";
pnlForm.Attributes.Add("style", "width:70%");
pnlForm.Controls.Add(lbl);
pnlForm.Controls.Add(tb);
pnlForm.Controls.Add(b);
Now if I was to add the above panel to a panel that already existed on the page, it would work perfectly and as expected, but the control rendering is causing it to break somewhere..
TextWriter myTextWriter = new StringWriter();
HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter);
pnlForm.RenderControl(myWriter);
string body = p.Copy.Replace("##donate##", myTextWriter.ToString());
The error I get is as follows:
Unable to find control with id 'tbAmount' that is associated with the Label 'lblAmount'.
Line 146: pnlForm.RenderControl(myWriter);
If I removed the assoicatedControlID for my label it works fine, but unfortunately it renders my label as a span which isn't what I need, I need it rendered as a label with a 'for' attribute.
The easiest way is to use literal with html tags inside it
Literal lbl = new Literal();
lbl.Text = "<Label For='tbAmount' style='width:25%; vertical-align:middle;' class='donate-label' > Enter Amount </label>";
lbl.ID = "lblAmount";
by the way make the tbAmount id static so you dont get any unpredictable id for your textbox
tb.ClientIDMode= System.Web.UI.ClientIDMode.Static

Artificially firing Page Events in ASP.NET?

I'm working with a static class in C#, and am trying to use Control.RenderControl() to get a string / mark-up representation of a Control.
Unfortunately the control (and all child controls) use event bubbling to populate certain values, for example, when instantiating, then calling RenderControl() on the following:
public class MyTest : Control
{
protected override void OnLoad(EventArgs e)
{
this.Controls.Add(new LiteralControl("TEST"));
base.OnLoad(e);
}
}
I am returned an empty string, because OnLoad() is never fired.
Is there a way I can invoke a 'fake' page lifecycle? Perhaps use some dummy Page control?
I was able to accomplish this by using a local instance of Page and HttpServerUtility.Execute:
// Declare a local instance of a Page and add your control to it
var page = new Page();
var control = new MyTest();
page.Controls.Add(control);
var sw = new StringWriter();
// Execute the page, which will run the lifecycle
HttpContext.Current.Server.Execute(page, sw, false);
// Get the output of your control
var output = sw.ToString();
EDIT
If you need the control to exist inside a <form /> tag, then simply add an HtmlForm to the page, and add your control to that form like so:
// Declare a local instance of a Page and add your control to it
var page = new Page();
var control = new MyTest();
// Add your control to an HTML form
var form = new HtmlForm();
form.Controls.Add(control);
// Add the form to the page
page.Controls.Add(form);
var sw = new StringWriter();
// Execute the page, which will in turn run the lifecycle
HttpContext.Current.Server.Execute(page, sw, false);
// Get the output of the control and the form that wraps it
var output = sw.ToString();

Loading a user control dynamically

I'm trying to load a user control in a web service, but it doesn't execute the Load_Page().
I tried to use:
HttpContext.Current.Server.Execute(page, text, false);
But it returns a NullException. It is my code:
public string Controle(string url)
{
Page page = new Page();
UserControl userControl = (UserControl)page.LoadControl(url);
//userControl.EnableViewState = false;
HtmlForm form = new HtmlForm();
form.Controls.Add(userControl);
page.Controls.Add(form);
StringWriter text = new StringWriter();
HtmlTextWriter htmltext = new HtmlTextWriter(text);
userControl.RenderControl(htmltext);
return text.ToString();
}
Hope it is clear.
You need to initialize the control using a method that does something like
this.Load += Page_Load;
Please refer to this post which explains exactly what needs to be done to achieve this. Be sure to read the section stating; "One word of caution:"
http://weblogs.asp.net/srkirkland/archive/2007/11/05/dynamically-render-a-web-user-control.aspx
This related post will also be able to assist:
Page_Load not firing in UserControl

Load a silverlight to aspx page through code behind

I need to load a silverlight application in a portion of an aspx page on a button click on that page page. Some init parameters need to be passed to the silverlight application based on the user inputs on the host page on button click. How to do that?
I presume I need to create the silverlight object from code-behind to set custom InitParameters. Any idea how to do that?
Extending to what is mentioned here, you can do something like this:
HtmlGenericControl myHtmlObject = new HtmlGenericControl("object");
myHtmlObject.Attributes["data"] = "data:application/x-silverlight-2";
myHtmlObject.Attributes["type"] = "application/x-silverlight-2";
myHtmlObject.Attributes["width"] = "100%";
myHtmlObject.Attributes["height"] = "100%";
this.Page.Controls.Add(myHtmlObject);
HtmlGenericControl mySourceParam = new HtmlGenericControl("param");
mySourceParam.Attributes["name"] = "source";
mySourceParam.Attributes["value"] = "ClientBin/MySilverlightApplication.xap";
myHtmlObject.Controls.Add(mySourceParam);
HtmlGenericControl myOnErrorParam = new HtmlGenericControl("param");
myOnErrorParam .Attributes["name"] = "onError";
myOnErrorParam .Attributes["value"] = "onSilverlightError";
myHtmlObject.Controls.Add(myOnErrorParam);
HtmlGenericControl myInputParam = new HtmlGenericControl("param");
myOnErrorParam .Attributes["name"] = "InitParameters";
myOnErrorParam .Attributes["value"] = "param1=Hello,param2=World";
myHtmlObject.Controls.Add(myInputParam);
this.Page.Controls.Add(myHtmlObject);

Render User Control and Fire Control Events

I'm trying to load a user control in code and store the output as a string variable. At the moment I've got the below code:
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
WidgetControlBase widget = (WidgetControlBase)LoadControl("/controls/mycontrol.ascx");
widget.RenderControl(htw);
The problem is that the RenderControl method doesn't fire any of the control events so anything I add in the control Page_Load doesn't happen.
I've tried loading the control in a PlaceHolder and then rendering the PlaceHolder like so:
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
WidgetControlBase widget = (WidgetControlBase)LoadControl("/controls/mycontrol.ascx");
myPlaceholder.Controls.Add(widget);
myPlaceholder.RenderControl(htw);
However this seems to do the same as just using RenderControl direct on the control, it doesn't fire any events either.
Is there a way I can get a string containing the contents of my control while still firing the control events?
I think you are trying to render the control at the wrong point in the pages life cycle. Try moving the code from Page_Load to PreInit like so:
protected override void OnPreInit(EventArgs e)
{
//custom code
base.OnPreInit(e);
}
Detailed information about the page life cycle can be found here:
http://www.codeasp.net/articles/asp.net/20/aspnet-page-lifecycle

Categories

Resources