Search code examples
c#asp.net-mvcentity-frameworkasp.net-corefile-upload

Automated way to code for uploading file in ASP.NET Entity Framework


I am fairly new to this topic. I can somehow make the code work to upload a file like picture by coding everything from scratch but with ASP.NET MVC and Entity Framework being so automated these days through scaffolding, I assume there must be a very straightforward way to add file upload to a scaffolded Entity Framework solution.

Does anyone know about such a way?


Solution

  • To upload a file in your ASP.NET Core project, you should first insert some lines in your View .cshtml file, like these (I prefer to use javascript code to upload and POST the file, so I can put a progress bar also):

    <script type="text/javascript">
    
    function uploadFile(currentForm) {
    
        let File1 = currentForm.querySelector("#File1").files[0];
    
        let fileName = currentForm.querySelector("#File1").value;
        fileName = fileName.substr(fileName.lastIndexOf("\\")).substr(1);
        currentForm.querySelector("#fileName").innerHTML = fileName;
    
        let data = new FormData();
        data.append("file", File1);
    
        let request = new XMLHttpRequest();
        let url = "/Home/UploadFile";
        let filePath = "";
        currentForm.querySelector("#progressBar").hidden = false;
    
        request.addEventListener("load", function (e) {
            filePath = request.responseText;            
            currentForm.querySelector("#fileLoaded").innerHTML = filePath;
        });
    
        request.upload.addEventListener("progress", function (e) {
            let percentual = (e.loaded / e.total) * 100;
            currentForm.querySelector("#progressBar").value = percentual;
        });
    
        request.open("POST", url);
        request.send(data);
    }
    
    </script>
    
    <form id="Form1" method="post" enctype="application/x-www-form-urlencoded">    
        <!-- with this enctype the file will not be submitted with the form -->
    
        <input type="file" id="File1" name="File1" onchange="uploadFile(this.form)" style="display:none">
        <input type="button" value="Choose..." onclick="this.form.querySelector('#File1').click()">
        <span id="fileName"></span>                
        <progress hidden id="progressBar" value="0" max="100"></progress>
        <br />
        <label id="fileLoaded"> Uploaded file path: None </label>
        
    </form>
    

    After that, you need an action (here is in your HomeController) which receives the file posted from the web with javascript, saving it in a server folder, and putting its URL in a property of your Entity Framework database context model (ie. FileRow containing UploadedFileURL):

    public class HomeController : Controller
    {
        private readonly ApplicationDbContext _dbContext;
        private readonly IWebHostEnvironment _hostEnvironment;
    
        public HomeController(ApplicationDbContext dbContext, IWebHostEnvironment hostEnvironment)
        {
            _dbContext = dbContext;
            _hostEnvironment = hostEnvironment;
        }
    
        [HttpPost]
        public ContentResult UploadFile()
        {
    
            string filePath = "";
            string fileName = "";
    
            if (Request.Form.Files.Count > 0)
            {
                IFormFile file = Request.Form.Files[0];
    
                if (file != null && file.Length > 0)
                {
                    fileName = Path.GetFileName(file.FileName);
                    filePath = _hostEnvironment.WebRootPath + @"/Uploads/" + fileName;
                    using (FileStream stream = new FileStream(filePath, FileMode.Create))
                    {
                        file.CopyTo(stream);                        
                    }
                    
                    FileRow fileRow = new FileRow()
                    {
                        UploadedFileURL = filePath
                    };                                    
                    _dbContext.Add(fileRow);
                    _dbContext.SaveChanges();
                }
            }                                    
            return Content(filePath);
        }
    }
    

    The file will be saved in wwwroot/Uploads folder.