Below is my code which generates a sample PDF file. However the server.mappath method saves the file at the project folder. How do i allow the PDF file to be saved in my own desktop?
protected void btnPDF_Click(object sender, EventArgs e)
{
var document = new Document(PageSize.A4, 50, 50, 25, 25);
var filename = DDLCase.SelectedItem.Text + ".pdf";
var output = new FileStream(Server.MapPath(filename), FileMode.Create);
var writer = PdfWriter.GetInstance(document, output);
document.Open();
var welcomeParagraph = new Paragraph("Test1");
document.Add(welcomeParagraph);
document.Close();
btnPDF.Enabled= false;
}
It is very unclear what your problem is as it should be pretty straightforward to replace Server.MapPath(filename) with some other location.
One useful function is Path.Combine so you can correctly build path to a file:
var output = new FileStream(Path.Combine("c:\\myPDF\\", filename), FileMode.Create);
Note that to be done properly folder on server where you plan to store files must have enough permissions to allow ASP.Net process to save files there. If you use Windows auth with impersonation it becomes trickier as account code is running under during request will be incoming user's account.
Try this
public string CommonFileSave(HttpPostedFileBase postedFile, string filePath)
{
string resultResponse = "sccuess";
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
postedFile.SaveAs(filePath + postedFile.FileName);
}
else
{
filePath = filePath + postedFile.FileName;
if (!System.IO.File.Exists(filePath))
{
postedFile.SaveAs(filePath);
}
}
return resultResponse;
}
Related
I have a Winform control to write notes whose contents are periodically uploaded to the server.
I need to create a local file as a backup to save the contents of the notes.
When I type text into the notebox, the content remains in the note box and gets saved into the local text file. However, when I enter more texts to the note-box, the previous content as well as the new content gets appended to the local file.
How do I make sure that only the recent content gets appended to the local file? If i clear the note-box content, no content gets logged on to the server.
private void btnNote_Click(object sender, EventArgs e)
{
Note noteFrm = new Note();
//set Note Text
noteFrm.NoteText = _timeCard.NoteText;
if (noteFrm.ShowDialog() == DialogResult.OK)
{
//Save notes locally as well
string path = #"C:\QB Notes\";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string projname = this._timeCard.Project.ProjectName.TrimEnd()+".txt";
string fileloc = path + projname;
// FileStream fs = null;
if (!File.Exists(fileloc))
{
using (TextWriter txt = new StreamWriter(fileloc))
{
// TextWriter txt = new StreamWriter(fileloc);
txt.Write(noteFrm.NoteText + Environment.NewLine);
txt.Close();
}
}
else if (File.Exists(fileloc))
{
using (var txt = new StreamWriter(fileloc, true))
{
txt.BaseStream.Seek(0, SeekOrigin.End);
txt.Write(noteFrm.NoteText + Environment.NewLine);
txt.Close();
}
}
//noteFrm.NoteText="";
//get Note Text
_timeCard.NoteText = noteFrm.NoteText;
Utils.LogManager.write("New Note Text: " + noteFrm.NoteText);
}
}
If you want the file to always match what is in the text box, then I'd suggest that you replace your whole if (!File.Exists(fileloc)) block with just this:
File.WriteAllText(fileloc, noteFrm.NoteText + Environment.NewLine);
That will create the file if needed, open the file, replace all the contents with what is in the text box, and close the file.
Scenario: upload file than try zip it using DotNetZip with password protection, password is generated with Membership.GeneratePassword() method. Everything is working fine except that sometimes user is not able to unzip files with generated password. Wired thing is that this happens only sometimes let's say 1 out of 15 times.
Generate password:
public static String FilePassword()
{
while (_filePassword.Length < 12)
{
_filePassword += string.Concat(Membership.GeneratePassword(1, 0).Where(char.IsLetterOrDigit));
}
return _filePassword;
}
Save file:
if (FileUploadControl.HasFile)
{
fileName = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(FileSavePath + fileName);
// Archive uploaded file to zip.
using (ZipFile zip = new ZipFile())
{
// File to be archived.
var file = FileUploadControl.PostedFile;
// Enable encryption of file
zip.Encryption = EncryptionAlgorithm.PkzipWeak;
// Set password.
zip.Password = Settings.FilePassword();
// Set temporary folder path for archive process.
zip.TempFileFolder = tempPath;
// Add file to archive with its path.
zip.AddFile(FileSavePath + file.FileName, "");
File objFile = new File(file.FileName, FileSavePath);
// Save zip file with the name as file ID.
zip.Save(FileSavePath + file.FileName);
}
}
I logged password while creating in method and also while protecting zip file with password, they are always matching, I cannot see what's wrong, why sometimes while unzipping file it shows wrong password.
Why do you use the static global variable _filePassword in FilePassword() instead of one in scope?
This way it could be modified from outside, or possible even still contain the last used value. Also it isn't thread safe without lock.
Settle with a local variable and it should be fine.
public static String FilePassword()
{
string retString = string.Empty;
while (retString.Length < 12)
{
retString += string.Concat(Membership.GeneratePassword(1, 0).Where(char.IsLetterOrDigit));
}
return retString;
}
You can log a return Value too.
Sample for understanding
if (FileUploadControl.HasFile)
{
fileName = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(FileSavePath + fileName);
string filePassword = Settings.FilePassword(); // Contains the Password
using (ZipFile zip = new ZipFile())
{
var file = FileUploadControl.PostedFile;
zip.Encryption = EncryptionAlgorithm.PkzipWeak;
zip.Password = filePassword; // <-- Set password for ZIP
zip.TempFileFolder = tempPath;
zip.AddFile(FileSavePath + file.FileName, "");
File objFile = new File(file.FileName, FileSavePath);
zip.Save(FileSavePath + file.FileName);
}
// Log this value!
Log(filePassword);
}
I already protect the csv files with zip by using the ionic.zip.dll
see the below code
using (ZipFile zip = new ZipFile())
{
TargetFileName = TargetNamePrefix;
OutPutDirectoryPath = TargetLocation + "\\" + TargetNamePrefix + ".zip";
zip.Password = zipFilePassword;
zip.AddFiles(FilePaths, TargetNamePrefix);
zip.Save(OutPutDirectoryPath)
}
here file paths is string[] variable it consists of files(csv/text) Names.
TargetNamePrefix means inside zipfile folder Name.OutPutDirectoryPath means
output directoty with zipfileName.
then How can i Open the those protected files in write mode why because I want to write Datainto the Protected csv file.
You can just extract them using a similar method:
using(ZipFile zip = ZipFile.Read(OutPutDirectoryPath))
{
zip.Password = zipFilePassword;
try
{
zip.ExtractAll(TargetLocation);
}
catch (BadPasswordException e)
{
// handle error
}
}
Update
Access single file entry into a stream without extracting
string entry_name = TargetNamePrefix + ".csv"; // update this if needed
using (ZipFile zip = ZipFile.Read(OutPutDirectoryPath))
{
// Set password for file
zip.Password = zipFilePassword;
// Extract entry into a memory stream
ZipEntry e = zip[entry_name];
using(MemoryStream m = new MemoryStream())
{
e.Extract(m);
// Update m stream
}
// Remove old entry
zip.RemoveEntry(entry_name);
// Add new entry
zip.AddEntry(entry_name, m);
// Save
zip.Save(OutPutDirectoryPath);
}
string host = #"ftphost";
string username = "user";
string password = "********";
string localFileName = System.IO.Path.GetFileName(#"localfilename");
string remoteDirectory = "/export/";
using (var sftp = new SftpClient(host, username, password))
{
sftp.Connect();
var files = sftp.ListDirectory(remoteDirectory);
foreach (var file in files)
{
if (!file.Name.StartsWith("."))
{
string remoteFileName = file.Name;
if (file.LastWriteTime.Date == DateTime.Today)
Console.WriteLine(file.FullName);
File.OpenWrite(localFileName);
string sDir = #"localpath";
Stream file1 = File.OpenRead(remoteDirectory + file.Name);
sftp.DownloadFile(remoteDirectory, file1);
}
}
}
I am using SSH.NET (Renci.SshNet) library to work with an SFTP server. What I need to do is grab files from a specific folder on the SFTP server based on today's date. Then copy those files from the SFTP server to a local drive a server of mine.
Above is the code I have but it is not working. Sometimes it says file does not exist but sometimes the files I will be downloading will not be on my local servers but I need to download whatever files were uploaded to the remote folder for that day.
Can someone take a look and see what is wrong? I believe it has something to do with the stream portion. I have worked with FTP much besides uploading files which I took some previous code I had and thought I could reverse the process but that isn't working. The code I used is based off of this example.
A simple working code to download a file with SSH.NET library is:
using (Stream fileStream = File.Create(#"C:\target\local\path\file.zip"))
{
sftp.DownloadFile("/source/remote/path/file.zip", fileStream);
}
See also Downloading a directory using SSH.NET SFTP in C#.
To explain, why your code does not work:
The second parameter of SftpClient.DownloadFile is a stream to write a downloaded contents to.
You are passing in a read stream instead of a write stream. And moreover the path you are opening read stream with is a remote path, what cannot work with File class operating on local files only.
Just discard the File.OpenRead line and use a result of previous File.OpenWrite call instead (that you are not using at all now):
Stream file1 = File.OpenWrite(localFileName);
sftp.DownloadFile(file.FullName, file1);
Or even better, use File.Create to discard any previous contents that the local file may have.
I'm not sure if your localFileName is supposed to hold full path, or just file name. So you may need to add a path too, if necessary (combine localFileName with sDir?)
While the example works, its not the correct way to handle the streams...
You need to ensure the closing of the files/streams with the using clause..
Also, add try/catch to handle IO errors...
public void DownloadAll()
{
string host = #"sftp.domain.com";
string username = "myusername";
string password = "mypassword";
string remoteDirectory = "/RemotePath/";
string localDirectory = #"C:\LocalDriveFolder\Downloaded\";
using (var sftp = new SftpClient(host, username, password))
{
sftp.Connect();
var files = sftp.ListDirectory(remoteDirectory);
foreach (var file in files)
{
string remoteFileName = file.Name;
if ((!file.Name.StartsWith(".")) && ((file.LastWriteTime.Date == DateTime.Today))
using (Stream file1 = File.Create(localDirectory + remoteFileName))
{
sftp.DownloadFile(remoteDirectory + remoteFileName, file1);
}
}
}
}
My version of #Merak Marey's Code. I am checking if files exist already and different download directories for .txt and other files
static void DownloadAll()
{
string host = "xxx.xxx.xxx.xxx";
string username = "###";
string password = "123";string remoteDirectory = "/IN/";
string finalDir = "";
string localDirectory = #"C:\filesDN\";
string localDirectoryZip = #"C:\filesDN\ZIP\";
using (var sftp = new SftpClient(host, username, password))
{
Console.WriteLine("Connecting to " + host + " as " + username);
sftp.Connect();
Console.WriteLine("Connected!");
var files = sftp.ListDirectory(remoteDirectory);
foreach (var file in files)
{
string remoteFileName = file.Name;
if ((!file.Name.StartsWith(".")) && ((file.LastWriteTime.Date == DateTime.Today)))
{
if (!file.Name.Contains(".TXT"))
{
finalDir = localDirectoryZip;
}
else
{
finalDir = localDirectory;
}
if (File.Exists(finalDir + file.Name))
{
Console.WriteLine("File " + file.Name + " Exists");
}else{
Console.WriteLine("Downloading file: " + file.Name);
using (Stream file1 = File.OpenWrite(finalDir + remoteFileName))
{
sftp.DownloadFile(remoteDirectory + remoteFileName, file1);
}
}
}
}
Console.ReadLine();
}
Massimiliano's solution has one problem which will lead to files not being completely downloaded. The FileStream must be closed. This is especially a problem for encrypted files. They won't completely decrypt intermittently without closing the stream.
var files = sftp.ListDirectory(remoteVendorDirectory).Where(f => !f.IsDirectory);
foreach (var file in files)
{
var filename = $"{LocalDirectory}/{file.Name}";
if (!File.Exists(filename))
{
Console.WriteLine("Downloading " + file.FullName);
using (var localFile = File.OpenWrite(filename))
sftp.DownloadFile(file.FullName, localFile);
}
}
This solves the problem on my end.
var files = sftp.ListDirectory(remoteVendorDirectory).Where(f => !f.IsDirectory);
foreach (var file in files)
{
var filename = $"{LocalDirectory}/{file.Name}";
if (!File.Exists(filename))
{
Console.WriteLine("Downloading " + file.FullName);
using (var localFile = File.OpenWrite(filename))
sftp.DownloadFile(file.FullName, localFile);
}
}
Without you providing any specific error message, it's hard to give specific suggestions.
However, I was using the same example and was getting a permissions exception on File.OpenWrite - using the localFileName variable, because using Path.GetFile was pointing to a location that obviously would not have permissions for opening a file > C:\ProgramFiles\IIS(Express)\filename.doc
I found that using System.IO.Path.GetFileName is not correct, use System.IO.Path.GetFullPath instead, point to your file starting with "C:\..."
Also open your solution in FileExplorer and grant permissions to asp.net for the file or any folders holding the file. I was able to download my file at that point.
I wrote this function for creating a zip archive
protected void ImageButton_documenti_Click(object sender, ImageClickEventArgs e)
{
string path_cartella = #"d:\work\project1\temp\document";
string path_cartella_zip = #"d:\work\project1\temp\document_zip\";
path_cartella_zip = path_cartella_zip + "zip_documenti_al_" + System.DateTime.Now.ToString("ddMMyyyy") + ".zip";
//al click dell'immagine creo un file zip contenente tutte le cartelle dei documenti
using (ZipFile zip = new ZipFile())
{
try
{
zip.AddDirectory(path_cartella);
zip.Comment = "This zip was created at " + System.DateTime.Now.ToString("G");
zip.Save(path_cartella_zip);
operazione_ok.Visible = true;
operazione_ok.InnerText = "Procedura di zip attivata.";
}
catch (Exception errore)
{
elenco_errori.Visible = true;
elenco_errori.InnerText = errore.Message;
}
}
}
this function work fine in local but on my web server I don't know the absolute path and I want to change the "string_path_cartella" and "string_path_cartella_zip" for saving document with a relative path in "temp/document" folder
Try this:
string path_cartella = Server.MapPath("~/temp/document");
string path_cartella_zip = Server.MapPath("~/temp/document_zip");
Reference: http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.mappath%28v=vs.110%29.aspx