Use content of FileUpload - c#

I am attempting to add a file import function to an admin webpage where a CSV file will be imported from a local C: drive
I've just realized that string filePath = Path.GetFileName(FileUpload1.FileName); doesn't actually allow the client path to be read and only gives the filename.
protected void btnImportData_Click(object sender, EventArgs e)
{
List<CSVFile> entries = new List<CSVFile>();
string filePath = Path.GetFileName(FileUpload1.FileName);
using (TextFieldParser parser = new TextFieldParser(filePath))
{
//Other code
}
}
Currently the line TextFieldParser parser = new TextFieldParser(filePath) gives an error as I can't get the full path to the CSV.
Is it possible to load the contents of FileUpload1 into variable parser instead? I can see the control has content but not sure how or if it's possible?

The FileName property is simply the filename the browser sent, and is not yet physically stored on the server. To do so, you'll need to save it first:
string filePath = String.Format({0}{1}", System.IO.Path.GetTempPath(), FileUpload1.FileName); // Save to temp directory
FileUpload1.SaveAs(filePath);
using (TextFieldParser parser = new TextFieldParser(filePath))
{
//...
}
File.Delete(filePath); // Delete the file if you're done with it
Also, if TextFieldParser can take in a System.IO.Stream, you won't even need to save the file to disk first:
using (TextFieldParser parser = new TextFieldParser(FileUpload1.FileContent)) // Read stream
{
//...
}

Take into account that the file is not stored yet on the server so there is no path. FileName is just that: a file name and not a full path.
If you require the file to exist on the file system in order to parse it, you'll need to first save it.

Related

How do I specify a specific file in my Xamarin/VisualStudio Project using Environment.SpecialFolder?

I am trying to append text to a text file, but I can't find anywhere how to actually locate an existing file.
partial void MainBtn_TouchUpInside(UIButton sender)
{
var Pp = ("Selected Form Of Exchange: Paypal");
string mydocpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments(WHAT DO I WRITE IN THIS SPACE??);
using (StreamWriter outputFile = new **StreamWriter(Path.Combine(mydocpath, "SelectPayment.txt")))
//I know that the file already exists, I just am trying different things.
{
outputFile.WriteLine(Pp);
}
So what do I do? Thanks
Josh
you specify a file by combining a folder path and a file name to create a file path
// this returns the path to a folder
string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
// combine that with a file name to create a file path
string file = Path.Combine(path, "myFile.text");
// append text to file
File.AppendAllText(file, "this is the text I want to append);

Get the filename of a file that was created through ZipFile.ExtractToDirectory()

string zipPath = #"D:\books\"+fileinfo.DccFileName;
string extractPath = #"D:\books";
System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, extractPath);
This is a simple piece of code that does exactly what i want it to do: Gets a zip file from d:\books and unzips it into the same directory. Is there any way i can read the filename of the newly created file (considering that there is only one file in the .zip archive). I would prefer a solution that does not involve reading changes in the directory since other files might be created in it at the same time of the unzip.
You can construct the path by inspecting the archive
var intentedPath = string.Empty;
//open archive
using (var archive = ZipFile.OpenRead(zipPath)) {
//since there is only one entry grab the first
var entry = archive.Entries.First();
//the relative path of the entry in the zip archive
var fileName = entry.FullName;
//intended path once extracted would be
intentedPath = Path.Combine(extractPath, fileName);
}

IO Exception - File being used by another process (Can't open file following directory creation)

I have got a project on the go that monitors patients for a vet while they are being operated on and writes the result to a text file. While I was experimenting with the outputting I just let the files save in the Debug folder, which worked fine. However, I've now created a full directory that creates or opens a main folder, and then a sub folder (based on input text from the program), to save the text file into.
private void createDirectory()
{ //create output file in this folder using owner name and current date
//main folder path (contains all files output from system)
string rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Horse Monitoring Records";
//sub folder path (each patient has individual subfolder)
string subDirectory = rootDirectory + "\\" + txtPatName.Text + "-" + txtOwnerName.Text;
//file name (patient has file created for each operation)
fileName = subDirectory + "\\" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("ddMMyyyy") + ".txt";
if (!Directory.Exists(rootDirectory)) //if main folder does not exist...
{
Directory.CreateDirectory(rootDirectory); //create it in My Documents
}
if (!Directory.Exists(subDirectory)) //if patient sub folder does not exist...
{
Directory.CreateDirectory(subDirectory); //create it in Patient-Owner format
}
if (!File.Exists(fileName)) //if monitoring file does not exist...
{
File.Create(fileName); //create it in Owner-Date format
}
}
This stage works fine, but as soon as you try to save some data to the text file, it throws to a run time error stating that
The file cannot be accessed because it is being used by another process.
The exception is brought up here:
private void saveFileDetails()
{
//Once case details have been entered, create new file using these details and add data input structure
StreamWriter consoleFile = new StreamWriter(fileName);
...
}
When I went and checked out the folder, the relevant sub-folder and file had been created but the text file was blank.
I'm guessing it's something to do with closing the text file after creating the directory, which means it's already open when the system tries to open it. I can't figure out how to sort this issue out though!
The two functions shown above are called like this:
private void btnStart_Click(object sender, EventArgs e)
{
...
//file details entered upon load written to new file - according to PatID
createDirectory();
saveFileDetails();
}
Any suggestions on where to go from here would be very much appreciated!
Thanks,
Mark
The issue here is that you do
if (!File.Exists(fileName)) //if monitoring file does not exist...
{
File.Create(fileName); //create it in Owner-Date format
}
Right before you try to write to the file. Because you've just created it (if it didn't exist), chances are that the operating system hasn't released the file yet.
Like #Jauch mentioned in the comments, you could skip this check completely and use the StreamWriter overload which will create file if it doesn't exist, or append to it if it does.
private void saveFileDetails()
{
//Once case details have been entered, create new file using these details and add data input structure
using (StreamWriter consoleFile = new StreamWriter(fileName, true))
{
// ...
}
}
Alternatively you can use the following to write all of your text at once:
File.AppendAllText(textToWrite, fileName);
File.Create(fileName) returns an open stream to the file which is never closed.
To create an empty file use File.WriteAllBytes(fileName, new byte[0]);
Otherwise the 2 methods can be shortend
private void SaveFileDetails()
{
string subDirectory = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"Horse Monitoring Records");
// create the folder hierarchy if not exists. does nothing if already there
Directory.CreateDirectory(subDirectory);
// each patient has individual file
var filepath = Path.Combine(subDirectory,
txtPatName.Text + "-" + txtOwnerName.Text + "-" + DateTime.Now.Date.ToString("yyyyMMdd") + ".txt");
// creates the file if not exists
using (var writer = new StreamWriter(filepath, append: true, encoding: Encoding.UTF8))
{
// write details
}
}
Note:
merged 2 methods
.NET naming conventions applied
changed dateformat to better sort by name in explorer
StreamWriter implements IDisposable, so wrapping it in a using block can manage closing and disposing the writer and ensuring it is available the next time you want to touch that file. It can also manage creating the text file if it doesn't exist, removing the need to explicitly call File.Create.
StreamWriter consoleFile = new StreamWriter(fileName);
becomes
using (StreamWriter writer = File.AppendText("log.txt"))
{
// writing, etc.
}
or
using (StreamWriter writer = new StreamWriter(fileName, true))
{ // true says "append to file if it exists, create if it doesn't"
// writing, etc.
}
Whatever seems more readable to you will work fine.

Copy a specific file (.docx, .pdf, .pptx etc) form folder in C#

I am trying to copy a file (.docx, .pdf, .pptx etc) from a source folder(on server) to a destination folder(on client).
The user can choose which among the list of files that he wants to download. He selects the files and then downloads it(Copies it to his computer) to the destination path
dstnLocation= #"C:\Fldr\Docs;
My Code:
string sourceLocation = textBox2.Text;
string dstnLocation = #"C:\Fldr\Docs";
System.IO.FileInfo file = new System.IO.FileInfo(dstnLocation);
file.Directory.Create();
System.IO.File.Copy(sourceLocation, dstnLocation,true);
MessageBox.Show("Download Complete");
The problem is that it creates a file as "Docs"(where one has to use open with to open the file) and if I am not wrong then its because of the destination path. Could someone please tell what all am I doing wrong.
The source path is retrieved through database!
you need to concat otherwise you're destination location is just the folder not the file path destination
so do something like
var destFile = string.Format(#"{0}\{1}", dstnLocation, Path.GetFileName(sourceLocation));
then copy that
So code becomes
string sourceLocation = textBox2.Text;
string dstnLocation = string.Format(#"C:\Fldr\Docs\{0}", Path.GetFileName(sourceLocation);
if (! System.IO.Directory.Exists(dstnLocation))
{
System.IO.Directory.CreateDirectory(dstnLocation);
}
System.IO.File.Copy(sourceLocation, dstnLocation,true);
MessageBox.Show("Download Complete");
You are creating the file name incorrectly:
string dstnLocation = #"C:\Fldr\Docs";
System.IO.FileInfo file = new System.IO.FileInfo(dstnLocation);
This creates a file with the name "C:\Fldr\Docs" for example what you want is "C:\Fldr\Docs\myfilename.docx" if I am not mistaken?
Try this instead:
var filename = Path.GetFileName(sourceLocation);
string dstnLocation = Path.Combine(#"C:\Fldr\Docs", filename);
The problem here is that the destination requires an "output" file name.
This problem lies in this line of code
System.IO.File.Copy(sourceLocation, dstnLocation,true);
The dstnLocation needs to be concatenated with the output file name for example:
System.IO.File.Copy(sourceLocation, Path.Combine(dstnLocation,"Database.dbs"),true);

Returning An Xml String To Client Code From C#

I am reading a file from the user files that contains xml that I am processing in a Generic Handler and then passing to the client.
The problem I am having is when I pass the string of xml to the client. Its not in the proper format. It removes the root tag and "<xml 1.0>" tag entirely when looking at it through the client code.
I am looking for some code to preserve the xml string as is when it gets to the client.
I am reading the xml out of a file using System.IO on the server..
public void ProcessRequest(HttpContext context)
{
if (context.Request.Files.Count > 0)
{
string path = context.Server.MapPath("~/Temp");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var file = context.Request.Files[0];
string fileName;
if (HttpContext.Current.Request.Browser.Browser.ToUpper() == "IE")
{
string[] files = file.FileName.Split(new char[] { '\\' });
fileName = files[files.Length - 1];
}
else
{
fileName = file.FileName;
}
string strFileName = fileName;
fileName = Path.Combine(path, fileName);
file.SaveAs(fileName);
string msg = File.ReadAllText(fileName);
File.Delete(fileName);
context.Response.Write(msg);
}
}
The xml always starts at "Gambardella..." For some reason it cannot read the beginning of the file when being send to the cient.
Here is an image of the sample xml..
The data is sent out of the handler fine but the client cuts off the top information. It looks like the plugin I am using is storing the (or getting) the data from an iframe. Could the iframe maybe be the culprit in cutting off the beginning xml??
The sample client code I am using is here
You can simply use Response.WriteFile, instead of reading the file then sending it.
Response.WriteFile(fileName);
This will return the contents of the file with the correct HTTP Content-Type header. If the file has the XML declaration, it will not remove it.
Something like the following, based on your code and untested (an without a MemoryStream, as it is not needed in this case):
var file = context.Request.Files[0];
file.InputStream.CopyTo(context.Response.OutputStream)

Categories