Click here to Skip to main content
15,886,772 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
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
C#
        // POST: Problems/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, [Bind("ID,ProblemTitle,ProblemDescription,ProblemStartDate,ProblemFileAttachments,ProblemSeverity,ProblemComplete")] Problem problem, List<IFormFile> iFormFile)
        {      
            //Used for file attachment upload.

            if (id != problem.ID)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {                    
                    _context.Update(problem);
                    await _context.SaveChangesAsync();
                    //Upload or update any attachments user inserted. 
                    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)
            {
                //Get the base Path, i.e, The Current Directory of the application + /Files/.
                var basePath = Path.Combine(Directory.GetCurrentDirectory() + "\\Files\\");

                //Checks if the base path directory exists, else creates it.
                bool basePathExists = System.IO.Directory.Exists(basePath);
                if (!basePathExists) Directory.CreateDirectory(basePath);
                //Gets the file name without the extension.
                var fileName = Path.GetFileNameWithoutExtension(file.FileName);
                //Combines the base path with the file name.
                var filePath = Path.Combine(basePath, file.FileName);
                //If the file doesnt exist in the generated path, we use a filestream object, and create a new file, and then copy the contents to it.
                var extension = Path.GetExtension(file.FileName);

                if (!System.IO.File.Exists(filePath))
                {
                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await file.CopyToAsync(stream);
                    }
                    //Create a new Problem object with required values.
                    var problem = await _context.Problems.FindAsync(id);
                    problem = new Problem
                    {
                        ProblemFileAttachments = filePath,
                        ProblemTitle = title,
                        ProblemDescription = description,
                        ProblemStartDate = dateTime,
                        ProblemSeverity = severity
                    };
                    //Inserts this model to the db via the context instance of EF Core.
                    _context.Problems.Add(problem);
                    _context.SaveChanges();
                }
            }
            //Loads all the File data to an object and sets a message in the TempData.
            TempData["Message"] = "File successfully uploaded to File System.";
            return RedirectToAction("Index");
        }


Edit.cshtml
ASP
@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;}
        //public List<Problem> ProblemFileModel {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.
Posted
Updated 19-Feb-22 19:57pm
v2
Comments
Jordan Nash 20-Feb-22 2:06am    
Hi I have swapped the images as they were in the wrong href tags.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900