Asp.net Multiple files download - asp.net

Im trying to search and download the files uploaded to the database,I can able to retrieve the files from the database.
Downloading single file works but cant download multiple files at a time,I have read about downloading as a zip file,Can anyone help??????
using (sampledbase dbcontext = new sampledbase ())
{
ZipFile zip = new ZipFile();
long id = Convert.ToInt64(Request.QueryString["id"]);
System.Nullable<long> fileid = id;
var query = dbcontext.searchfile(ref fileid );
foreach (var i in query)
{
byte[] binarydata = i.Data.ToArray();
Response.AddHeader("content-disposition", string.Format("attachment; filename =\"{0}\"", i.Name));
Response.BinaryWrite(binarydata);
Response.ContentType = i.ContentType;
Response.End();
}
}

I see that you are using ZipFile so you are in the right direction. In order to zip your files, you can save your files in a directory and zip the directory using this code :
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
ZipFile.CreateFromDirectory(startPath, zipPath);
In your case, look at the data type returned by dbcontext.searchfile() and save the content to a directory using something like StreamWriter. Looking at your code, the type seems to be a byte[], you can see this link to learn how to save the bytes in a file : Write bytes to file
Another solution is to zip directly the bytes[] : Create zip file from byte[]

Related

Convert Byte Array to pdf for UWP

I am working on Xamarin.Forms-UWP.
I want to convert byte array stored in the database to pdf for Windows phone.
I know how to convert
var base64Binarystr = "ABCDS"
byte[] bytes = Convert.FromBase64String(base64Binarystr );
Can anyone help as how to display pdf? Just a pointer- I have multiple pdf files so I cannot add all the files to the application or store on the disk.
Appreciate for any pointers on this.
Thanks!
Every received file can be stored with the same name (I used "my.pdf") then there is no risk for too many files stored. If you need to cache files then you can give different names. The pdf viewer didn't want to show files from Local, Temp or Downloads folder for me though I tried ms-appdata, so I had to move the file from Local folder to Assets to display the way viewer "wants" it via ms-appx-web. Downloads folder also has a problem with CreationCollisionOption.ReplaceExisting, it says invalid parameter if file already exists instead of replacing it but Local and Temporary folder behave correctly.
/////////////// store pdf file from internet, move it to Assets folder and display ////////////////////
//bytes received from Internet. Simulated that by reading existing file from Assets folder
var pdfBytes = File.ReadAllBytes(#"Assets\Content\samplepdf.pdf");
try
{
StorageFolder storageFolder = ApplicationData.Current.LocalFolder; //or ApplicationData.Current.TemporaryFolder
StorageFile pdfFile = await storageFolder.CreateFileAsync("my.pdf", CreationCollisionOption.ReplaceExisting);
//write data to created file
await FileIO.WriteBytesAsync(pdfFile, pdfBytes);
//get asets folder
StorageFolder appInstalledFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFolder assetsFolder = await appInstalledFolder.GetFolderAsync("Assets");
//move file from local folder to assets
await pdfFile.MoveAsync(assetsFolder, "my.pdf", NameCollisionOption.ReplaceExisting);
}
catch (Exception ex)
{
}
Control.Source = new Uri(string.Format("ms-appx-web:///Assets/pdfjs/web/viewer.html?file={0}", "ms-appx-web:///Assets/my.pdf")); //local pdf

Uploading files and preventing duplicates by knowing to update the file

In our system, when a user uploads a file it is stored in a unique file system structure and a database record is generated. A file is uploaded via the webbrowser via XMLHttpRequest. The file then gets moved from the temporary upload area into the FS.
How can I detect that a file after being uploaded already exists in my FS?
If the file uploaded is the same as one already uploaded.
If the file is the same file, but the uploaded content has been updated which
means I need to update the file in the FS.
I am ignoring file names as a way of knowing if the file already exists. A filename cannot be considered unique. An example is that some cameras name photos using an incremental number that rolls over after a time.
When a file is uploaded via the web browser, the source file structure is masked. E.g. C:\Users\Drive\File\Uploaded\From. So I cant use the that to figure out if the file has already been uploaded.
How do I know the file being uploaded already exists because its content is the same. Or it exists but because the uploaded file has been changed, so I can just update the file?
Microsoft Word documents create a challenge as Word regenerates the file on every save.
In a situation where the user renames a file on their own accord, I could say tough luck.
I would start with finding files that are the same via an SHA Hash. You could use something like this to get a list of files that have the same hash as your newly uploaded file then take some action.
Just an example of getting the hash of the new file:
string newfile;
using(FileStream fs = new FileStream( string newfile;
using(FileStream fs = new FileStream("C:\\Users\\Drive\\File\\Uploaded\\From\\newfile.txt", FileMode.Open))
{
using (System.Security.Cryptography.SHA1Managed sha1 = new System.Security.Cryptography.SHA1Managed())
{
newfile = BitConverter.ToString(sha1.ComputeHash(fs));
}
}
This goes through all files and gets a list of file names and hashes
var allfiles = Directory.GetFiles(#"var allfiles = Directory.GetFiles(#"C:\Users\Drive\File\Uploaded\From\", "*.*")
.Select(
f => new
{
FileName = f,
FileHash = new System.Security.Cryptography.SHA1Managed()
.ComputeHash(new FileStream(f,
FileMode.Open,
FileAccess.Read))
})
.ToList();
foreach(var fi in allfiles){
if(newfile == BitConverter.ToString(fi.FileHash))
Console.WriteLine("Match!!!");
Console.WriteLine(fi.FileName + ' ' + BitConverter.ToString(fi.FileHash));
}
}", ".")
.Select(
f => new
{
FileName = f,
FileHash = new System.Security.Cryptography.SHA1Managed()
.ComputeHash(new FileStream(f,
FileMode.Open,
FileAccess.Read))
})
.ToList();
This loops through them all and looks for a match to the new one.
foreach(var fi in allfiles){
if(newfile == BitConverter.ToString(fi.FileHash))
Console.WriteLine("Match!!!");
Console.WriteLine(fi.FileName + ' ' + BitConverter.ToString(fi.FileHash));
}
Ideally you would save this hash when the file is uploaded since this is very intense to recompute.

How to update a PDF without creating a new PDF?

I am required to replace a word in an existing PDF AcroField with another word. I am using PDFStamper of iTEXTSHARP to do the same and it is working fine. But, in doing so it is required to create a new PDF and i would like the change to be reflected in the existing PDF itself. If I am setting the destination filename same as the original filename then no change is being reflected.I am new to iTextSharp , is there anything I am doing wrong? Please help.. I am providing the piece of code I am using
private void ListFieldNames(string s)
{
try
{
string pdfTemplate = #"z:\TEMP\PDF\PassportApplicationForm_Main_English_V1.0.pdf";
string newFile = #"z:\TEMP\PDF\PassportApplicationForm_Main_English_V1.0.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
for (int page = 1; page <= pdfReader.NumberOfPages; page++)
{
PdfReader reader = new PdfReader((string)pdfTemplate);
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create, FileAccess.ReadWrite)))
{
AcroFields form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
//Replace Address Form field with my custom data
if (fieldKey.Contains("Address"))
{
form.SetField(fieldKey, s);
}
}
stamper.FormFlattening = true;
stamper.Close();
}
}
}
As documented in my book iText in Action, you can't read a file and write to it simultaneously. Think of how Word works: you can't open a Word document and write directly to it. Word always creates a temporary file, writes the changes to it, then replaces the original file with it and then throws away the temporary file.
You can do that too:
read the original file with PdfReader,
create a temporary file for PdfStamper, and when you're done,
replace the original file with the temporary file.
Or:
read the original file into a byte[],
create PdfReader with this byte[], and
use the path to the original file for PdfStamper.
This second option is more dangerous, as you'll lose the original file if you do something that causes an exception in PdfStamper.

The given path's format is not supported

I am getting the following error while uploading the file from my local drive.
The given path's format is not supported.
The code is given.
Please tell me what changes I have to make.
string file0 = MapPathReverse(FileUpload1.PostedFile.FileName);// Get virtual path
string conversationFileSource = Server.MapPath(file0);
StreamReader file = new StreamReader(conversationFileSource);
If you want to access the input stream of the uploaded file:
using (StreamReader reader = new StreamReader(FileUpload1.PostedFile.InputStream))
{
...
}
If you want to save the uploaded file on some folder on your server:
var uploadsFolder = Server.MapPath("~/uploads");
var file = Path.Combine(uploadsFolder, Path.GetFileName(FileUpload1.PostedFile.FileName));
FileUpload1.PostedFile.SaveAs(file);

FileUpload problem with Struts on server

I am trying to create a upload servlet that handles enctype="multipart/form-data" from a form. The file I am trying to upload is a zip. However, I can upload and read the file on localhost, but when I upload to the server, I get a "File not found" error when I want to upload a file. Is this due to the Struts framework that I am using? Thanks for your help. Here is part of my code, I am using FileUpload from http://commons.apache.org/fileupload/using.html
I have changed to using ZipInputStream, however, how to I reference to the ZipFile zip without using a local disk address (ie: C://zipfile.zip). zip is null because its not instantiated. I will need to unzip and read the zipentry in memory, without writing to the server.
For the upload servlet:
>
private ZipFile zip;
private CSVReader reader;
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List <FileItem> items = upload.parseRequest(request);
Iterator iter = items.iterator();
while (iter.hasNext()) {
//Iterating through the uploaded zip file and reading the content
FileItem item = (FileItem) iter.next();
ZipInputStream input = new ZipInputStream(item.getInputStream());
ZipEntry entry = null;
while (( entry= input.getNextEntry()) != null) {
ZipEntry entry = (ZipEntry) e.nextElement();
if(entry.getName().toString().equals("file.csv")){
//unzip(entry)
}
}
}
public static void unzip(ZipEntry entry){
try{
InputStream inputStream = **zip**.getInputStream(entry);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
reader = new CSVReader(inputStreamReader);
}
catch(Exception e){
e.printStackTrace();
}
}
<
Here,
zip = new ZipFile(new File(fileName));
You're assuming that the local disk file system at the server machine already contains the file with exactly the same name as it is at the client side. This is a wrong assumption. That it worked at localhost is obviously because both the webbrowser and webserver "by coincidence" runs at physically the same machine with the same disk file system.
Also, you seem to be using Internet Explorer as browser which incorrectly includes the full path in the filename like C:/full/path/to/file.ext. You shouldn't be relying on this browser specific bug. Other browsers like Firefox correctly sends only the file name like file.ext, which in turn would have caused a failure with new File(fileName) (which should have helped you to spot your mistake much sooner).
To fix this "problem", you need to obtain the file contents as InputStream by item.getInputStream():
ZipInputStream input = new ZipInputStream(item.getInputStream());
// ...
Or to write it to disk by item.write(file) and reference it in ZipFile:
File file = File.createTempFile("temp", ".zip");
item.write(file);
ZipFile zipFile = new ZipFile(file);
// ...
Note: don't forget to check the file extension beforehand, else this may choke.

Resources