skip to Main Content

I have a controller, which I will include the methods for at the end. I allow users to upload either .DOC, .DOCX or .PDF files via my POST method.

I then have a GET method which I can currently return a file from, but it is hardcoded to .PDF. I want to know how I would enable my GET method read from any of the file types above? Or how would I get the file extension of a file, before I have read it into a stream?

If you have any feedback on my approach to either method, feedback is welcome!

    [HttpGet("Download/{requestId}/{lineNumber}")]
    public IActionResult Download([FromRoute] long requestId, [FromRoute] int lineNumber)
    {
        string fileName = requestId.ToString() + lineNumber.ToString();
        string fileDownloadName = fileName + DateTime.Now.ToString("ddMMyyyy");
        try
        {
            FileStream stream = new(GetFilePath() + fileName + ".pdf", FileMode.Open);
            return File(stream, "application/pdf", fileDownloadName + ".pdf");
        }

        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }

    [HttpPost("Upload/{requestId}/{lineNumber}")]
    public async Task<IActionResult> OnPostUploadAsync(IFormFile formFile, [FromRoute] long requestId, [FromRoute] int lineNumber)
    {
        try
        {
            if (formFile.Length > 0)
            {
                string filename = formFile.FileName;
                string filepath = GetFilePath();
                string docId = requestId.ToString() + lineNumber.ToString();

                var supportedTypes = new[] { "doc", "docx", "pdf" };
                var fileExt = System.IO.Path.GetExtension(formFile.FileName).Substring(1);

                string concessionDocumentPath = filepath + "\" + docId + "." + fileExt;

                if (!supportedTypes.Contains(fileExt))
                {
                    string ErrorMessage = "File Extension Is Invalid - Only Upload WORD/PDF File";
                    return BadRequest(ErrorMessage);
                }

                if (!System.IO.Directory.Exists(filepath))
                {
                    System.IO.Directory.CreateDirectory(filepath);
                }

                if (System.IO.File.Exists(concessionDocumentPath))
                {
                    System.IO.File.Delete(concessionDocumentPath);
                }
                using (FileStream stream = System.IO.File.Create(concessionDocumentPath))
                {
                    await formFile.CopyToAsync(stream);
                }
            }
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }

        return Ok(formFile.FileName.ToString() + " was uploaded successfully");
    }

    [NonAction]
    private string GetFilePath()
    {
        return this._environment.WebRootPath + "\Uploads\ConcessionDocuments\";
    }

2

Answers


  1. Chosen as BEST ANSWER

    With thanks to @WisdomSeeker for his help, I was able to get a solution in place. Instead of using GetFiles, I used EnumerateFiles

    I'm doubtful it's the most effective, or best way to do this, but it works for what I need.

        [HttpGet("Download/{requestId}/{lineNumber}")]
        public IActionResult Download([FromRoute] long requestId, [FromRoute] int lineNumber)
        {
            string fileName = requestId.ToString() + lineNumber.ToString();
            string fileDownloadName = fileName + DateTime.Now.ToString("ddMMyyyy");
            string extension = null!;
            string mimeType = null!;
            string filePath;
    
            try
            {
                IEnumerable<string> directory = Directory.EnumerateFiles(GetFilePath(), fileName + "*");
    
                if (directory.Any())
                {
                    filePath = directory.FirstOrDefault()!;
    
                    if (filePath.EndsWith(".pdf"))
                    {
                        extension = ".pdf";
                        mimeType = "application/pdf";
                    }
                    else if (filePath.EndsWith(".doc"))
                    {
                        extension = ".doc";
                        mimeType = "application/msword";
                    }
                    else if (filePath.EndsWith(".docx"))
                    {
                        extension = ".docx";
                        mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                    }
    
                    FileStream stream = new(GetFilePath() + fileName + extension, FileMode.Open);
    
                    return File(stream, mimeType, fileDownloadName + extension);
                }
                else
                {
                    return BadRequest();
                }
    
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }
    

  2. One way I could think of for getting the file extension is

    DirectoryInfo di = new DirectoryInfo(GetFilePath());
    FileInfo fileInfo = di.GetFiles().FirstOrDefault();
    
    string fileExtension = System.IO.Path.GetExtension(fileInfo.FullName);
    

    and you could use this extension in the hardcoded part.

    Here I assumed you have only one file in the directory. Now if you have multiple files in the directory, try to identify the file using
    searchPattern overload of GetFiles.

    Hope this helps.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search