Uploaded file not being saved to directory - c#

I am trying to upload a file using devexpress save as function which works exact same as the standard asp.net uploader but i am getting the following error
Could not find a part of the path 'C:\Projects\fhs\fhs\Uploads\documents\VX00150\Barry Allen\Aperture - Signature Template.docx'.
UploadDirectory refers to a virutal directory setup in the web config which im getting via the property.
string UploadDirectory = WebConfigurationManager.AppSettings["uploadDirectory"].ToString();
Which contains the directory
<add key="uploadDirectory" value="~\Uploads\" />
But for the live of me I cannot see why the file is not saving to the server
protected void UploadControl_FileUploadComplete(object sender, FileUploadCompleteEventArgs e)
{
UploadControl.Enabled = false;
string id = Request.QueryString["Case"];
if (id != null)
{
CaseId = Guid.Parse(id);
OpenCase = _dal.GetCaseById(Guid.Parse(id));
}
string PersonId = Session["CurrentPersonalMainID"].ToString();
Personal = _dal.GetPersonalByPersonalId(new Guid(PersonId));
e.CallbackData = SavePostedFile(e.UploadedFile, OpenCase.CaseReference, Personal.firstName, Personal.lastName);
}
The below saved postedfile is called from above
public string SavePostedFile(UploadedFile uploadedFile,string IVACaseRef, string firstName ,string lastName)
{
try
{
if (!uploadedFile.IsValid)
return string.Empty;
string fileName = uploadedFile.FileName;
FileInfo fileInfo = new FileInfo(uploadedFile.FileName);
string fullFileName = CombinePath(fileName);
string docsPath = UploadDirectory + #"documents\" + IVACaseRef + #"\" + firstName + " " +
lastName + #"\";
string resFileName =docsPath + fileInfo.Name;
bool exists = System.IO.Directory.Exists(resFileName);
if (!exists)
System.IO.Directory.CreateDirectory(docsPath);
uploadedFile.SaveAs(Server.MapPath(resFileName), true);
System.Net.Mail.Attachment attachment;
attachment = new System.Net.Mail.Attachment(resFileName.ToString());
// we need to reget this as issue with postback and the fileuplaod
FormsIdentity _identity = (FormsIdentity)Context.User.Identity;
_identity = (FormsIdentity)Context.User.Identity;
return fileName;
}
catch (Exception ex)
{
string inner = string.Empty;
if (ex.InnerException != null)
{
inner = ex.InnerException.ToString();
}
// logger.Error("Error in GetNotificationById function aperturenetdal " + ex.ToString() + " " + inner);
return "";

I've noticed that a lot of file manipulation methods and classes differ in how they handle spaces, sometimes in ways that are not well documented. For example, I've seen situations where testing for the existence of a file with a space in the filename succeeds but opening it does not.
It's just a hunch, but it seems likely.

Related

can't use replace function when upload files API on asp.net core 2.2

I work on ASP.NET Core 2.2 Web API and face an issue: I can't use replace function to change the name property of a selected file that I get when uploaded.
When I try like this:
string fileName = DisplayFileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";
I get an error
Iform file doesn't contain definition for replace and no accessible extension method Replace accepting first argument of iformfile
Full sample is here:
[HttpPost, DisableRequestSizeLimit]
public IActionResult Upload()
{
try
{
var DisplayFileName = Request.Form.Files[0];
string fileName = DisplayFileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";
string Month = DateTime.Now.Month.ToString();
string DirectoryCreate = myValue1 + Month;
Path.Combine(Directory.GetCurrentDirectory(), folderName);
if (!Directory.Exists(DirectoryCreate))
{
Directory.CreateDirectory(DirectoryCreate);
}
if (DisplayFileName.Length > 0)
{
var filedata = ContentDispositionHeaderValue.Parse(Request.Form.Files[0].ContentDisposition).FileName.Trim('"');
var dbPath = Path.Combine(DirectoryCreate, fileName);
using (var stream = new FileStream(dbPath, FileMode.Create))
{
Request.Form.Files[0].CopyTo(stream);
}
return Ok(new { dbPath });
}
else
{
return BadRequest();
}
}
catch (Exception ex)
{
return StatusCode(500, $"Internal server error: {ex}");
}
}
How to solve this issue?
sample
suppose i select file developed.xlsx
then after use replace or any way result will be
developed-sddfn78888.xlsx
You can use System.IO.Path to get filename and get file extension from request files.
Change this
string fileName = DisplayFileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";
To
string filename = Path.GetFileName(DisplayFileName.FileName);
string fileExtension = Path.GetExtension(DisplayFileName.FileName);
string newFileName = $"{filename}-{Guid.NewGuid().ToString()}{fileExtension}";
Otherwise, you could modify your code to
string fileName = DisplayFileName.FileName.Replace(".xlsx", "-") + Guid.NewGuid().ToString() + ".xlsx";

ASP.Net FileUpload: Rename file name before saving if already exists

I need change file name when users upload from file upload control.
If file name be duplicate it add count at file name but here it doesn't work.
I mean when I upload file i.e. 00076007-2013.pdf it saves in the host with this name 00076007-2013(0).pdf
But when again I want upload 00076007-2013.pdf in host it overwrite last (00076007-2013(0).pdf).
But I want if there was 00076007-2013.pdf file it saves with this name 00076007-2013(1).pdf in host.
How I can solve this problem.
My code below.
int count = 0;
string fileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
string FileExstention = Path.GetExtension(FileUpload1.FileName);
string[] files = Directory.GetFiles(Server.MapPath("/public/2Version/sk_PDF/"));
if (FileUpload1.HasFile)
{
if (FileExstention == ".pdf")
{
try
{
if (File.Exists(Server.MapPath("/public/2Version/sk_PDF/") + fileName.ToString()))
{
foreach (string s in files)
{
string filename = string.Empty;
filename = Path.GetFileName(s).Substring(0, Path.GetFileName(s).LastIndexOf("."));
if (filename.Contains("("))
{
filename = filename.Substring(0, filename.LastIndexOf("("));
}
if (filename == fileName.ToString().Trim())
{
count++;
}
FileUpload1.PostedFile.SaveAs(Server.MapPath("/public/2Version/sk_PDF/") + filename.ToString() + "(" + count.ToString() + ")" + FileExstention);
}
}
else
{
FileUpload1.PostedFile.SaveAs(Server.MapPath("/public/2Version/sk_PDF/") + fileName.ToString());
}
}
catch (Exception ex)
{
throw ex;
}
}
}
Edit #01
This is the output.
I have upload the 00076007-2013.pdf file for three times.
The first time OK, 00076007-2013.pdf.
The second time OK, 00076007-2013(0).pdf.
The last time he was saved 00076007-2013(0).pdf and not 00076007-2013(1).pdf
Please change this part :
if (filename.Contains("("))
{
filename = filename.Substring(0, filename.LastIndexOf("("));
}
With :
if (filename.Contains("("))
{
filename = filename.Substring(0, filename.LastIndexOf("("));
count++;
}
I hope I was helpful.

ASP.NET Core API 500 Internal Server Error when uploading file on IIS

i am working on a API Project which require a functionality to upload a file. When i run the project on localhost and trying to upload a file it works perfectly, but when i publish the project and deploy it on IIS the upload functionality it's not working and produce 500 Internal Server Error.
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class UserFilesController : ControllerBase
{
private IConfiguration configuration;
public UserFilesController(IConfiguration iConfig)
{
configuration = iConfig;
}
[HttpPost]
public async Task<IActionResult> PostFormData([FromForm]IFormFile file)
{
var dict = new Dictionary<string, string>();
HttpContext.User.Claims.ToList()
.ForEach(item => dict.Add(item.Type, item.Value));
string userid = dict.ElementAt(2).Value;
FileConverter fileConverter = new FileConverter();
if (file == null || file.Length == 0)
return Content("file not selected");
var path = Path.Combine(
Directory.GetCurrentDirectory(), "File",
file.FileName);
string ext = Path.GetExtension(file.FileName);
string newFileName = Guid.NewGuid().ToString();
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "File", newFileName+ext);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
fileConverter.ConvertToPdf(filePath, newFileName);
var pdfPath = Path.Combine(
Directory.GetCurrentDirectory(), "File",
newFileName+".pdf");
DateTime ExpiredOn = DateTime.Now.AddDays(1);
DateTime CreatedOn = DateTime.Now;
string fileUrl = "/File/" + newFileName + ext;
string pdfUrl = "/File/" + newFileName + ".pdf";
using (var connection = new NpgsqlConnection(configuration.GetValue<string>("dbServer:connectionData")))
{
connection.Open();
try
{
string createdon = CreatedOn.ToString("yyyy-MM-dd HH:mm:ss").Replace(".", ":");
string expiredon = ExpiredOn.ToString("yyyy-MM-dd HH:mm:ss").Replace(".", ":");
var value = connection.Execute(
"INSERT INTO uf (ufid, name, oriformat, fileurl, pdfurl, createdon, expiredon, isdeleted, systemuserid) VALUES (uuid_generate_v4(), '" + file.FileName + "', '" + ext.Replace(".","") + "', '" + fileUrl + "', '" + pdfUrl + "', '" + createdon + "', '" + expiredon + "', false, '" +userid+ "');"
);
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
TableUserFileBaru result = new TableUserFileBaru();
using (var connection = new NpgsqlConnection(configuration.GetValue<string>("dbServer:connectionData")))
{
connection.Open();
try
{
var value = connection.Query<TableUserFileBaru>(
"select * from uf where systemuserid = '"+userid+"' order by createdon desc;"
);
result = value.First();
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
string ori_format = result.oriformat.ToString().Replace(".", "");
PostUserFileResp resp = new PostUserFileResp();
resp.UFId = result.ufid.ToString();
resp.Name = result.name;
resp.OriFormat = ori_format;
resp.FileURL = result.fileurl;
resp.PdfURL = result.pdfurl;
resp.CreatedOn = result.createdon;
resp.ExpiredOn = result.expiredon;
resp.SystemUserId = result.systemuserid;
resp.IsDeleted = result.isdeleted;
return Ok(resp);
}
}
UPDATE :
After i followed ArunPratap's step to show the error detail i got this following message.
An unhandled exception occurred while processing the request.UnauthorizedAccessException: Access to the path 'C:\inetpub\wwwroot\NetCore\File\7ebb3a76-f194-41f2-8a4b-a576308856aa.pdf' is denied. System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)
After i
Did anyone know how to solve it?
Thanks.
You can create a System Environment variable named ASPNET_ENV and set its value to Development and call the UseDeveloperExceptionPage() method. that will show the details of the error and after that, you can fix that
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
Update
As now you are getting request.UnauthorizedAccessException: Access to the path denied Try to go to App_Data folder property and add ASPNET user with reading and write privileges
Look for instruction

Assignment inside IF statement

string Newfilename;
string Defaultfilename;
protected void btnup_Click(object sender, EventArgs e)
{
if (ASPxUploadControl1.HasFile)
{
string fileExt =
Path.GetExtension(ASPxUploadControl1.FileName);
if (fileExt == ".xls" || fileExt == ".xlsx")
try
{
string extension = Path.GetExtension(ASPxUploadControl1.FileName);
string id = Guid.NewGuid().ToString();
string fileLocation = string.Format("{0}/{1}{2}", Server.MapPath("upload/"), id, extension);
ASPxUploadControl1.SaveAs( fileLocation );
StatusLabel.Text = "Upload status: File uploaded!";
Newfilename = fileLocation;
Defaultfilename = Path.GetFileName(ASPxUploadControl1.FileName);
}
catch (Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
}
else
{
StatusLabel.Text = "Please choose excel file";
}
}
}
I am trying to assign values to Newfilename and Defaultfilename (inside "try", after naming uploaded file), but they stay empty.
Where I'm wrong?
Refactor your code and think about the process that you want .. then Debug the Code.. Test it.. and if you have an Issue then edit your post.. that's what I suggest..
If statements should be wrapped with in a code block "{ }" same way that you have Try {} a good rule of thumb for even readability would be to wrap everthing around {} if you have If Else otherwise it makes if hard to read as well as lend assistance.
inside your code where you are declaring the following, make them variables within the method itself
string fileExt = string.Empty;
string extension = string.Empty;
string id = string.Empty;
string fileLocation = string.Empty;
so your method would look like this
protected void btnup_Click(object sender, EventArgs e)
{
string fileExt = string.Empty;
string extension = string.Empty;
string id = string.Empty;
string fileLocation = string.Empty;
if (ASPxUploadControl1.HasFile)
{
fileExt = Path.GetExtension(ASPxUploadControl1.FileName);
if (fileExt == ".xls" || fileExt == ".xlsx")
{
try
{
extension = Path.GetExtension(ASPxUploadControl1.FileName);
id = Guid.NewGuid().ToString();
fileLocation = string.Format("{0}/{1}{2}", Server.MapPath("upload/"), id, extension);
ASPxUploadControl1.SaveAs( fileLocation );
StatusLabel.Text = "Upload status: File uploaded!";
Newfilename = fileLocation;
Defaultfilename = Path.GetFileName(ASPxUploadControl1.FileName);
}
catch (Exception ex)
{
StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
}
}
else
{
StatusLabel.Text = "Please choose excel file";
}
}
}
Path.GetExtension returns null if the passed value is null and returns string.Empty if the passed value doesn't have an extension.
So please check if the value inside ASPxUploadControl1.FileName actually contains something usefull.
If this is not the case then you'll have to look up where the value is set and debug from there to find out why it's not set.
Can you step through the execution?
Does
NewFilename = fileLocation;
get executed?
If so, what are the values for NewFilename before and after?
This looks like ASP.Net code.
If it is. Is the problem that when you try to use NewFilename elsewhere in the code-behind is is blank.
If you are, then NewFilename may need to be saved to the session to allow you to use it.
hth,
Alan.

c# service renaming files!

I have a windows service , that takes files with metadata(FIDEF) and corresponding video file and , translates the XML(FIDEF) using XSLT .
I get the file directory listing for FIDEF's and if a video file of the same name exists it translates it. That works ok , but it is on a timer to search every minute. I am trying to handle situations where the same file name enters the input directory but is already in the output directory. I just have it changing the output name to (copy) thus if another file enters i should get (copy)(copy).mov but the service won't start with filenames of the same directory already in the output , it works once and then does not seem to pick up any new files.
Any Help would be great as I have tried a few things with no good results. I believe its the renaming methods, but I've put most of the code up in case its a clean up issue or something else.
(forgive some of the names just trying different things).
private void getFileList()
{
//Get FILE LIST FROM Directory
try
{
// Process Each String/File In Directory
string result;
//string filename;
filepaths = null;
filepaths = Directory.GetFiles(path, Filetype);
foreach (string s in filepaths)
{
for (int i = 0; i < filepaths.Length; i++)
{
//Result Returns Video Name
result = Path.GetFileNameWithoutExtension(filepaths[i]);
FileInfo f = new FileInfo(filepaths[i]);
PreformTranslation(f, outputPath + result , result);
}
}
}
catch (Exception e)
{
EventLog.WriteEntry("Error " + e);
}
}
private void MoveVideoFiles(String Input, String Output)
{
File.Move(Input, Output);
}
private string GetUniqueName(string name)
{
//Original Filename
String ValidName = name;
//remove FIDEF from filename
String Justname1 = Path.GetFileNameWithoutExtension(name);
//get .mov extension
String Extension2 = Path.GetExtension(Justname1);
//get filename with NO extensions
String Justname = Path.GetFileNameWithoutExtension(Justname1);
//get .Fidef
String Extension = Path.GetExtension(name);
int cnt = 0;
//string[] FileName = Justname.Split('(');
//string Name = FileName[0];
while (File.Exists(ValidName)==true)
{
ValidName = outputPath + Justname + "(Copy)" + Extension2 + Extension;
cnt++;
}
return ValidName;
}
private string getMovFile(string name)
{
String ValidName = name;
String Ext = Path.GetExtension(name);
String JustName = Path.GetFileNameWithoutExtension(name);
while(File.Exists(ValidName))
{
ValidName = outputPath + JustName + "(Copy)" + Ext;
}
return ValidName;
}
//Preforms the translation requires XSL & FIDEF name.
private void PreformTranslation(FileInfo FileName, String OutputFileName , String result)
{
string FidefName = OutputFileName + ".FIDEF";
String CopyName;
String copyVidName = outputPath + result;
XslCompiledTransform myXslTransform;
myXslTransform = new XslCompiledTransform();
try
{
myXslTransform.Load(XSLname);
}
catch
{
EventLog.WriteEntry("Error in loading XSL");
}
try
{ //only process FIDEF's with corresponding Video file
if (AllFidef == "no")
{
//Check if video exists if yes,
if (File.Exists(path + result))
{
//Check for FIDEF File Already Existing in the Output Directory.
if (File.Exists(FidefName))
{
//Get unique name
CopyName = GetUniqueName(FidefName);
copyVidName= getMovFile(copyVidName);
//Translate and create new FIDEF.
//double checking the file is here
if (File.Exists(outputPath + result))
{
myXslTransform.Transform(FileName.ToString(), CopyName);
File.Delete(FileName.ToString());
MoveVideoFiles(path + result, copyVidName);
}
////Move Video file with Corresponding Name.
}
else
{ //If no duplicate file exsists in Directory just move.
myXslTransform.Transform(FileName.ToString(), OutputFileName + ".FIDEF");
MoveVideoFiles(path + result, outputPath + result);
}
}
}
else
{
//Must have FIDEF extension
//Processes All FIDEFS and moves any video files if found.
myXslTransform.Transform(FileName.ToString(), OutputFileName + ".FIDEF");
if (File.Exists(path + result))
{
MoveVideoFiles(path + result, outputPath + result);
}
}
}
catch (Exception e)
{
EventLog.WriteEntry("Error Transforming " + "FILENAME = " + FileName.ToString()
+ " OUTPUT_FILENAME = " + OutputFileName + "\r\n" +"\r\n"+ e);
}
}
There is a lot wrong with your code. getFileList has the unneeded inner for loop for starters. Get rid of it. Your foreach loop has s, which can replace filepaths[i] from your for loop. Also, don't do outputPath + result to make file paths. Use Path.Combine(outputPath, result) instead, since Path.Combine handles directory characters for you. Also, you need to come up with a better name for getFileList, since that is not what the method does at all. Do not make your method names liars.
I would simply get rid of MoveVideoFiles. The compiler just might too.
GetUniqueName only works if your file name is of the form name.mov.fidef, which I'm assuming it is. You really need better variable names though, otherwise it will be a maintenance nightware later on. I would get rid of the == true in the while loop condition, but that is optional. The assignment inside the while is why your files get overwritten. You always generate the same name (something(Copy).mov.fidef), and as far as I can see, if the file exists, I think you blow the stack looping forever. You need to fix that loop to generate a new name (and don't forget Path.Combine). Maybe something like this (note this is untested):
int copyCount = 0;
while (File.Exists(ValidName))
{
const string CopyName = "(Copy)";
string copyString = copyCount == 0 ? CopyName : (CopyName + "(" + copyCount + ")");
string tempName = Justname + copyString + Extension2 + Extension;
ValidName = Path.Combine(outputPath, tempName);
copyCount++;
}
This generates something(Copy).mov.fidef for the first copy, something(Copy)(2).mov.fidef for the second, and so on. Maybe not what you want, but you can make adjustments.
At this point you have a lot to do. getMovFile looks as though it could use work in the same manner as GetUniqueName. You'll figure it out. Good luck.

Categories