Path issue with wkhtmltopdf.exe to convert HTML file to PDF - asp.net

I am using wkhtmltopdf to convert HTML file into PDF document on a link Button
http://code.google.com/p/wkhtmltopdf/
When User Click on a link Button it runs the following code as shown below code in pass file path as an argument ProcessStartInfo. THis code works fine in Following Scenarios only
Taking Into consideration that website is hosted on Domain http://www.xyz.net/
When i mention path as http://demo.XYZ.net/ It works fine
When i mention path as http://www.XYZ.net/ It doesn't work
In-case of local-host it works fine if path is http://localhost:51005/XYZ/or http://web:8080/
For this to work properly we need to give the website full trust level & i am not sure why code doesn't run i give it the same domain path if i create put PrintArticle.aspx if i create a sub domain then it will work fine. I am nost sure if this is a security problem or what
Code Below
protected void lnkbtnDownload_Click(object sender, EventArgs e)
{
//ConvertURLToPDF();
try
{
string url = "PrintArticle.aspx?articleID=" + Request["articleID"] + "&download=yes&Language=" + Request["Language"];
//string args = string.Format("\"{0}\" - ", "http://demo.XYZ.net/" + url); //Works
//string args = string.Format("\"{0}\" - ", "http://www.xyz.net/" + url); Doesnt work
//string args = string.Format("\"{0}\" - ", url);
string args = string.Format("\"{0}\" - ", "http://localhost:51005/XYZ/" + url); //Works
var startInfo = new ProcessStartInfo(Server.MapPath("bin\\wkhtmltopdf.exe"), args)
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
var proc = new Process { StartInfo = startInfo };
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
byte[] buffer = proc.StandardOutput.CurrentEncoding.GetBytes(output);
proc.WaitForExit();
proc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=download.pdf");
Response.BinaryWrite(buffer);
Response.End();
}
catch (Exception ex)
{
throw ex;
}
}
Error Message in case file is on same domain
Server Error in '/' Application. The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its
dependencies) could have been removed, had its name changed, or is
temporarily unavailable. Please review the following URL and make sure
that it is spelled correctly.
Requested URL: /PrintArticle.aspx
Version Information: Microsoft .NET Framework Version:4.0.30319;
ASP.NET Version:4.0.30319.272

I resolved this issue by using the following statement
var url = Request.Url.GetLeftPart(UriPartial.Authority) + "/PrintArticle.aspx?articleID=" + Request["articleID"] + "&download=yes&Language=" + Request["Language"];
Now it is working fine i am not sure what it doesn't work when i specify the file path.

output variable contains empty string
my code as follows:
try
{
string url=Request.Url.GetLeftPart(UriPartial.Authority) +"/PrintQuickPrescription.aspx?DoctorId=" + DoctorID + "&DispnID=" + DispnID + "&ApptID=" + ApptID + "&PatientID=" + PatientID;
System.Diagnostics.Process process = new System.Diagnostics.Process();
string args = string.Format("\"{0}\" - ", "http://localhost:50013/DPMNewWeb/"+url);
//string args="http://localhost:50013/DPMNewWeb/PrintQuickPrescription.aspx";
var startInfo = new ProcessStartInfo(Server.MapPath("~\\Bin\\wkhtmltopdf.exe"), args)
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
var proc = new Process { StartInfo = startInfo };
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
byte[] buffer = proc.StandardOutput.CurrentEncoding.GetBytes(output);
proc.WaitForExit();
proc.Close();
Response.ContentType = "application/pdf";
Response.BinaryWrite(buffer);
Response.End();
//byte[] fileContent = GeneratePDFFile();
//GeneratePDFFile();
//if (fileContent != null)
//{
// Response.Clear();
// Response.ContentType = "application/pdf";
// Response.AddHeader("content-length", fileContent.Length.ToString());
// Response.BinaryWrite(fileContent);
// Response.End();
//}
}
catch
{
}

Related

download a file from asp.net api in xamarin form? [duplicate]

I am trying to save a file to the client's machine. I want to require the client to pick the location of the download.
I have endpoint of the REST service which returns the file to be downloaded. I am trying to set up the code to download the file thats returned from the service with save as dialog.
var Url = "https://randomaddresss/v5/invoices/{" + InvoicesId + "}/getpdfbyid";
HttpResponse response = HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", "attachment; filename=" + InvoicesId + ".pdf;");
response.TransmitFile(Url);
response.Flush();
response.End();
The error thats returned is on the line response.TransmitFile(Url); :
'https:/randomaddresss/v5/invoices/2131231231231312/getpdfbyid'
is not a valid virtual path.
HttpResponse.TransmitFile expects a file path, not a URL.
You will need to download the file first, then write to the response stream.
Here's an example using HttpClient:
using var invoiceResponse = await httpClient.GetAsync(Url);
using var invoiceStream = await invoiceResponse.Content.ReadAsStreamAsync();
invoiceStream.CopyTo(response.OutputStream);
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", "attachment; filename=" + InvoicesId + ".pdf;");
JS:
function downloadPdfInvoice(iId) {
$.ajax({
url: '/api/DownloadInvoice?Invoice=' + iId,
type: 'get',
success: function (response, status) {
if (response) {
var link = document.createElement('a');
link.href = "data:application/octet-stream;base64," + response.Data;
link.target = '_blank';
link.download = iId + '.pdf';
link.click();
}
},
});
}
CS:
[HttpGet]
public ApiResponse DownloadInvoiceAsync(string InvoicesId)
{
try
{
String Url = "https://test/{" + InvoicesId + "}/getpdfinvoice";
HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create(Url);
var resp = fileReq.GetResponse();
Stream input = resp.GetResponseStream();
byte[] data = input.ReadAsBytes();
return new ApiResponse(true, "Downloadet til skrivebordet.", data);
}
catch (Exception ex)
{
Logger.Warn(MethodBase.GetCurrentMethod().DeclaringType,
string.Format("DownloadInvoice Exception {0}", ex.Message));
throw ex;
}
}

HTTP POST receiving more than one HTTP Response

I have an http POST being actioned via a .NET System.Net.WebRequest as follows:
...
XXXUtilities.Log.WriteLog(string.Format("XXXHTTPPost PostToUri has uri={0}, body={1}", uri, messageBodyAsString));
System.Net.WebRequest req = System.Net.WebRequest.Create(uri);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(messageBodyAsString);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
try
{
using (System.Net.WebResponse resp = req.GetResponse())
{
if (resp == null) return null;
System.IO.StreamReader sr =
new System.IO.StreamReader(resp.GetResponseStream());
string rs = sr.ReadToEnd().Trim();
sr.Close();
resp.Close();
XXXUtilities.Log.WriteLog(string.Format("XXXHTTPPost PostToUri has string response = {0}", rs));
MongoDB.Bson.BsonDocument doc2 = new BsonDocument();
doc2.Add("Response", rs);
return doc2;
}
}
catch (System.Net.WebException e)
{...
This all works fine most of the time. However, looking at the log files that this creates I spotted something strange. The suspect log entries look like this:
18:59:17.0608 HPSHTTPPost PostToUri has uri=https://salesforce.ringlead.com/cgi-bin/2848/3/dedup.pl, body=LastName=Doe&FirstName=Jon
18:59:17.5608 HPSHTTPPost PostToUri has string response = Success
18:59:18.0295 HPSHTTPPost PostToUri has string response = Success
It seems that the Http Response is being received twice. Is this even technically possible? i.e. is it possible for an Http POST to receive two Responses, one after the other? If so, is my code below then liable to be called twice, thus resulting in the observed log file entries? Many thanks.
Edit:
In response to the comment that the logging code may be broken, here is the logging code:
public class Log
{
public static void WriteLog(string commandText)
{
string clientDBName = "test";
string username = "test";
try
{
string filePath = "c:\\Data\\XXXLogs\\" + clientDBName + "logs\\";
string filename = System.DateTime.Now.ToString("yyyyMMdd_") + username + ".log";
DirectoryInfo dir = new DirectoryInfo(filePath);
if (!dir.Exists)
{
dir.Create();
}
System.IO.FileStream stream = new System.IO.FileStream(
filePath + filename
, System.IO.FileMode.Append); // Will create if not already exists
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine(); // Writes a line terminator, thus separating entries by 1 blank line
writer.WriteLine(System.DateTime.Now.ToString("HH:mm:ss.ffff") + " " + commandText);
writer.Flush();
stream.Close();
}
catch { }
}
}

asp.net upload control is not working in ipad

The asp.net upload control is uploading the file for first time in Ipad but not after that and not even showing any error
The code is as below
protected void UploadThisFile(FileUpload upload)
{
try
{
string folderpath = ConfigurationManager.AppSettings["BTCommDynamic"].ToString() + ConfigurationManager.AppSettings["Attachments"].ToString();
Guid fileguid = Guid.NewGuid();
string filename = fileguid + upload.FileName;
if (upload.HasFile && dtFiles != null)
{
DataRow drFileRow = dtFiles.NewRow();
drFileRow["FileName"] = upload.FileName;
string theFileName = Path.Combine(Server.MapPath(folderpath), filename);
string theFileName1 = Path.Combine(folderpath, filename);
//string theFileName = folderpath;
//to save the file in specified path
upload.SaveAs(theFileName);
drFileRow["FilePath"] = theFileName1;
double Filesize = (upload.FileContent.Length);
if (Filesize > 1024)
{
drFileRow["FileSize"] = (upload.FileContent.Length / 1024).ToString() + " KB";
}
else
{
drFileRow["FileSize"] = (upload.FileContent.Length).ToString() + " Bytes";
}
dtFiles.Rows.Add(drFileRow);
gvAttachment.DataSource = dtFiles;
gvAttachment.DataBind();
}
}
catch (Exception ex)
{
string message = Utility.GetExceptionMessage(ex.GetType().ToString(), ex.Message);
Display_Message(message);
}
}
Do you use firebug? There might be an error on a client side that prevents the work of your functionality.
Do you have any logic on your client side? Some kinda jquery/ajax calls?

Getting Error when using response.write()

I need to save a file as .csv in client machine. I am using the code below.
protected void btnGen_Click(object sender, EventArgs e)
{
try
{
string fileName = "test";
string attachment = "attachment; filename=" + fileName + ".csv";
List<string> lst1 = new List<string> { "wert", "fds", "hjgfh", "hgfhg" };
List<string> lst2 = new List<string> { "hgfds", "hdfg", "yretg", "treter" };
List<string> lst3 = new List<string> { "hgfdgf", "gfdg", "gfdgf", "ghfdg" };
List<List<string>> lst = new List<List<string>> { lst1, lst2, lst3 };
StringBuilder sb = new ExportFacade().GenerateStringBuilder(lst);
Response.ContentType = "text/csv" ;
lblProgress.ForeColor = System.Drawing.Color.Green;
lblProgress.Text = "File created and write successfully!";
HttpContext.Current.Response.AddHeader("content-disposition", attachment);
Response.Write(sb.ToString());
lblProgress.ForeColor = System.Drawing.Color.Green;
lblProgress.Text = "File created and write successfully!";
Response.Flush();
Response.End();
}
catch (Exception ex)
{
lblProgress.ForeColor = System.Drawing.Color.Red;
lblProgress.Text = "File Saving Failed!";
}
}
I am not using update panels.
When I click on the button I get the following error
Sys.WebForms.PageRequestManagerParserErrorException: The message
received from the server could not be parsed. Common causes for this
error are when the response is modified by calls to Response.Write(),
response filters, HttpModules, or server trace is enabled.
It will be a great help to me if you can help me to get rid of this problem.
thank you.
I solved it. Ajax script manager in the master page has created the problem. After removing it, the function worked properly. But labels are not being updated as response is not for the page.

Problem downloading a 25MB file - the 8MB file downloads without problem (ASP.NET)

I have two files at the same location but the big one, when is about to finish download, gives an error (both in IE and Firefox).
I use the following code:
public static void DownloadZipFile (string filename, bool notifyMe)
{
HttpContext context = HttpContext.Current;
HttpServerUtility server = context.Server;
bool ok = false;
try
{
string file = string.Format ("~/contents/licensing/members/downloads/{0}", filename);
string server_file = server.MapPath (file);
HttpResponse response = context.Response;
//response.BufferOutput = false;
response.ContentType = "application/zip";
string value = string.Format ("attachment; filename={0}", filename);
response.AppendHeader ("Content-Disposition", value);
FileInfo f = new FileInfo (server_file);
long size = f.Length;
response.TransmitFile (server_file, 0, size);
response.Flush ();
ok = true;
response.End ();
}
catch (Exception ex)
{
Utilities.Log (ex);
}
finally
{
if (ok && notifyMe)
NotifyDownload (filename);
}
}
Any ideas?
Response.End() calls Response.Flush(). Try removing the Flush call.
The solution to this problem is to add the line:
response.AddHeader("Content-Length",size.ToString());
before the call to TransmitFile ().
The credits go to Jim Schubert (see his comment above).

Resources