Setting the src attribute of an IFrame to data:application/pdf;base64? - asp.net

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,

Related

how do you populate sql query result in a textbox or input control like google search dropdown result

i'm doing a small project for a friend any help would be great thank you in advance.
i have a textbox however i can use a html input control as well.
same idea as google bar where you able to type a letter a which will return any description match with letter a. It would show matching values underneath the inut control same as goodle search bar.
Any ideas how to do this code example C# would be great thank you.
You could use jQuery and an HTTP handler
Download jQuery(If you don't already have it)
Download autocomplete.js
Download jquery.autocomplete.css
Copy the files to your project.Mine are in sub folders called Scripts and Style
SQL:
For the sake of example I've created a local database called Search which has one table with two columns SearchId and Search to store some dummy search data
ASPX:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Auto complete</title>
<script src="Scripts/jquery-1.7.1.js" type="text/javascript"></script>
<link href="Style/jquery.autocomplete.css" rel="stylesheet" type="text/css" />
<script src="Scripts/jquery.autocomplete.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#txtSearch").autocomplete("Autocomplete.ashx");
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input id="txtSearch" type="text" />
</div>
</form>
</body>
</html>
Autocomplete.ashx handler:
using System;
using System.Data.SqlClient;
using System.Web;
namespace WebApplication17
{
public class Autocomplete : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string connectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["connection"].ConnectionString;
string input = context.Request.QueryString["q"];
string query = "SELECT TOP 10 Search FROM Search WHERE Search LIKE '" + input + "%'";
using (var conn = new SqlConnection(connectionString))
{
using (var command = new SqlCommand(query,conn))
{
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
context.Response.Write(reader.GetString(0) + Environment.NewLine);
}
}
}
}
public bool IsReusable
{
get{return false;}
}
}
}
Output:
I've placed the zipped version of the project on Google Drive.Hope this helps!

Generic Handler not getting called in asp.net

I am trying to display an image from my database. I have an generic handler to display the image. But my problem is that it doesn't get called. My code for calling the handler is
Image1.ImageUrl = "~/ShowImage.ashx?id=" + id;
where id is a number and ShowImage.ashx is the handler. The breakpoints in .ashx file doesn't get hit either. I am new to asp.net. So any help would be highly appreciated.
In this cases the steps that you need to follow is to see how the html is rendered.
So, right click on the html page, and "view page source".
There locate the point that the ShowImage.ashx is called, and see if the full rendered path is correct.
From there you simple correct the path.
Additional you can use the browser tools to see what browser looks for, and if he finds it or not. On google chrome for example you make right click, then inspect elements and then click on the network. There you can see with red, what files your page can not find, and you need to fix the path.
Check this sample Example code this might help you.
ASPX Code :
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>
HTTP Handler class Impliment in Img tag
</h1>
<h1>Id : 1</h1>
<img src="ImageHandler.ashx?id=1" alt="Dynamic Image" />
<h1>Id : 2</h1>
<img src="ImageHandler.ashx?id=2" alt="Dynamic Image" />
</div>
</form>
</body>
</html>
C# Examples (ImageHandler.ashx File) :
<%# WebHandler Language="C#" Class="ImageHandler" %>
using System;
using System.Web;
public class ImageHandler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
//context.Response.ContentType = "text/plain";
//context.Response.Write("Hello World");
context.Response.ContentType = "image/jpeg";
if (context.Request.QueryString["id"] == "1")
{
context.Response.WriteFile("bamboo.jpg");
}
else
{
context.Response.WriteFile("palmtree.jpg");
}
}
public bool IsReusable {
get {
return false;
}
}
}
Here is live downloadable C# Examples and VB.Net Examples of this. Click Here...

Why can't the attribute imageurl in the image tag not accept an absolute path?

I'm using two image tags. In one the used path is relative and in the other it is absolute. The absolute path image is not shown. Here is the code:
Expt_Image2.aspx page:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Expt_Image2.aspx.cs" Inherits="Expt_Image2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Image
ID="Image1"
runat="server"
ImageUrl="~/Image/Bluehills.jpg"
Height="100"
Width="100"/>
<asp:Image
ID="Image2"
runat="server"
ImageUrl="C:\Documents and Settings\Lovey\My Documents\Visual Studio 2008\WebSites\Expt-New\Image\Sunset.jpg"
Height="100"
Width="100"/>
</div>
</form>
</body>
</html>
Expt_Image2.aspx.cs:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.IO;
public partial class Expt_Image2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string[] files = Directory.GetFiles(MapPath("~/Image/"));
Image im = new Image();
im.ImageUrl = files[1];
im.AlternateText = files[1];
form1.Controls.Add(im);
}
}
The first error that in your Page_Load method you get your image and store it in array. In C# indexes of items in arrays start from 0, not from 1.
Second, you must specify the virtual path to the property ImageUrl of the Image control.
It is the right Page_Load method:
protected void Page_Load(object sender, EventArgs e)
{
string[] files = Directory.GetFiles( MapPath( "~/Image/" ) );
Image im = new Image();
im.ImageUrl = "~/Image/" + Path.GetFileName( files[ 0 ] );
im.AlternateText = files[ 0 ];
im.Height = 100;
im.Width = 100;
form1.Controls.Add( im );
}
Doesn't MapPath return the physical location of the file. In your case something like C:\inetpub\wwwroot\mysite\image
Whereas you would want the virtual path eg. http://mysite/image/image1.png
Something like this should work:
DirectoryInfo di = new DirectoryInfo(MapPath("~/Image/"));
FileInfo[] files = di.GetFiles();
Image im = new Image();
im.ImageUrl = "~/Image/" + files[0].Name;
im.AlternateText = "~/Image/" + files[0].Name;
form1.Controls.Add(im);
Use the application path,
Request.ApplicationPath + "~/Image/"
This will fix the problem.
One more thing. You don't need to put "~" before the path.

ASP.NET :Show background process status to User

I have a web page where it will input an excel/CSV file from the user and read the data from it and import to DB.While inserting each record.I just want to show the details about the record being inserted to the user.(Ex : Client Details of A is adding...)
Try this... Set the output to unbuffered (Response.BufferOutput), and include some javascript in your page that updates the UI as you see appropriate. For example, it might update a SPAN with a percentage complete or the details of the record you are processing. Then in your server code, output <script> tags that call the Javascript function from the Render override. Make sure you call Flush() at the appropriate times, and also Flush the base code after it Renders... The JS function calls should get sent down at the appropriate times and executed on the client, resulting in an updating page.
For example... Your HTML page might look like this:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<script type="text/javascript">
function UpdateScreen(t) {
document.getElementById('output').innerHTML = t;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id='output'></div>
</div>
</form>
</body>
</html>
<script type="text/javascript">
UpdateScreen('hello');
</script>
and your codebehind will look like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void Render(HtmlTextWriter writer)
{
Response.BufferOutput = false;
base.Render(writer);
Response.Flush();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
Response.Write(string.Format("<script type='text/javascript'>UpdateScreen('{0}');</script>", i * 10));
Response.Flush();
}
}
}
}
I know this is an old question, and the owner of it may have moved on a long time ago. Anyway:
The proposed solution will not work on ASP.NET MVC. And if you ask me, which you don't, I'll say this is not the cleanest solution to the problem:
Here's a jQuery one,
And here's an IFrame one.

How to add a server image control to html container using innerHTML =

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);

Resources