Hi I want to upload my files to the filesystem after I have pressed the "save" button in the Edit view. To do that I am trying to call the UploadToFileSystem method inside the Edit (POST) action.
This is what it looked like before I call UploadToFileSystem in a button that uses only that method and it worked.
BEFORE:
Debugging in VS Code showing UploadToFileSystem being called by it's self.">
AFTER: (Where it didn't work.)
Debugging in VS Code showing UploadToFileSystem being called by it's self.
ProblemsController.cs
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,ProblemTitle,ProblemDescription,ProblemStartDate,ProblemFileAttachments,ProblemSeverity,ProblemComplete")] Problem problem, List<IFormFile> iFormFile)
{
if (id != problem.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(problem);
await _context.SaveChangesAsync();
await UploadToFileSystem(iFormFile ,problem.ID, problem.ProblemTitle, problem.ProblemDescription,
problem.ProblemStartDate, problem.ProblemSeverity);
}
catch (DbUpdateConcurrencyException)
{
if (!ProblemExists(problem.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(problem);
}
[HttpPost]
public async Task<IActionResult> UploadToFileSystem(List<IFormFile> files, int? id, string title,
string description, DateTime dateTime, int severity)
{
foreach (var file in files)
{
var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\Files\\");
bool basePathExists = System.IO.Directory.Exists(basePath);
if (!basePathExists) Directory.CreateDirectory(basePath);
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
var filePath = Path.Combine(basePath, file.FileName);
var extension = Path.GetExtension(file.FileName);
if (!System.IO.File.Exists(filePath))
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var problem = await _context.Problems.FindAsync(id);
problem = new Problem
{
ProblemFileAttachments = filePath,
ProblemTitle = title,
ProblemDescription = description,
ProblemStartDate = dateTime,
ProblemSeverity = severity
};
_context.Problems.Add(problem);
_context.SaveChanges();
}
}
TempData["Message"] = "File successfully uploaded to File System.";
return RedirectToAction("Index");
}
Edit.cshtml
@model Pitcher.Models.Problem
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Problem</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit" enctype="multipart/form-data" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ID" class="control-label" ></label>
<input asp-for="ID" readonly="true" disabled="true" class="form-control"/>
</div>
<div class="form-group">
<label asp-for="ProblemTitle" class="control-label"></label>
<input asp-for="ProblemTitle" class="form-control" />
<span asp-validation-for="ProblemTitle" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProblemDescription" class="control-label"></label>
<textarea asp-for="ProblemDescription" class="form-control" rows="10" cols="50"></textarea>
<span asp-validation-for="ProblemDescription" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProblemStartDate" class="control-label"></label>
<input asp-for="ProblemStartDate" class="form-control" />
<span asp-validation-for="ProblemStartDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProblemFileAttachments" class="control-label"></label>
<input asp-for="ProblemFileAttachments" type="file" name="files"/>
@* <button type="submit" class="btn btn-primary" asp-controller="Problems" asp-action="UploadToFileSystem">Upload to File System</button> *@
</div>
<div class="form-group">
<label asp-for="ProblemSeverity" class="control-label"></label>
<select asp-for="ProblemSeverity" class="form-control">
<option value="">Choose severity level</option>
<option value="1">Very Low</option>
<option value="2">Low</option>
<option value="3">Medium</option>
<option value="4">High</option>
<option value="5">Very High</option>
</select>
<span asp-validation-for="ProblemSeverity" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="ProblemComplete" /> @Html.DisplayNameFor(model => model.ProblemComplete)
</label>
</div>
<div class="form-group" method="post">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Problem.cs
<pre lang="C#">using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace Pitcher.Models
{
public class Problem
{
public int ID {get;set;}
[Required]
[StringLength(180, MinimumLength = 2, ErrorMessage = "Problem Title must be bettween 2 to 20 characters.")]
[DataType(DataType.Text)]
[Display(Name = "Problem Title")]
[Column("ProblemTitle")]
public string ProblemTitle {get;set;}
[Required]
[StringLength(int.MaxValue, MinimumLength = 5, ErrorMessage = "Problem Title must be at least 5 characters.")]
[DataType(DataType.Text)]
[Display(Name = "Problem Description")]
[Column("ProblemDescription")]
public string ProblemDescription {get;set;}
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = " Problem Start Date")]
[Column("ProblemStartDate")]
public DateTime ProblemStartDate {get;set;}
[DataType(DataType.Upload)]
[Display(Name = " Upload file")]
[Column("ProblemFileAttachments")]
public string ProblemFileAttachments {get;set;}
[Required]
[Display(Name = "Problem Severity")]
[Range(1,5, ErrorMessage
= "Problem Severity value for {0} must be between {1} and {2}.")]
[Column("ProblemSeverity")]
public int ProblemSeverity {get;set;}
[Display(Name = "Problem Complete")]
[Column("ProblemComplete")]
public bool ProblemComplete {get;set;}
public ICollection<Result> Result {get;set;}
public ICollection<Chat> Chat {get;set;}
}
}
What I have tried:
I tried to make a button before in Edit.cshtml for the method call to only do one action which successfully uploaded the file to the server. But if I try to save the path to database to get the image that is where I get stuck.
If you look inside the Edit you'll see when I call it it does not get the paramater of the IFormFile files which is all I want to store in the database please advise why that is not happening.