Reputation: 489
Trying to upload a file as part of a form and store it in a folder in wwwroot then store the url for the file in a sql server database table along with the other details of the form? If anyone has any ideas it would be greatly appriciated. I have used this code but it does not store anything. However when i created a fresh new project i managed to get the code working on that correctly but cannot seem to get it to work in this work project. Not sure if it has something to do with the fact i have repositories and the fresh project i created that did work didnt have any repositories. That is the only difference i can think of. Any ideas?
//Model
namespace PostProjectEvaluations.Web.Models
{
public partial class Projects
{
[Key]
public int ProjectId { get; set; }
[Required]
[StringLength(300)]
public string Name { get; set; }
[Required]
[StringLength(50)]
public string Manager { get; set; }
public string FilePath { get; set; }
}
public class ProjectsVM
{
public string Name { get; set; }
public IFormFile File { get; set; }
}
//Controller
namespace PostProjectEvaluations.Web.Controllers
{
public class projectsController : Controller
{
private readonly IApplicationRepository ApplicationRepository;
private readonly PostProjectEvaluationsContext _context;
private IHostingEnvironment mxHostingEnvironment { get; set; }
private object objproject;
public projectsController(IApplicationRepository applicationRepository,
IHostingEnvironment hostingEnvironment, PostProjectEvaluationsContext context)
{
mxHostingEnvironment = hostingEnvironment;
ApplicationRepository = applicationRepository;
_context = context;
}
public IActionResult Index()
{
ViewBag.dataSource = ApplicationRepository.GetAllProjects().ToList();
var projects = ApplicationRepository.GetAllProjects();
return View(projects);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(ProjectsVM projectsVM)
{
if (projectsVM.File != null)
{
//upload files to wwwroot
var fileName = Path.GetFileName(projectsVM.File.FileName);
var filePath = Path.Combine(mxHostingEnvironment.WebRootPath, "Uploads", fileName);
using (var fileSteam = new FileStream(filePath, FileMode.Create))
{
await projectsVM.File.CopyToAsync(fileSteam);
}
//your logic to save filePath to database, for example
Projects projects = new Projects();
projects.Name = projectsVM.Name;
projects.FilePath = filePath;
_context.Projects.Add(projects);
_context.SaveChanges();
}
else
{
}
return View("Index");
}
public IActionResult Details(int id)
{
var project = ApplicationRepository.GetProjects(id);
return View(project);
}
[HttpGet]
public IActionResult Create()
{
var project = new Projects();
return View(project);
}
[HttpPost]
public IActionResult Create(Projects projects)
{
ApplicationRepository.Create(projects);
return RedirectToAction("Index");
}
public IActionResult Delete(int id)
{
var project = ApplicationRepository.GetProjects(id);
ApplicationRepository.Delete(project);
return RedirectToAction("Index");
}
[HttpGet]
public IActionResult Edit(int id)
{
var project = ApplicationRepository.GetProjects(id);
//mxApplicationRepository.SaveChangesAsync();
return View(project);
}
[HttpPost]
public IActionResult Edit(Projects projects)
{
ApplicationRepository.Edit(projects);
//mxApplicationRepository.SaveChangesAsync();
return RedirectToAction("Index");
}
}
}
//View
<form enctype="multipart/form-data" asp-controller="Projects" asp-action="Create" method="post" class="form-horizontal">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-body">
<h3 class="form-section">Project Info</h3>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-3">Project Name</label>
<div class="col-md-9">
<input asp-for="Name" class="form-control" placeholder="Name">
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
</div>
<!--/span-->
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-3">Project Manager</label>
<div class="col-md-9">
<input asp-for="Manager" class="form-control" placeholder="Name">
</div>
</div>
</div>
<!--/span-->
</div>
<!--/span-->
</div>
<h3 class="form-section">Project Files</h3>
<!--/row-->
<div class="row">
<div>
<div class="col-md-6">
<div class="col-md-10">
<p>Upload one or more files using this form:</p>
<input type="file" name="files" multiple />
</div>
</div>
</div>
<div>
</div>
</div>
<div class="form-actions right">
<input type="submit" class="btn blue-assembly" name="submitButton" value="Save" />
<a asp-action="Index" class="btn default" onclick="cancelClick()">Cancel</a>
</div>
</form>
Upvotes: 3
Views: 13071
Reputation: 25
Try the following code
if (ModelState.IsValid)
{
string folder = null;
if (model.File != null)
{
if (model.File.Length > 0)
{
Guid guid1 = Guid.NewGuid();
folder = "/attachement/docs/" + guid1 + model.File.FileName;
string uploadFolder = Path.Combine(webHostEnvironment.WebRootPath, "attachement/docs");
string uniqueFileName = guid1 + model.File.FileName;
string filePath = Path.Combine(uploadFolder, uniqueFileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await model.FormFile.CopyToAsync(stream);
}
}
}}
And for uploading multiple files, first you have to define this in Model
public List<IFormFile> ImageFiles { get; set; }
and in Model constructor
ImageFiles = new List<IFormFile>();
and then use the following code
foreach (var file in model.ImageFiles)
{
if (file.Length > 0)
{
Guid guid = Guid.NewGuid();
folder = "/attachement/images/" + guid + file.FileName;
string uploadFolder = Path.Combine(webHostEnvironment.WebRootPath, "attachement/images");
string uniqueFileName = guid + file.FileName;
string filePath = Path.Combine(uploadFolder, uniqueFileName);
// string filePath = Path.Combine(uploadFolder, model.FormFile.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
await context.GraspProgressDetails.AddAsync(new GraspProgressDetail
{
GraspProgressId = result.Entity.ProgressId,
ImageUrl = folder
});
}
}
Upvotes: 0
Reputation: 20106
You could use IFormFile
to receive the file.And then save the file path url to your database using EF core. Remember to create a myFiles
folder where to save uploaded files under wwwroot
firstly.
You could refer to the tutorial of File uploads in ASP.NET Core
Below is a simple demo:
Models:
public class Engineer
{
public int Id { get; set; }
public string Name { get; set; }
public string FilePath { get; set; }
}
public class EngineerVM
{
public string Name { get; set; }
public IFormFile File{ get; set; }
}
View:
@model EngineerVM
<form method="post" enctype="multipart/form-data" asp-controller="Home" asp-action="Index">
<div class="form-group">
<div class="col-md-10">
<input type="text" asp-for="Name" />
</div>
<div class="col-md-10">
<p>Upload one or more files using this form:</p>
<input type="file" name="file"/>
</div>
</div>
<div class="form-group">
<div class="col-md-10">
<input type="submit" value="Save" />
</div>
</div>
</form>
Controller:
public class HomeController : Controller
{
private readonly IHostingEnvironment _hostingEnv;
private readonly ApplicationDbContext _context;
public HomeController(IHostingEnvironment hostingEnv,ApplicationDbContext context)
{
_hostingEnv = hostingEnv;
_context = context;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(EngineerVM engineerVM)
{
if (engineerVM.File != null)
{
//upload files to wwwroot
var fileName = Path.GetFileName(engineerVM.File.FileName);
var filePath = Path.Combine(_hostingEnv.WebRootPath, "images", fileName);
using (var fileSteam = new FileStream(filePath, FileMode.Create))
{
await engineerVM.File.CopyToAsync(fileSteam);
}
//your logic to save filePath to database, for example
Engineer engineer = new Engineer();
engineer.Name = engineerVM.Name;
engineer.FilePath = filePath;
_context.Engineers.Add(engineer);
await _context.SaveChangesAsync();
}
else
{
}
return View();
}
}
Upvotes: 3