I've searched around and have not been able to find an good solution. I have a custom extension to a PlaceHolder control that will contain expressions that I would like to take the string output of without having to call control.Render(), since that call automatically writes the contents out to the page.
Does anybody know how to get the would be rendered content into a string and prevent the page from containing it?
The often-regurgitated, slightly dated code for this goes something like:
public string RenderControl(Control ctrl)
{
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);
ctrl.RenderControl(hw);
return sb.ToString();
}
Related
Is there any Possibility that it can Generate Compressed HTML from the GridVIew ???
I do not suggest to do that, but I can give an idea for how I will try to do that:
You can render the GridView in a string, make the compression and then show it to the page.
TextWriter stringWriter = new StringWriter();
HtmlTextWriter GrapseMesaMou = new HtmlTextWriter(stringWriter);
cGridView.RenderControl(GrapseMesaMou);
// this is the string that you show on page (eg place it on a literal)
string cFinalResults = CompressHtml(stringWriter.ToString());
// not show it any more...
cGridView.Visible = false;
one html compressor: http://code.google.com/p/htmlcompressor/
I do not know if this can work smoothly for all cases, but you can give it a try to see if it is what you look for.
Can ASCX or ASP.net files be saved as HTML files? if so, how?
yes, it is possible, to get the rendered content of a User Control, do the following :
StringWriter output = new StringWriter();
Page pageHolder = new Page();
UserControl viewControl = (UserControl)pageHolder.LoadControl("path to ascx file");
pageHolder.Controls.Add(viewControl);
HttpContext.Current.Server.Execute(pageHolder, output, true);
string htmlOutput = output.ToString();
Am sure you can adapt the above for ASPX page if required :-)
From there, saving that to a file should be fairly straight forward.
HTH.
D
You can do this directly with the Render method of a Page or UserControl. Since the method is protected, you will need to create a control that subclasses either. From there, you've got access to do whatever you need.
e.g.
public partial class MyPage: Page
{
public string GetPageContents()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (HtmlTextWriter writer = new HtmlTextWriter(sw))
{
Render(writer);
}
return sb.ToString();
}
}
You probably wouldn't want to call this anytime before the PreRenderComplete event of the page though, since otherwise you can't be sure all child controls/events/etc have finished.
Is it possible to LoadControl in windows application?
I have email generation as web, but I want to move it to windows service for monthly newsletter.
Emails now are implemented as UserControls, in this way html person can easily modify look & feel.
Current rendering implementation looks like:
StringBuilder sb = new StringBuilder(4000);
StringWriter sw = new StringWriter(sb);
HtmlTextWriter htw = new HtmlTextWriter(sw);
Page page = new Page();
EmailTemplateBase emailCtrl = (EmailTemplateBase)page.LoadControl(
"Controls/EmailTempaltes/Template.ascx");
// Exception here
emailCtrl.DataContext = dataContext;
emailCtrl.Parameter = parameter;
emailCtrl.RenderMode = renderMode;
emailCtrl.DataBind();
emailCtrl.RenderControl(htw);
subject = emailCtrl.Subject;
string MessageText = sb.ToString().Replace("\t", "").Replace(Environment.NewLine, "");
return MessageText;
Solution for me was to call web service, which was able to generate Html from .ascx.
Pass necessary parameters to
webservice
in Webservice, Build
new Page, than LoadControl
Set all parameters
Do rendering to
StringBuilder.
You can see code in question.
instead of the LoadControl method used in asp.net, you can use Controls.Add method of the parent control. Just add a panel to be the parent then:
UserControl uc1 = new UserControl //this is your usercontrol
Panel1.Controls.Add(uc1);
I'd like to know one (or more) ways to parse the HTML page output. I'd like to detect some patterns on the HTML that will be send to the client and log some info if present.
Everything you need is in the
Page.Render
method, override it and do what you want to in there.
protected override void Render(HtmlTextWriter writer)
{
// do your stuff here
StringBuilder stringBuilder = new StringBuilder();
StringWriter stringWriter = new StringWriter(stringBuilder);
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlTextWriter); // <-- render the page into the htmlTextwriter
// the htmlTextwriter connects trough the stringWriter to the stringBuilder
string theHtml = stringBuilder.ToString(); // <---- html captured in string
//---------------------------------------------
//do stuff on theHtml here
//---------------------------------------------
writer.Write(theHtml); // <----write html with the original writer
}
It depends on what you mean by "parse" exactly, but something like the HTML Agility Pack can create an XML-like structure from an HTML document - essentially creating a proper HTML DOM data structure. You can even then convert it straight to XML, use LINQ, etc.
I'm referencing the article reference
To create a UserControl dynamically and pass it back to a page via jQuery.
When I just do a simple text in the UserControl "Hello World" everything works great... however, when I tried putting interactive controls on the control, I got the following message in my WebMethod (so the jQuery call stuff is irrelevant) (further testing showed that textboxes, and buttons cause the issue, but not labels)
Error executing child request for handler 'System.Web.UI.Page'
here's the webmethod:
[WebMethod]
public static string GetCtrl(string cname)
{
StringWriter sw = new StringWriter();
Page p = new Page();
Control c = p.LoadControl("~/Controls/" + cname);
p.Controls.Add(c);
try
{
HttpContext.Current.Server.Execute(p, sw, false);
}
catch (Exception err)
{
return err.Message;
}
sw.Close();
return sw.ToString();
}
The exception is happening during the Server.Execute call.
A solution may not be possible, I'd just like to know why interactive controls cause this.
EDIT:
Taking advice below I looked deeper and found the inner exception said something to the effect that it must be within a form tag marked with runat="server", while I'm displaying this control on a aspx page within the form tag... my guess is that there's got to be some sort of 'asp.net magic' connection there for the control to operate... regardless, it'd be nice to know how to render a page with controls on it anyway (even if it wasn't usable in this situation)
So I looked at the output of the above code and for those curious:
<span id="ctl00_lbl1">abc: </span>
So the control is rendering properly (with just the label id='lbl1') on the page, however, the control is itself rendered, and the page content is not there at all... Is there a way to generate the page source as well? (I must not understand the way the Server.Execute function works)
I'd start by narrowing down the problem. For instance, what happens if you leave off the
p.Controls.Add(c);
What happens if you properly implement a using statement?
using (StringWriter sw = new StringWriter()) {
// ...
HttpContext.Current.Server.Execute(p, sw, false);
return sw.ToString();
}
What happens, if you leave off the try/catch? It's costing you all the information in the exception other than the Message property, so why not just leave it off? Your caller might be expecting HTML in any case, so if you keep it, you might (later) want to wrap the output:
return "<p>" + ex.ToString() + "</p>";
Little by little, remove things until the problem goes away.
Based on what you learned from the InnerException, I recommend that you add an HtmlForm control to the page, then add your loaded control as a child control of the HtmlForm.
Using Scott Gu's blog as a reference, I also came across the same problem loading server controls in my widgets (e.g. GridView and RadTreeView controls would cause the same error) for our company's dashboard. Following John Saunders's tip, I added an HTML form control and script manager control (for RadTreeView controls) and it fixed the problem. Now my user controls render out as pure HTML. w00t!
[WebMethod]
public static string[] LoadWidget(string widgetID, string widgetPath)
{
try
{
var pageHolder = new Page();
var form = new HtmlForm();
var viewControl = (UserControl)pageHolder.LoadControl(widgetPath);
var scriptManager = new ScriptManager();
form.Controls.Add(scriptManager);
form.Controls.Add(viewControl);
pageHolder.Controls.Add(form);
var output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return new string[]
{
widgetID, output.ToString()
};
}
catch (Exception e)
{
// handle error...
}
}
I would try rendering the control and sending that string back...
Control ctrl;
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);
ctrl.RenderControl(hw);
return sb.ToString();