I'm using this tutorial https://web.archive.org/web/20211020001747/https://www.4guysfromrolla.com/articles/030211-1.aspx that’s uses a PDF template, lets the user input fields using textbox's. The file downloads onto the client’s pc but I would like to save a copy of the file into a sql database also or just save the file in the database instead of both.
protected void btnGeneratePDF_Click(object sender, EventArgs e)
{
var pdfPath = Path.Combine(Server.MapPath("~/PDFTemplates/fw9.pdf"));
// Get the form fields for this PDF and fill them in!
var formFieldMap = PDFHelper.GetFormFieldNames(pdfPath);
formFieldMap["topmostSubform[0].Page1[0].f1_01_0_[0]"] = txtName.Text;
formFieldMap["topmostSubform[0].Page1[0].f1_02_0_[0]"] = txtBusinessName.Text;
if (rblTaxClassification.SelectedValue != null)
{
var formFieldName = string.Format("topmostSubform[0].Page1[0].c1_01[{0}]", rblTaxClassification.SelectedIndex);
formFieldMap[formFieldName] = (rblTaxClassification.SelectedIndex + 1).ToString();
}
if (chkExemptPayee.Checked)
formFieldMap["topmostSubform[0].Page1[0].c1_01[7]"] = "8";
formFieldMap["topmostSubform[0].Page1[0].f1_04_0_[0]"] = txtAddress.Text;
formFieldMap["topmostSubform[0].Page1[0].f1_05_0_[0]"] = txtCityStateZIP.Text;
formFieldMap["topmostSubform[0].Page1[0].f1_07_0_[0]"] = txtAccountNumbers.Text;
// Requester's name and address (hard-coded)
formFieldMap["topmostSubform[0].Page1[0].f1_06_0_[0]"] = "Acme Website\n123 Anywhere Lane\nSpringfield, USA";
// SSN
if (!string.IsNullOrEmpty(txtSSN1.Text))
{
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField1[0]"] = txtSSN1.Text;
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[0]"] = txtSSN2.Text;
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[1]"] = txtSSN3.Text;
}
else if (!string.IsNullOrEmpty(txtEIN1.Text))
{
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[2]"] = txtEIN1.Text;
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[3]"] = txtEIN2.Text;
}
var pdfContents = PDFHelper.GeneratePDF(pdfPath, formFieldMap);
PDFHelper.ReturnPDF(pdfContents, "Completed-W9.pdf");
FileStream fs = new FileStream(pdfPath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
br.Close();
fs.Close();
//insert the file into database
string strQuery = "insert into tblFiles(Name, ContentType, Data) values (#Name, #ContentType, #Data)";
SqlCommand cmd = new SqlCommand(strQuery);
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = "Completed-W9132.pdf";
cmd.Parameters.Add("#ContentType", SqlDbType.VarChar).Value = "application/pdf";
cmd.Parameters.Add("#Data", SqlDbType.Binary).Value = bytes;
InsertUpdateData(cmd);
App_code/pdfHelper.cs
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.IO;
using iTextSharp.text.pdf;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public class PDFHelper
{
public static Dictionary<string, string> GetFormFieldNames(string pdfPath)
{
var fields = new Dictionary<string, string>();
var reader = new PdfReader(pdfPath);
foreach (DictionaryEntry entry in reader.AcroFields.Fields)
fields.Add(entry.Key.ToString(), string.Empty);
reader.Close();
return fields;
}
public static byte[] GeneratePDF(string pdfPath, Dictionary<string, string> formFieldMap)
{
var output = new MemoryStream();
var reader = new PdfReader(pdfPath);
var stamper = new PdfStamper(reader, output);
var formFields = stamper.AcroFields;
foreach (var fieldName in formFieldMap.Keys)
formFields.SetField(fieldName, formFieldMap[fieldName]);
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
return output.ToArray();
}
// See http://stackoverflow.com/questions/4491156/get-the-export-value-of-a-checkbox-using-itextsharp/
public static string GetExportValue(AcroFields.Item item)
{
var valueDict = item.GetValue(0);
var appearanceDict = valueDict.GetAsDict(PdfName.AP);
if (appearanceDict != null)
{
var normalAppearances = appearanceDict.GetAsDict(PdfName.N);
// /D is for the "down" appearances.
// if there are normal appearances, one key will be "Off", and the other
// will be the export value... there should only be two.
if (normalAppearances != null)
{
foreach (var curKey in normalAppearances.Keys)
if (!PdfName.OFF.Equals(curKey))
return curKey.ToString().Substring(1); // string will have a leading '/' character, so remove it!
}
}
// if that doesn't work, there might be an /AS key, whose value is a name with
// the export value, again with a leading '/', so remove it!
var curVal = valueDict.GetAsName(PdfName.AS);
if (curVal != null)
return curVal.ToString().Substring(1);
else
return string.Empty;
}
public static void ReturnPDF(byte[] contents)
{
ReturnPDF(contents, null);
}
public static void ReturnPDF(byte[] contents, string attachmentFilename)
{
var response = HttpContext.Current.Response;
if (!string.IsNullOrEmpty(attachmentFilename))
response.AddHeader("Content-Disposition", "attachment; filename=" + attachmentFilename);
response.ContentType = "application/pdf";
response.BinaryWrite(contents);
response.End();
}
}
The parts of the tutorial you're looking for in that case are right here:
Response.ContentType = "application/pdf";
Response.BinaryWrite(output.ToArray());
When saving a "file" to a database you essentially care about two (maybe three) things:
The byte array of the file contents
The type of the file
(Maybe a name for the file)
Since the tutorial concludes with two of these things (above), the type and the data, you can store these two things into your database however you need to store them. This depends on the database you're using, how you access that database, etc. Essentially to store these two things you just need a text column (varchar?) and a binary (or "blob") column (varbinary?).
The only difference is that instead of setting the type as a header in an HTTP response and writing the bytes to that HTTP response, you're using both of them as values in your database. Everything else is the same.
Related
I want to read a file from a FTP server without downloading it to a local file. I wrote a function but it does not work:
private string GetServerVersion()
{
WebClient request = new WebClient();
string url = FtpPath + FileName;
string version = "";
request.Credentials = new NetworkCredential(ftp_user, ftp_pas);
try
{
byte[] newFileData = request.DownloadData(new Uri(FtpPath)+FileName);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
}
catch (WebException e)
{
}
return version;
}
Here's a simple working example using your code to grab a file from the Microsoft public FTP servers:
WebClient request = new WebClient();
string url = "ftp://ftp.microsoft.com/developr/fortran/" +"README.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous#example.com");
try
{
byte[] newFileData = request.DownloadData(url);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
Console.WriteLine(fileString);
}
catch (WebException e)
{
// Do something such as log error, but this is based on OP's original code
// so for now we do nothing.
}
I reckon you're missing a slash on this line here in your code:
string url = FtpPath + FileName;
Perhaps between FtpPath and FileName ?
Small binary file
If the file is small, the easiest way is using WebClient.DownloadData:
WebClient client = new WebClient();
string url = "ftp://ftp.example.com/remote/path/file.zip";
client.Credentials = new NetworkCredential("username", "password");
byte[] contents = client.DownloadData(url);
Small text file
If the small file is a text file, use WebClient.DownloadString:
string contents = client.DownloadString(url);
It assumes that the file contents is in UTF-8 encoding (a plain ASCII file will do too). If you need to use a different encoding, use WebClient.Encoding property.
Large binary file
If the file is large, so that you need to process it in chunks, instead of loading it to memory whole, use FtpWebRequest:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream stream = request.GetResponse().GetResponseStream())
{
byte[] buffer = new byte[10240];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
// process the chunk in "buffer"
}
}
You can also simplify the code by using WebClient.OpenRead.
Large text file
If the large file is a text file and you want to process it by lines, instead of by chunks of a fixed size, use StreamReader:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.txt");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream stream = request.GetResponse().GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
// process the line
Console.WriteLine(line);
}
}
Again, this assumes UTF-8 encoding. If you want to use another encoding, use an overload of StreamReader constructor that takes also Encoding.
As previously, you can simplify the code by using WebClient.OpenRead.
Stream interface
Though, in many cases, you will want to use the downloaded data in some API that uses the Stream interface. In that case, instead of using any of the solutions above, directly use the stream returned by request.GetResponse().GetResponseStream() or WebClient.OpenRead in the API.
For an example, see Transferring files from FTP directly to Azure Blob storage in C#.
The code you have above is very simillar to another Stackoverlow example I found and used myself 2 days ago. Provided you set the URI, User and Password correctly, it will download the file and set the contents to FileString. I'm not sure what you mean by wanting to read the file without downloading it. This is not really an option.
If you want to look at file attributes (I see you mention "version"), you could use the code below to get all the file Name, Data, and Size from the FTP server without downloading the file.
Call GetFileInfo and pass in the file name (make sure you follow through the code to set the full FTP path, User and Password). This will give you back a FTPFileInfo object with a Name, Date and Size.
public static FTPFileInfo GetFileInfo(string fileName)
{
var dirInfo = WordstockExport.GetFTPDirectoryDetails();
var list = FTPFileInfo.Load(dirInfo);
try
{
FTPFileInfo ftpFile = list.SingleOrDefault(f => f.FileName == fileName);
return ftpFile;
}
catch { }
return null;
}
class FTPFileInfo
{
private DateTime _FileDate;
private long _FileSize;
private string _FileName;
public DateTime FileDate
{
get { return _FileDate; }
set { _FileDate = value; }
}
public long FileSize
{
get { return _FileSize; }
set { _FileSize = value; }
}
public string FileName
{
get { return _FileName; }
set { _FileName = value; }
}
public FTPFileInfo() { }
public static FTPFileInfo LoadFromLine(string line)
{
FTPFileInfo file = new FTPFileInfo();
string[] ftpFileInfo = line.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
file._FileDate = DateTime.Parse(ftpFileInfo[0] + " " + ftpFileInfo[1]);
file._FileSize = long.Parse(ftpFileInfo[2]);
file._FileName = ftpFileInfo[3];
return file;
}
public static List<FTPFileInfo> Load(string listDirectoryDetails)
{
List<FTPFileInfo> files = new List<FTPFileInfo>();
string[] lines = listDirectoryDetails.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach(var line in lines)
files.Add(LoadFromLine(line));
return files;
}
}
private static string GetFTPDirectoryDetails()
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(App.Export_FTPPath);
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
request.Credentials = new NetworkCredential(App.FTP_User, App.FTP_Password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string fileLines = reader.ReadToEnd();
reader.Close();
response.Close();
return fileLines;
}
It is impossible to know what the issue is without details about the error/exception.
At a guess, you do not seem to be assigning a new value to version after the initial declaration
string version = "";
Try changing your code to
version = System.Text.Encoding.UTF8.GetString(newFileData);
C Sharp GUI app. Minimal ftp transfer, not elegant but it works fine.
GUI, not console.
Weather from noaa. Find your region (look for your metar)!
A METAR weather report is predominantly used by pilots in fulfillment of a part of a pre- flight
Build with vs 2012 premium RC (july 2012)
(click on label, not button)
using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Collections.Generic;
namespace getweather
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void CYYY_Click(object sender, EventArgs e)
{
WebClient request = new WebClient();
string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYYY.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous#example.com");
byte[] newFileData = request.DownloadData(url);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
richTextBox1.Text = fileString;
}
private void CYSC_Click(object sender, EventArgs e)
{
WebClient request = new WebClient();
string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYSC.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous#example.com");
byte[] newFileData = request.DownloadData(url);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
richTextBox1.Text = fileString;
}
private void CYQB_Click(object sender, EventArgs e)
{
WebClient request = new WebClient();
string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYQB.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous#example.com");
byte[] newFileData = request.DownloadData(url);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
richTextBox1.Text = fileString;
}
private void CYUY_Click(object sender, EventArgs e)
{
WebClient request = new WebClient();
string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYUY.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous#example.com");
byte[] newFileData = request.DownloadData(url);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
richTextBox1.Text = fileString;
}
private void CYHU_Click(object sender, EventArgs e)
{
WebClient request = new WebClient();
string url = "ftp://tgftp.nws.noaa.gov/data/observations/metar/decoded/CYHU.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous#example.com");
byte[] newFileData = request.DownloadData(url);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
richTextBox1.Text = fileString;
}
}
}
WebClient request = new WebClient();
string url = "ftp://ftp.microsoft.com/developr/fortran/" +"README.TXT";
request.Credentials = new NetworkCredential("anonymous", "anonymous#example.com");
request.Proxy = null;
try
{
byte[] newFileData = request.DownloadData(url);
string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
Console.WriteLine(fileString);
}
catch (WebException e)
{
// Do something such as log error, but this is based on OP's original code
// so for now we do nothing.
}
I know this is an old question, but I thought I'd suggest using path.combine for the next guy reading this. Helps clean up these kinds of issues.
string url = Path.Combine("ftp://ftp.microsoft.com/developr/fortran", "README.TXT");
We can use below method to get the file attribute from ftp without downloading the file.This is working fine for me.
public DataTable getFileListFTP(string serverIP,string userID,string Password)
{
DataTable dt = new DataTable();
string[] fileListArr;
string fileName = string.Empty;
long fileSize = 0;
// DateTime creationDate;
string creationDate;
FtpWebRequest Request = (FtpWebRequest)WebRequest.Create(serverIP);
Request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
Request.Credentials = new NetworkCredential(userID,Password);
FtpWebResponse Response = (FtpWebResponse)Request.GetResponse();
Stream ResponseStream = Response.GetResponseStream();
StreamReader Reader = new StreamReader(ResponseStream);
dt.Columns.Add("FileName", typeof(String));
dt.Columns.Add("FileSize", typeof(String));
dt.Columns.Add("CreationDate", typeof(DateTime));
//CultureInfo c = new CultureInfo("ES-ES");
while (!Reader.EndOfStream)//Read file name
{
fileListArr = Convert.ToString(Reader.ReadLine()).Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
fileSize = long.Parse(fileListArr[4]);
creationDate = fileListArr[6] + " " + fileListArr[5] + " " + fileListArr[7];
//creationDate =Convert.ToDateTime(fileListArr[6] + " " + fileListArr[5] + " " + fileListArr[7], c).ToString("dd/MMM/yyyy", DateTimeFormatInfo.InvariantInfo);
fileName = Convert.ToString(fileListArr[8]);
DataRow drow = dt.NewRow();
drow["FileName"] = fileName;
drow["FileSize"] = fileName;
drow["CreationDate"] = creationDate;
dt.Rows.Add(drow);
}
Response.Close();
ResponseStream.Close();
Reader.Close();
return dt;
}
Take a look at my FTP class, it might be exactly what you need.
Public Class FTP
'-------------------------[BroCode]--------------------------
'----------------------------FTP-----------------------------
Private _credentials As System.Net.NetworkCredential
Sub New(ByVal _FTPUser As String, ByVal _FTPPass As String)
setCredentials(_FTPUser, _FTPPass)
End Sub
Public Sub UploadFile(ByVal _FileName As String, ByVal _UploadPath As String)
Dim _FileInfo As New System.IO.FileInfo(_FileName)
Dim _FtpWebRequest As System.Net.FtpWebRequest = CType(System.Net.FtpWebRequest.Create(New Uri(_UploadPath)), System.Net.FtpWebRequest)
_FtpWebRequest.Credentials = _credentials
_FtpWebRequest.KeepAlive = False
_FtpWebRequest.Timeout = 20000
_FtpWebRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile
_FtpWebRequest.UseBinary = True
_FtpWebRequest.ContentLength = _FileInfo.Length
Dim buffLength As Integer = 2048
Dim buff(buffLength - 1) As Byte
Dim _FileStream As System.IO.FileStream = _FileInfo.OpenRead()
Try
Dim _Stream As System.IO.Stream = _FtpWebRequest.GetRequestStream()
Dim contentLen As Integer = _FileStream.Read(buff, 0, buffLength)
Do While contentLen <> 0
_Stream.Write(buff, 0, contentLen)
contentLen = _FileStream.Read(buff, 0, buffLength)
Loop
_Stream.Close()
_Stream.Dispose()
_FileStream.Close()
_FileStream.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message, "Upload Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Public Sub DownloadFile(ByVal _FileName As String, ByVal _ftpDownloadPath As String)
Try
Dim _request As System.Net.FtpWebRequest = System.Net.WebRequest.Create(_ftpDownloadPath)
_request.KeepAlive = False
_request.Method = System.Net.WebRequestMethods.Ftp.DownloadFile
_request.Credentials = _credentials
Dim _response As System.Net.FtpWebResponse = _request.GetResponse()
Dim responseStream As System.IO.Stream = _response.GetResponseStream()
Dim fs As New System.IO.FileStream(_FileName, System.IO.FileMode.Create)
responseStream.CopyTo(fs)
responseStream.Close()
_response.Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Download Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Public Function GetDirectory(ByVal _ftpPath As String) As List(Of String)
Dim ret As New List(Of String)
Try
Dim _request As System.Net.FtpWebRequest = System.Net.WebRequest.Create(_ftpPath)
_request.KeepAlive = False
_request.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails
_request.Credentials = _credentials
Dim _response As System.Net.FtpWebResponse = _request.GetResponse()
Dim responseStream As System.IO.Stream = _response.GetResponseStream()
Dim _reader As System.IO.StreamReader = New System.IO.StreamReader(responseStream)
Dim FileData As String = _reader.ReadToEnd
Dim Lines() As String = FileData.Split(New String() {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
For Each l As String In Lines
ret.Add(l)
Next
_reader.Close()
_response.Close()
Catch ex As Exception
MessageBox.Show(ex.Message, "Directory Fetch Error: ", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return ret
End Function
Private Sub setCredentials(ByVal _FTPUser As String, ByVal _FTPPass As String)
_credentials = New System.Net.NetworkCredential(_FTPUser, _FTPPass)
End Sub
End Class
To initialize:
Dim ftp As New FORM.FTP("username", "password")
ftp.UploadFile("c:\file.jpeg", "ftp://domain/file.jpeg")
ftp.DownloadFile("c:\file.jpeg", "ftp://ftp://domain/file.jpeg")
Dim directory As List(Of String) = ftp.GetDirectory("ftp://ftp.domain.net/")
ListBox1.Items.Clear()
For Each item As String In directory
ListBox1.Items.Add(item)
Next
https://stackoverflow.com/a/28669746/2701974
I had my code to retrieve logged user details , every thing is OK but
i cannot retrieve the user image .
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = string.Format(CultureInfo.InvariantCulture, "(sAMAccountName={0})", Environment.UserName);
//SearchResult findUser = searcher.FindOne();
foreach (SearchResult findUser in searcher.FindAll())
{
if (findUser != null)
{
DirectoryEntry user = findUser.GetDirectoryEntry();
string userName = user.Properties["displayName"].Value.ToString();
string departement = user.Properties["Department"].Value.ToString();
string title = user.Properties["title"].Value.ToString();
string[] rt = new string[] { Login, userName, Email, Mobile };
Lbl_User.Text = userName;
Lbl_Administrative.Text = departement;
Lbl_Position.Text = title;
}
}
I've just taken your code and made a method out of it just to retrieve the image. You would need to refactor it, to either get only the byte[] or thw whole image.
//add this
using System.Drawing;
static Image GetPhotoFromAD(string userName)
{
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = string.Format(CultureInfo.InvariantCulture, "(sAMAccountName={0})", userName);
//SearchResult findUser = searcher.FindOne();
foreach (SearchResult findUser in searcher.FindAll())
{
if (findUser != null)
{
byte[] photodata = findUser.Properties["jpegPhoto"].Value as byte[];
using (MemoryStream str = new MemoryStream(photodata))
{
return Bitmap.FromStream(str);
}
}
}
}
If you only want the raw data, the important bit is byte[] photodata = user.Properties["jpegPhoto"].Value as byte[];
The binary image should be stored in property called thumbnailPhoto.
var photo = user.Properties["thumbnailPhoto"];
if (photo != null) {
byte[] buffer = (byte[])photo.Value;
//var bitmap = new Bitmap(new MemoryStream(buffer, false));
//bitmap.Save(#"c:\test.bmp");
}
Now, given the fact that you tagged question as asp.net you'll have to write generic handler (.ashx) for retrieving the image. This handler should write content of
photo.Value
into response output stream and set content type to image/bmp
In your control/page just reference the handler like
<img src="/GenericHandler.ashx" alt="My image" />
I have a fillable pdf. In which i have few textboxes.
I fill these fields by using following code(itextsharp).
DataTable dt = new DataTable();
String pdfPath1 = Server.MapPath("pdfs\\transmittal2.pdf");
if (File.Exists(pdfPath1))
{
dt = objClsTransmittal.GetTransmittal(jobid, cid);
String comment = "Correspondence generated for " + dt.Rows[0]["Recipient"].ToString();
var formfield = PDFHelper.GetFormFieldNames(pdfPath1);
formfield["DocDate"] = DateTime.Now.ToLongDateString();
formfield["Address1"] = dt.Rows[0]["Company"].ToString();
formfield["Address2"] = dt.Rows[0]["Address1"].ToString();
formfield["PropertyAddress"] = dt.Rows[0]["PropertyAddress"].ToString();
formfield["Job"] = dt.Rows[0]["JobID"].ToString();
formfield["Name"] = dt.Rows[0]["Recipient"].ToString();
formfield["CityStateZip"] = dt.Rows[0]["address2"].ToString();
formfield["E-mail"] = dt.Rows[0]["Email"].ToString();
var pdfcontent = PDFHelper.GeneratePDF(pdfPath1, formfield);
PDFHelper.ReturnPDF(pdfcontent, "Transmittal.pdf");
}
Currently its downloded as read only pdf.
when this pdf gets downloaded, i want that all fields still remain fillable, with the text i have filled in pdf. So that i can edit the text.
I'm looking forward for your replies.
Thanks.
EDIT
PdfHelper is my custom class. In which i have used following code:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.IO;
using iTextSharp.text.pdf;
public class PDFHelper
{
public static Dictionary<string, string> GetFormFieldNames(string pdfPath)
{
var fields = new Dictionary<string, string>();
var reader = new PdfReader(pdfPath);
foreach (DictionaryEntry entry in reader.AcroFields.Fields)
fields.Add(entry.Key.ToString(), string.Empty);
reader.Close();
return fields;
}
public static byte[] GeneratePDF(string pdfPath, Dictionary<string, string> formFieldMap)
{
var output = new MemoryStream();
var reader = new PdfReader(pdfPath);
var stamper = new PdfStamper(reader, output);
var formFields = stamper.AcroFields;
foreach (var fieldName in formFieldMap.Keys)
formFields.SetField(fieldName, formFieldMap[fieldName]);
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
return output.ToArray();
}
public static string GetExportValue(AcroFields.Item item)
{
var valueDict = item.GetValue(0);
var appearanceDict = valueDict.GetAsDict(PdfName.AP);
if (appearanceDict != null)
{
var normalAppearances = appearanceDict.GetAsDict(PdfName.N);
if (normalAppearances != null)
{
foreach (var curKey in normalAppearances.Keys)
if (!PdfName.OFF.Equals(curKey))
return curKey.ToString().Substring(1); // string will have a leading '/' character, so remove it!
}
}
var curVal = valueDict.GetAsName(PdfName.AS);
if (curVal != null)
return curVal.ToString().Substring(1);
else
return string.Empty;
}
public static void ReturnPDF(byte[] contents)
{
ReturnPDF(contents, null);
}
public static void ReturnPDF(byte[] contents, string attachmentFilename)
{
var response = HttpContext.Current.Response;
if (!string.IsNullOrEmpty(attachmentFilename))
response.AddHeader("Content-Disposition", "attachment; filename=" + attachmentFilename);
response.ContentType = "application/pdf";
response.BinaryWrite(contents);
response.End();
}
Your code line
stamper.FormFlattening = true;
instructs iTextSharp to flatten the form fields, i.e. to integrate them into the page content and remove the form field annotations.
As you want to keep the form fields as editable fields, don't flatten the form.
Error: Cannot convert type in PDFHelper.cs
public static Dictionary<string, string> GetFormFieldNames(string pdfPath)
{
var fields = new Dictionary<string, string>();
var reader = new PdfReader(pdfPath);
foreach (DictionaryEntry entry in reader.AcroFields.Fields) //ERROR: 'System.Collections.Generic.KeyValuePair' to 'System.Collections.DictionaryEntry'
{
fields.Add(entry.Key.ToString(), string.Empty);
}
reader.Close();
return fields;
}
'System.Collections.Generic.KeyValuePair' to 'System.Collections.DictionaryEntry'
[Below is the almost full Code modified. Currently shows illegal character error when being read].
I have a C# ASP.NET application which is currently reading an XML file from the file system and then loading it into a GridView control. In the grid I can Delete rows. There is also an file upload button below the grid which upload PDF files and they show up in the grid. My code is basically a modified version of this code
The next stage of my work involves reading the XML data as String from a database field--instead of from the XML file. For that to happen, I think I can start out by just reading from the XML file, making changes in the aspx page, and the writing the 'dataset' into a database field called 'PDF_Storage'. How can I do that. Crucially, I need to be able to convert the dataset into some kind of string format for storage. Here is my code snippet.
My database is Oracle 10 but I can figure out the Update sql syntax.
SAMPLE XML FILE:
<DataSet>
<PDF>
<pdf>MyPDF1.pdf</pdf>
</PDF>
<PDF>
<pdf>MyPDF2.pdf</pdf>
</PDF>
<PDF>
<pdf>MyPDF3.pdf</pdf>
</PDF>
</DataSet>
And the corresponding code:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
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 Oracle.DataAccess.Client;
using System.Web.Configuration;
using System.IO;
using System.Xml;
using System.Text.RegularExpressions;
public partial class XMLGridTest : System.Web.UI.Page
{
public static string GetConnString()
{
return WebConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
binddata();
}
}
void binddata()
{
DataSet ds = new DataSet();
// ds.ReadXml(Server.MapPath("testxml.xml"));
String strConnect = GetConnString();
OracleConnection oracleConn = new OracleConnection();
oracleConn.ConnectionString = strConnect;
oracleConn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = oracleConn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT PDF_Storage FROM CampusDev.CU_POLY WHERE OBJECTID = " + Request.QueryString["OBJECTID"];
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(0))
{
//## Line Below as the 'illegal characters' problem###
ds.ReadXml(reader[0].ToString(), XmlReadMode.IgnoreSchema);
gv.DataSource = ds;
gv.DataBind();
}
else
{
// Response.Write(reader.GetString(1));
// TextBox1.Text = reader.GetString(1);
}
}
// gv.DataSource = ds;//##Hard coded for XML. Works!
// gv.DataBind();
//Finally, close the connection
oracleConn.Close();
}
protected void Canceldata(object s, GridViewCancelEditEventArgs e)
{
gv.EditIndex = -1;
binddata();
}
protected void pageddata(object s, GridViewPageEventArgs e)
{
gv.PageIndex = e.NewPageIndex;
binddata();
}
protected void insert(object sender, EventArgs e)
{
/////////////////////////////////File Upload Code/////////////////////////////////
// Initialize variables
string sSavePath = "ParcelPDF/"; ;
if (fileupload.PostedFile == null)
{
Label1.Text = "Must Upload a PDF file!";
return;
}
HttpPostedFile myFile = fileupload.PostedFile;
int nFileLen = myFile.ContentLength;
// Check file extension (must be JPG)
if (System.IO.Path.GetExtension(myFile.FileName).ToLower() != ".pdf")
{
Label1.Text = "The file must have an extension of .pdf";
return;
}
// Read file into a data stream
byte[] myData = new Byte[nFileLen];
myFile.InputStream.Read(myData, 0, nFileLen);
// Make sure a duplicate file doesn’t exist. If it does, keep on appending an incremental numeric until it is unique
string sFilename = System.IO.Path.GetFileName(myFile.FileName);
int file_append = 0;
while (System.IO.File.Exists(Server.MapPath(sSavePath + sFilename)))
{
file_append++;
sFilename = System.IO.Path.GetFileNameWithoutExtension(myFile.FileName) + file_append.ToString() + ".pdf";
}
// Save the stream to disk
System.IO.FileStream newFile = new System.IO.FileStream(Server.MapPath(sSavePath + sFilename), System.IO.FileMode.Create);
newFile.Write(myData, 0, myData.Length);
newFile.Close();
binddata();
DataSet ds = gv.DataSource as DataSet;
DataRow dr = ds.Tables[0].NewRow();
// dr[0] = pdf.Text;
dr[0] = sFilename.ToString();
ds.Tables[0].Rows.Add(dr);
ds.AcceptChanges();
string blah = "blah";
Response.Write(ds.Tables.ToString());
// ds.WriteXml(Server.MapPath("testxml.xml"));
String strConnect = GetConnString();
OracleConnection oracleConn = new OracleConnection();
oracleConn.ConnectionString = strConnect;
oracleConn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = oracleConn;
cmd.CommandType = CommandType.Text;
// cmd.CommandText = "SELECT OBJECTID,COMMENTS FROM CampusDev.CU_POLY WHERE OBJECTID = " + Request.QueryString["OBJECTID"];
cmd.CommandText = "UPDATE CampusDev.CU_POLY SET PDF_Storage = :PDF_Storage WHERE OBJECTID = " + Request.QueryString["OBJECTID"];
StringWriter SW = new StringWriter();
ds.WriteXml(SW);
cmd.Parameters.Add(":PDF_Storage", SW.ToString());
cmd.ExecuteNonQuery();
oracleConn.Close();
binddata();
}
protected void Deletedata(object s, GridViewDeleteEventArgs e)
{
binddata();
DataSet ds = gv.DataSource as DataSet;
ds.Tables[0].Rows[gv.Rows[e.RowIndex].DataItemIndex].Delete();
// ds.WriteXml(Server.MapPath("testxml.xml"));//Disabled now. Do database. Irfan. 07/09/10
String strConnect = GetConnString();
OracleConnection oracleConn = new OracleConnection();
oracleConn.ConnectionString = strConnect;
oracleConn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = oracleConn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "UPDATE CampusDev.CU_POLY SET PDF_Storage = :PDF_Storage WHERE OBJECTID = " + Request.QueryString["OBJECTID"];
StringWriter SW = new StringWriter();
ds.WriteXml(SW,XmlWriteMode.IgnoreSchema);
Regex regex = new Regex(#"(\r\n|\r|\n)+");
string newText = regex.Replace(SW.ToString(), "");
cmd.Parameters.Add(":PDF_Storage", newText);
cmd.ExecuteNonQuery();
oracleConn.Close();
binddata();
string blah = "blah";
}
Here is how I have done this in the past. For the insert you can basically just write the dataset's xml representation out to a string and save it directly to a field in the database. In this case I leveraged Sql Server 2008 and an XML datatype for the database field. I think the datatype in Oracle is XMLTYPE.
Insert:
public static void InsertDataSet(string key, DataSet dataSet)
{
string xml = string.Empty;
using (MemoryStream ms = new MemoryStream())
{
dataSet.WriteXml(ms, XmlWriteMode.WriteSchema);
ms.Position = 0;
using (StreamReader sr = new StreamReader(ms))
{
xml = sr.ReadToEnd();
}
using (SqlServerConnection c = new SqlServerConnection(connectionString))
{
c.command.CommandType = CommandType.StoredProcedure;
c.command.CommandText = "some stored procedure to do the insert";
c.command.Parameters.Clear();
c.command.Parameters.Add(new SqlParameter("#key", key));
c.command.Parameters.Add(new SqlParameter("#xml", xml));
c.command.ExecuteNonQuery();
}
}
}
Getting the dataset back out of the database is as simple as reading the xml data from the database back into a TextReader and then building a new DataSet.
Get:
public static DataSet GetDataSet(string key)
{
using (SqlServerConnection c = new SqlServerConnection(connectionString))
{
c.command.CommandType = CommandType.StoredProcedure;
c.command.CommandText = "some stored procedure to get the xml";
c.command.Parameters.Clear();
c.command.Parameters.Add(new SqlParameter("#key", key));
dr = c.command.ExecuteReader();
if (dr == null)
{
return null;
}
if (dr.HasRows)
{
while (dr.Read())
{
if (dr["xml_field"] != DBNull.Value)
{
TextReader tr = new StringReader(dr["xml_field"].ToString());
result = new DataSet();
result.ReadXml(tr, XmlReadMode.ReadSchema);
}
}
}
}
return result;
}
Hope this helps.
Enjoy!
I need advice. I zip and crypt SOAP message on web service and client side.
Client is winforms app.
If I only crypt SOAP message, it works good.
If I only zip SOAP message it also works good.
I use SOAP extension on crypt and zip SOAP.
I use AES - Advanced Encryption Standard - Rijndael and on compresion I use SharpZipLib from http://sourceforge.net/projects/sharpdevelop/.
The problem is I send dataset on client.
Firstly I zip and secondly encrypt SOAP on web service side.
Send on client.
On client side I load XML from stream. But it finish with this error :
Data at the root level is invalid. Line 1, position 2234.
Here is the code, where I load XML from stream:
var doc = new XmlDocument();
using (var reader = new XmlTextReader(inputStream))
{
doc.Load(reader);
}
Any advice ? Thank you...
Here are methods on web service side which zip and crypt SOAP :
//encrypt string
private static string EncryptString(string #string, string initialVector, string salt, string password,
string hashAlgorithm, int keySize, int passwordIterations)
{
byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(#string);
var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
var symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes);
using (var memStream = new MemoryStream())
{
var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
var serializer = new XmlSerializer(typeof(byte[]));
var sb = new StringBuilder();
TextWriter writer = new StringWriter(sb);
serializer.Serialize(writer, memStream.ToArray());
writer.Flush();
var doc = new XmlDocument();
doc.LoadXml(sb.ToString());
if (doc.DocumentElement != null) return doc.DocumentElement.InnerXml;
}
return "";
}
//zip string
private static byte[] ZipArray(string stringToZip)
{
byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToZip);
var ms = new MemoryStream();
// SharpZipLib.Zip,
var zipOut = new ZipOutputStream(ms);
var zipEntry = new ZipEntry("ZippedFile");
zipOut.PutNextEntry(zipEntry);
zipOut.SetLevel(7);
zipOut.Write(inputByteArray, 0, inputByteArray.Length);
zipOut.Finish();
zipOut.Close();
return ms.ToArray();
}
//zip and encrypt SOAP
public virtual Stream OutSoap(string[] soapElement, Stream inputStream)
{
#region Load XML from SOAP
var doc = new XmlDocument();
using (XmlReader reader = XmlReader.Create(inputStream))
{
doc.Load(reader);
}
var nsMan = new XmlNamespaceManager(doc.NameTable);
nsMan.AddNamespace("soap",
"http://schemas.xmlsoap.org/soap/envelope/");
#endregion Load XML from SOAP
#region Zip SOAP
XmlNode bodyNode = doc.SelectSingleNode(#"//soap:Body", nsMan);
bodyNode = bodyNode.FirstChild.FirstChild;
while (bodyNode != null)
{
if (bodyNode.InnerXml.Length > 0)
{
// Zip
byte[] outData = ZipArray(bodyNode.InnerXml);
bodyNode.InnerXml = Convert.ToBase64String(outData);
}
bodyNode = bodyNode.NextSibling;
}
#endregion Zip SOAP
#region Crypt SOAP
foreach (string xPathQuery in soapElement)
{
XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
if (nodesToEncrypt != null)
foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
{
//Encrypt
nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml,
user.IV, user.Salt, user.Password, user.HashType,
user.KeySize, user.PasswordIterations);
}
}
#endregion Crypt SOAP
inputStream.Position = 0;
var settings = new XmlWriterSettings { Encoding = Encoding.UTF8 };
using (XmlWriter writer = XmlWriter.Create(inputStream, settings))
{
doc.WriteTo(writer);
return inputStream;
}
}
Here is a code on client side which decrypt and uzip SOAP :
//decrypt string
private static string DecryptString(string #string, string initialVector, string salt, string password,
string hashAlgorithm, int keySize, int passwordIterations)
{
byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
byte[] cipherTextBytes = Convert.FromBase64String(#string);
var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations);
byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes);
using (var memStream = new MemoryStream(cipherTextBytes))
{
var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read);
var plainTextBytes = new byte[cipherTextBytes.Length];
int byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
}
}
//unzip string
private static byte[] UnzipArray(string stringToUnzip)
{
byte[] inputByteArray = Convert.FromBase64String(stringToUnzip);
var ms = new MemoryStream(inputByteArray);
var ret = new MemoryStream();
// SharpZipLib.Zip
var zipIn = new ZipInputStream(ms);
var theEntry = zipIn.GetNextEntry();
var buffer = new Byte[2048];
int size = 2048;
while (true)
{
size = zipIn.Read(buffer, 0, buffer.Length);
if (size > 0)
{
ret.Write(buffer, 0, size);
}
else
{
break;
}
}
return ret.ToArray();
}
public virtual Stream InSoap(Stream inputStream, string[] soapElement)
{
#region Load XML from SOAP
var doc = new XmlDocument();
using (var reader = new XmlTextReader(inputStream))
{
doc.Load(reader);
}
var nsMan = new XmlNamespaceManager(doc.NameTable);
nsMan.AddNamespace("soap",
"http://schemas.xmlsoap.org/soap/envelope/");
#endregion Load XML from SOAP
#region Decrypt SOAP
foreach (string xPathQuery in soapElement)
{
XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
if (nodesToEncrypt != null)
foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
{
nodeToEncrypt.InnerXml = DecryptString(nodeToEncrypt.InnerXml, saltPhrase, passwordPhrase, initialVector,
hashAlgorithm, passwordIterations, keySize);
}
}
#endregion Decrypt SOAP
#region UnZip SOAP
XmlNode node = doc.SelectSingleNode("//soap:Body", nsMan);
node = node.FirstChild.FirstChild;
while (node != null)
{
if (node.InnerXml.Length > 0)
{
byte[] outData = UnzipArray(node.InnerXml);
string sTmp = Encoding.UTF8.GetString(outData);
node.InnerXml = sTmp;
}
node = node.NextSibling;
}
#endregion UnZip SOAP
var retStream = new MemoryStream();
doc.Save(retStream);
return retStream;
}
strong text
I'm not sure why your unencrypted xml won't parse, but I think you're first step should be to dump the decrypted data to the terminal to see exactly what text you're getting back. Perhaps the process corrupts your data somehow, or you have an encoding issue.
Alternatively, you could configure your server to use https and gzip compression to achieve the same goal. You won't loose any security with this approach and this is by far the more standard way to do things. You can also have a look at MS's support for the WS-Security standard