I have a td that I want to inject with a server image control (asp.net) using innerHTML = "". The webcontrol's toString is giving the type.
Is there a way to extract the generated from the server control?
Or, is there a different solution...?
Thanks
StringBuilder sb = new StringBuilder();
StringWriter writer = new StringWriter(sb);
img.RenderControl(new HtmlTextWriter(writer));
td.InnerHtml = sb.ToString();
or the more obvious
td.Controls.Add(img);
You can use the RenderControl method to get the output HTML.
Ex:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
class Program
{
static void Main()
{
var img = new Image();
var hw = new HtmlTextWriter(Console.Out);
img.RenderControl(hw);
hw.Dispose();
}
}
Output:
<img src="" style="border-width:0px;" />
The first part of your question looks like you're asking how to inject an image at runtime into a table cell.
If the table cell is part of your ASP.NET page, you could do something like:
<td id="imageCell" runat="server"/>
In your code behind:
Image img = new Image();
img.ImageUrl = "mypic.jpg";
imageCell.Controls.Add(img);
Related
I'm using a pretty simple HtmlGenericControl code that just add CSS dynamically in my code behind
and it gives me object reference not set to an instance of an object which as you see clearly not null
HtmlGenericControl style = new HtmlGenericControl();
style.TagName = "style";
style.Attributes.Add("type", "text/css");
style.InnerHtml = "header{"+ imagePath +";}";
Page.Header.Controls.Add(style);
On which line does it throw the exception? Which object is the offending one? Add a breakpoint to your code and let us know. Could it be that imagePath is not set up correctly?
Update:
I just created a brand new C# WebForms project and added the following to the Page_Load method of Default.aspx.cs and then inspected the source and it does exactly what you'd expect:
var imagePath = "contentHere";
HtmlGenericControl style = new HtmlGenericControl();
style.TagName = "style";
style.Attributes.Add("type", "text/css");
style.InnerHtml = "header{" + imagePath + ";}";
Page.Header.Controls.Add(style);
This is added to the end of the head tag of my HTML page:
<style type="text/css">header{contentHere;}</style>
To confirm, I have the following using statements on the page:
using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
I am using string builder class to display an image but the image is not coming
My code is
StringBuilder sb1 = new StringBuilder();
sb1.AppendLine("<tr>");
string url = "<img src='~/images/youtube.png'/>";
sb1.AppendLine("<td style='padding-top:3px;border:solid 1px orange;text-
align:center'><a href='http://www.linkedin.com/groups/
'><img src=url style='height:55px;width:220px;border-style:solid; padding-
left:50px/></a></td>");
sb1.AppendLine("</tr>");
This is a much better way, not messing with any of the strings, much cleaner.
Server side:
Table tbl = new Table();
TableRow tr = new TableRow();
TableCell td = new TableCell();
td.Controls.Add(new Image
{
ImageUrl = "http://www.your-site.com/content/images/pic.jpg"
});
tr.Cells.Add(td);
tbl.Rows.Add(tr);
ph.Controls.Add(tbl);
aspx page:
<asp:PlaceHolder runat="server" ID="ph" />
I thing the problem is with in the line
sb1.AppendLine("<td style='padding-top:3px;border:solid 1px orange;text-
align:center'><a href='http://www.linkedin.com/groups/QuickMove-Core-Business-Solutions-
Moving-3791901'><img src=url style='height:55px;width:220px;border-style:solid; padding-
left:50px/></a></td>");
use it like this
sb1.AppendLine("<td style='padding-top:3px;border:solid 1px orange;text-
align:center'><a href='http://www.linkedin.com/groups/QuickMove-Core-Business-Solutions-
Moving-3791901'><img src="+url+" style='height:55px;width:220px;border-style:solid; padding-
left:50px/></a></td>");
Edit
change
string url = "<img src='~/images/youtube.png'/>";
to
string url = "/images/youtube.png";
You have to assign this html to your page element. You need server accessible html element to assign the html to it. You can make a table server accessible by assigning id to it and setting runat = "server".
In html
<table id="tbl" runat="server" >
</table>
In Code bahind
tbl.InnerHTML = sb1.ToString();
Using ASP.NET...
I have an email button on a popup extender and would like to use the inner html of another aspx page to use for the body, then edit a couple tags before it is sent. Is this possible?
Basically I'm using the .Net.Mail.MailMessage to create an HtmlBody and want to grab the html of another page (without actually rendering the page) as opposed to recreating it in a string.
You will need to create an instance of the Page that you want the html from. After that you can use the Page's Render method (see below example about this being protected) to have it generate the html that would normally be sent to the browser to a HtmlTextWriter.
When you create the HtmlTextWriter, you can use a combination of StringBuilders and TextWriters in order to get the html from the HtmlTextWriter. Something like this.
StringBuilder SB = new StringBuilder();
StringWriter SW = new StringWriter(SB);
HtmlTextWriter htmlTW = new HtmlTextWriter(SW);
MyPage page = new MyPage(); // your page here
page.RenderHtml( htmlTW ); //You need to create this method in your page, see below
string html = SB.ToString();
So the only problem is that Page.Render is protected. You will need to expose a method in your Page class that is public that calls the Render method.
Something like this should work for that method
public void RenderHtml( HtmlTextWriter htmlTextWriter )
{
Render( htmlTextWriter );
}
Hope this helps.
First of all creating html emails doesn't allow for complicated html (internal,external styling, and other controls) see...
Html Email Guidline.
So what I did was use the following to create an html string for emailing...
1) Create a simple .htm file as a template, formatting everything in standard html tables (not asp:tables), and other standard html tags.
2) Only use in-line styling if necessary.
3) Then create replacable text words or phrases to replace. You can also use a comment to replace text or for adding to a table see markup below
<span style="font-size: 16px;">TodaysDate</span>
<table id="PeopleTable" border="1" cellpadding="3" cellspacing="0" width="720">
<tr style="font-weight: bold;">
<td width="100">
First Name
</td>
<td width="100">
Last Name
</td>
<td width="100">
Phone Number
</td>
</tr>
<!--AddRowsHere-->
</table>
4) Then from a button in code behind you need to get the .htm page as string and replace the text with values you want
Using sr As New System.IO.StreamReader(Server.MapPath("PeoplePage.htm"))
GetHtml = sr.ReadToEnd
End Using
GetHtml = Replace(GetHtml, "TodaysDate", Now.ToShortDateString)
5) Return this string to the .Net.Mail.MailMessage.Body and send it out as you normally would. Make sure to set MailMesage.IsBodyHtml = True
You could also create the entire string using StringBuilder without using a template.
If you put the content of your email into a server control, you can render it as a string.
public static string GetRenderedHtml(this Control control)
{
StringBuilder sbHtml = new StringBuilder();
using (StringWriter stringWriter = new StringWriter(sbHtml))
using (HtmlTextWriter textWriter = new HtmlTextWriter(stringWriter))
{
control.RenderControl(textWriter);
}
return sbHtml.ToString();
}
If you have any editable controls (TextBox, DropDownList, etc), you'll need to replace them with Labels. See the following post for a full example and explanation.
http://jrummell.com/send-a-completed-form-email-without-a-stringbuilder
I have a table on my ASP.net page something like this:
<table runat="server" id="resultsTable"></table>
I dynamically add content to the table, and it works just fine. However, I want to get the HTML of the table once I've added the dynamic content, i.e. something like this (formatting isn't important, I've just added it)
<table runat="server" id="resultsTable">
<tr>
<td>Hello!</td>
</tr>
<tr>
<td>Goodbye!</td>
</tr>
</table>
I need the result as a string. Obviously I could do some looping and build my own table with the data, but I'd prefer to not do that if at all possible.
Initially I though to just use the InnerHtml or InnerText methods, but these are not supported on the HtmlTable class.
So what if we use the Render method? Something like this (take from Anatoly Lubarsky)?
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();
}
This method could obviously be cleaned up to handle closing the writers, etc.
Since your table is a server control, you may use its RenderControl method to obtain the render result:
public static string GetRenderResult(Control control) {
using(StringWriter sw = new StringWriter(CultureInfo.InvariantCulture)) {
using(HtmlTextWriter writer = new HtmlTextWriter(sw))
control.RenderControl(writer);
sw.WriteLine();
return sw.ToString();
}
}
There is a couple of way I can think of how to do this. The easy would be to surround the table in a . Then on your vb/C# side simply call hold.innerhtml and it will return a string.
I used the following in the OnLoad method of my page to convert your table to a string of HTML:
string html;
using (var writer = new StringWriter())
using (var xmlwriter = new HtmlTextWriter(writer))
{
this.resultsTable.RenderControl(xmlwriter);
html = writer.ToString();
}
Hmm. I'd javascript the table markup to some hidden field (which is a server control) before the form gets posted.
<div id="tablediv">
<table>...</table>
</div>
javascript:
var html = document.getElementById('tablediv').innerHTML;
document.getElementById('hfTableHtml').value = html;
EDIT: And yes, I'd worry about the request validation that is going to happen! You'd have to disable it or substitute those markup elements w/ something else before storing it into the hidden field
Look into the HTMLAgilityPack (several SO posts reference it.)
Setting the src attribute of an IFrame to data:application/pdf;base64, isn't working for me, any ideas why?
Here's the .aspx markup
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript">
function loadIFrameFromHiddenField()
{
//get the node containing the base64 pdf data from the xml in the hidden field
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.loadXML(document.getElementById("pdfData").value);
xmlDoc.setProperty('SelectionLanguage', 'XPath');
var pdfDataNode = xmlDoc.selectSingleNode("//PDF");
//if we've got the node
if (pdfDataNode != null)
{
//get the data and append it to the src contents
var pdfIFrameSrc = "data:application/pdf;base64," + pdfDataNode.text;
//set the src attribute
document.getElementById("pdfIFrame").setAttribute("src", pdfIFrameSrc);
}
}
</script>
</head>
<body>
<form id="form1" runat="server" style="width:100%;height:100%;">
<asp:HiddenField ID="pdfData" runat="server" />
<div style="width:100%;height:80%;">
<iframe id="pdfIFrame" runat="server" scrolling="auto" frameborder="0" marginheight="0" marginwidth="0" style="height:99.5%;width:99.5%" />
</div>
</form>
</body>
</html>
and here's the code behind:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Text;
using System.Xml;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//get the bytes from our PDF
Byte[] pdfBytes = File.ReadAllBytes("c:\\temp\\Test.pdf");
//build xml containiing our base64 encoded pdf data and put it in hidden field
pdfData.Value = buildDocumentXML(pdfBytes, "TestDoc");
//call js function to add the src to the iframe
String scriptText = "<script type='text/javascript'>loadIFrameFromHiddenField()</script>";
ClientScript.RegisterStartupScript(this.GetType(), "loadIFrameFromHiddenField", scriptText);
}
private string buildDocumentXML(Byte[] pdfBytes, string documentName)
{
StringBuilder documentsString = new StringBuilder();
XmlWriterSettings documentsXmlSettings = new XmlWriterSettings();
documentsXmlSettings.Indent = false;
documentsXmlSettings.OmitXmlDeclaration = true;
documentsXmlSettings.ConformanceLevel = ConformanceLevel.Fragment;
documentsXmlSettings.NewLineHandling = NewLineHandling.None;
using (XmlWriter documentsXmlWriter = XmlWriter.Create(documentsString, documentsXmlSettings))
{
documentsXmlWriter.WriteStartElement("DOCUMENTS");
documentsXmlWriter.WriteStartElement("FILENAME");
documentsXmlWriter.WriteString(documentName);
documentsXmlWriter.WriteEndElement();
documentsXmlWriter.WriteStartElement("PDF");
documentsXmlWriter.WriteBase64(pdfBytes, 0, pdfBytes.Length);
documentsXmlWriter.WriteEndElement();
documentsXmlWriter.WriteEndElement();
}
return documentsString.ToString();
}
}
I should say unlike in this example, in the real app, the pdf data is generated serverside. The reason I'm trying to load the pdf data clientside is I have to have the pdf byte data clientside anyway to do something else with and I'm trying to reduce instances of this data being generated and chucked around.
Just stick the above code and markup into a simple one page website in VS2005 and stick any old pdf in c:\temp\, call it TestDoc.pdf and it should compile and run.
Basically the behaviour I'm getting is nothing in the iframe at all.
I'm using IE7 so that might be a problem. I don't know since there's precious little information about using the data:application/pdf;base64[base64 data] syntax around.
It may be tacky to reference wikipedia, but Wikipdia says that there may be some restrictions on which filestypes you are allowed to use the data:filetype;base64 syntax on. Namely, only pictures for now. The IE9 spec, the article says, allows for broader use, but I'm not sure what exactly that entails. In the meantime, you'll just have to use the .pdf file and not just it's base 64 string data.
this way worked for me :
var oldsrc = $('.content-control-iframe').attr('src');
var newsrc = $('.content-control-iframe').attr('src').slice(8);
$('.content-control-iframe[src="'+oldsrc+'"]').attr('src', newsrc);
As far as I know, IE doesn't handle the data: URL scheme at all, so I guess, it doesn't know what to pass to the PDF viewer. See WP.
Cheers,