I´m working in a MVC project and receive a file(HttpPostedFileBase property) in my controller via modelbinding and what I want is to delete all the empty spaces in the name of the file I just received, for that purpose I use this
var nombre_archivo = DateTime.Now.ToString("yyyyMMddHHmm.") +"_"+ (info.file.FileName.ToString()).Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
but the var "nombre_archivo" is always: 201801240942.System.String[] and what I want is 201801240942.nameOfFile, could you please tell me where is the error?
Your are splitting on an array of dots.
Use replace instead :
var nombre_archivo = string.Format("{0}_{1}",
DateTime.Now.ToString("yyyyMMddHHmm."),
info.file.FileName.replace(" ", "")
);
Moreover, we recommend to use string.Format instead of + concatenation. It's faster and clearer
var name = $"{DateTime.Now.ToString("yyyyMMddHHmm.")}_{info.file.FileName.Replace(" ", "")}";
You can use String.Replace to replace a space with an empty string. The method has other issues though. It doesn't check whether FileName is valid which means someone could make a POST request with a hand-coded path like ../../ or E:\somepath\myinnocentprogram.exe to write a file to the server's disk. Or worse, ../index.htm.
Replacing spaces doesn't make much sense. It's the dots and slashes that can result
If you check Uploading a File (Or Files) With ASP.NET MVC you'll see that the author uses Path.GetFileName() to retrieve only the file's name before saving it in the proper folder. Your code should look like this::
[HttpPost]
public ActionResult Index(HttpPostedFileBase file) {
if (file.ContentLength > 0) {
var fileName = Path.GetFileName(file.FileName)
.Replace(" ","");
var finalName=String.Format("{0:yyyyMMddHHmm}._{1}",DateTime.Now,fileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), finalName);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
This ensures that only the filename part of the file is used, and that the file is saved in the appropriate folder, even if someone posted an invalid path
This is how you should be able to fix your problem
string nombre_archivo = string.Format("{0}_{1}", DateTime.Now.ToString("yyyyMMddHHmm."), info.file.FileName.Where(c => !Char.IsWhiteSpace(c))
EDIT :
You should use string.Replace instead of using Linq query.
There is a format problem I did not expect.
So, the right answer is given below, but basically, it would look like :
string nombre_archivo = string.Format("{0}_{1}", DateTime.Now.ToString("yyyyMMddHHmm."), info.file.FileName.Replace(" ", ""));
Related
Consider the following code snippet
public static string AppendDateTimeToFileName(this string fileName)
{
return string.Concat(
Path.GetFileNameWithoutExtension(fileName),
DateTime.Now.ToString("yyyyMMddHHmmssfff"),
Path.GetExtension(fileName));
}
This basically puts a date time stamp on any file that is being uploaded by the users. Now this works great is the file name is something like
MyFile.png
AnotherFile.png
Now I'm trying to change this method so if the file name is something like
MyFile - Copy(1).png
AnotherFile - Copy(1).png
I want the file name to become
MyFile-Copy-120170303131815555.png
AnotherFile-Copy-120170303131815555.png
If there an easy soltuion for this with regex or similar or do I have to re-write the method again and check each of those values one by one.
return string.Concat(
Regex.Replace(Path.GetFileNameWithoutExtension(fileName), #" - Copy\s*\(\d+\)", "-Copy-", RegexOptions.IgnoreCase),
DateTime.Now.ToString("yyyyMMddHHmmssfff"),
Path.GetExtension(fileName));
This matches any number of digits and is a global replace.
I am uploading image to a folder and saving its path in db.Here is my code.
[HttpPost]
public ActionResult UploadPic(FileManagement fmanage, HttpPostedFileBase file)
{
string email = User.Identity.Name;
if (file != null && file.ContentLength > 0)
{
var FileName = string.Format("{0}.{1}", Guid.NewGuid(), Path.GetFileName(file.FileName));
var path = Path.Combine(Server.MapPath("~/Content/Uploads"), FileName);
file.SaveAs(path);
using (var session = DocumentStore.OpenSession("RavenMemberShip"))
{
var query = from q in Session.Query<Registration>() where q.Email == email select q;
if (query.Count() > 0)
{
foreach (var updated in query)
{
updated.FileName = FileName;
updated.Path = path;
session.SaveChanges();
}
}
}
}
else
ModelState.AddModelError("", "Remove the errors and try again");
return View();
}
But the path is stored as double forward slash,which is wrong.How can i save the path as single slash.
Thanks in advance for help.
You said the path is stored with a "double forward slash", which would be //. I think you meant a "double backslash", which would be \\. Please provide an example if I am mistaken.
The double backslash is appropriate, because it escapes the backslash character. A value such as \n would be a newline, so an actual backslash has to be escaped as \\. This is part of how JSON stores strings.
However, you might want to consider only storing the file name into your document. The full path to the uploads folder is just going to be redundant. If you ever want to change it, then you should just be able to edit a setting instead of having to modify all of your documents.
Other issues with your code:
Remove this line:
if (query.Count() > 0)
It is unnecessary, and is causing the query to be executed twice.
This line:
session.SaveChanges();
Needs to be moved after your foreach loop. You only want a single batch of changes sent to RavenDB.
Use consistent naming conventions. The FileName local variable should be cased as fileName.
I have a reasonably straight-forward question here but I seem to find myself revisiting each time I have to deal with the validation of file paths and names. So I'm wondering if there is a method available in System.IO or some other library in the framework that can make my life easier!?
Lets take the contrived example of a method that takes a file path and a filename and from these inputs it formats and returns unique full file-location.
public string MakeFileNameUnique(string filePath, string fileName)
{
return filePath + Guid.NewGuid() + fileName;
}
I know that I must do the following to get the path in a correct format so that I can append the guid and filename:
if filePath is null or empty then throw exception
if filePath does not exist then throw exception
if no valid postfixed '/' then add one
if it contains a postfixed '\' then remove and replace with a '/'
Can someone tell me if there is a framework method that can do this(particularly the forwareslash/backslash logic) available to achieve this repetitive logic?
Are you looking for the Path.Combine method:
public string MakeFileNameUnique(string filePath, string fileName)
{
return Path.Combine(filePath, Guid.NewGuid().ToString(), fileName);
}
but looking at the name of your method (MakeFileNameUnique), have you considered using the Path.GenerateRandomFileName method? Or the Path.GetTempFileName method?
Following your requirements this will do
public string MakeFileNameUnique(string filePath, string fileName)
{
// This checks for nulls, empty or not-existing folders
if(!Directory.Exists(filePath))
throw new DirectoryNotFoundException();
// This joins together the filePath (with or without backslash)
// with the Guid and the file name passed (in the same folder)
// and replace the every backslash with forward slashes
return Path.Combine(filePath, Guid.NewGuid() + "_" + fileName).Replace("\\", "/");
}
a call with
string result = MakeFileNameUnique(#"d:\temp", "myFile.txt");
Console.WriteLine(result);
will result in
d:/temp/9cdb8819-bdbc-4bf7-8116-aa901f45c563_myFile.txt
However I wish to know the reason about the replace for the backslash with forward slashes
this code was working fine till this morning, can anyone spot my mistake? probably really silly but it has me stumped!
i use a form to submit a file (field name 'fileUpEx'), and then i wrote a class to upload it (like i said, it's been working for ages)....
(if i write 'filepath' to the page it is 'Test copy.pdf')
My class returns 'no groups'!!!
Very odd, can anyone please help?
string filepath = fileUpEx.PostedFile.FileName;
string pat = #"\\(?:.+)\\(.+)\.(.+)";
Regex r = new Regex(pat);
Match m = r.Match(filepath);
if (m.Groups[0].Captures.Count != 0)
{
//blaa blaa blaa
}
else
{
return "no Groups";
}
Thanks in advance,
Vauneen
Your regular expression requires that the file path contains a backslash which it doesn't. You could perhaps make that part optional, for example:
#"(?:\\.+\\)?(.+)\.(.+)"
Alternatively you could use the methods available in System.IO.Path:
string extension = Path.GetExtension(filePath);
string filename = Path.GetFilenameWithoutExtension(filePath);
I'd like to trim these purchase order file names (a few examples below) so that everything after the first "_" is omitted.
INCOLOR_fc06_NEW.pdf
Keep: INCOLOR (write this to db as the VendorID) Remove: _fc08_NEW.pdf
NORTHSTAR_sc09.xls
Keep: NORTHSTAR (write this to db as the VendorID) Remove: _sc09.xls
Our scenario: The managers are uploading these files to our Intranet web server, to make them available to download/view ect. I'm using Brettles NeatUpload, and for each file uploaded, am writing the files attributes into the PO table (sql 2000). The first part of the file name will be written to the DB as a VendorID.
The naming convention for these files is consistent in that the the first part of the file is always the vendor name (or Vendor ID) followed by an "_" then other unpredictable chars used to identify the type of Purchase Order then the file extention - which is consistently either .xls, .XLS, .PDF, or .pdf.
I tried TrimEnd - but the array of chars that you have to provide ends up being long and can conflict with the part of the file name I want to keep. I have a feeling I'm not using TrimEnd properly.
What is the best way to use string.TrimEnd (or any other string manipulation in C#) that will strip off all chars after the first "_" ?
String s = "INCOLOR_fc06_NEW.pdf";
int index = s.IndexOf("_");
return index >= 0 ? s.Substring(0,index) : s;
I'll probably offend the anti-regex lobby, but here I go (ducking):
string stripped = Regex.Replace(filename, #"(?<=[^_]*)_.*",String.Empty);
This code will strip all extra characters after the first '_', unless there is no '_' in the string (then it will just return the original string).
It's one line of code. It's slower than the more elaborate IndexOf() algorithm, but when used in a non-performance-sensitive part of the code, it's a good solution.
Get your flame-throwers out...
TrimEnd removes white spaces and punctuation marks at the end of the String, it won't help you here. Read more about TrimEnd here:
http://msdn.microsoft.com/en-us/library/system.string.trimend.aspx
Bnaffas code (with a small tweak):
String fileName = "INCOLOR_fc06_NEW.pdf";
int index = fileName.IndexOf("_");
return index >= 0 ? fileName.Substring(0, index) : fileName;
If you want to do something with the other parts, you could use a Split
string fileName = "INCOLOR_fc06_NEW.pdf";
string[] parts = fileName.Split('_');
public string StripOffStuff(string sInput)
{
int iIndex = sInput.IndexOf("_");
return (iIndex > 0) ? sInput.Substring(0, iIndex) : sInput;
}
// Call it like:
string sNewString = StripOffStuff("INCOLOR_fc06_NEW.pdf");
I would go with the SubString approach but to round out the available solutions here's a LINQ approach just for fun:
string filename = "INCOLOR_fc06_NEW.pdf";
string result = new string(filename.TakeWhile(c => c != '_').ToArray());
It'll return the original string if no underscore is found.
To go with all the "alternative" solutions, here's the second one that I thought of (after substring):
string filename = "INCOLOR_fc06_NEW.pdf";
string stripped = filename.Split('_')[0];