Search code examples
c#asp.net-corefile-uploadasp.net-core-mvc

ASP.NET Core MVC - How to upload the selected image


I am creating a web page. There is an image selection section on the page. My page looks like this:

enter image description here

I want to select the image from the Image section and add it to the Images folder in my project. How can I do that?

My code:

Index.cshtml:

@model IncomeExpenseWeb.Models.IncomeExpenseTable
@{
    ViewData["Title"] = "Home Page";
}
<br />
<div class="p-3 mb-2 bg-light text-dark">
    <h2>Add Record</h2>
</div>
@using (Html.BeginForm("Index", "/", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div class="row">
        <div class="col">
            <div class="mb-3">
                <label for="formGroupExampleInput" class="form-label">Name</label>
                <input type="text" class="form-control" id="Name" placeholder="What is your name?" />
            </div>
        </div>
        <div class="col">
            <div class="mb-3">
                <label for="formGroupExampleInput" class="form-label">Surname</label>
                <input type="text" class="form-control" id="Surname" placeholder="What is your surname?" />
            </div>
        </div>
    </div>
    <div class="form-group">
        <p>Money Status:</p>
        <select class="form-control" id="SelectedId" name="SelectedId">
            <option value="income">Income</option>
            <option value="expense">Expense</option>
        </select>
    </div>
    <br/>
    <div class="form-group">
        <label>Image:</label>
        <input type="file" name="UploadedImage"/>
    </div>
    <br/>
    <div>
        <input type="submit" class="btn btn-success" value="Save">
    </div>
}

Controller:

[HttpPost]
public ActionResult Index()
{
    // I didn't know how to write code.
    return View();
}

Model:

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;

namespace IncomeExpenseWeb.Models
{
    public partial class IncomeExpenseTable
    {
        public int Id { get; set; }
        public string Name { get; set; } = null!;
        public string Surname { get; set; } = null!;
        public string MoneyStatus { get; set; } = null!;
        // public string Image { get; set; } = null!;
        public IFormFile Image { get; set; } = null!;
    }
}

Thanks for help.


Solution

  • Actually, the image upload feature is not as complex as you thought.

    1. Set the folder directory path to store the image. For configurable purposes, add the setting for the folder directory path used to store the image in appsettings.json.

    appsettings.json

    {
      ...
      "AppSettings": {
        "ImageDir": "<Your Folder Directory Path>"
      }
    }
    

    Controller

    2.1. Read the directory path with key "AppSettings:ImageDir" from IConfiguration.

    using Microsoft.Extensions.Configuration;
    using System.IO;
    
    public class IncomeExpenseTableController : Controller
    {
        private readonly string directoryPath;
    
        public IncomeExpenseTableController(IConfiguration configuration)
        {
            directoryPath = configuration["AppSettings:ImageDir"];
        }
    
        ...
    }
    

    2.2. API action should expect to receive the form data with the IncomeExpenseTable type.

    2.2.1. Create the folder directory if it does not exist.

    2.2.2. Save the image file to the directory.

    [HttpPost]
    public ActionResult Index(IncomeExpenseTable model)
    {
        if (model.Image != null)
        {
            Directory.CreateDirectory(directoryPath);
    
            string filePath = Path.Combine(directoryPath, model.Image.FileName);
    
            using var stream = System.IO.File.Create(filePath);
            model.Image.CopyTo(stream);
        }
    
        return View(model);
    }
    

    View

    3.1. Concern that the form may submit to the wrong action path as you set "/" in the controller for @Html.BeginForm(). (For my demo, "Index" action with "IncomeExpenseTable" controller is the path that the form will be submitted to.)

    3.2. Make sure the form control name is mapped to the property name in the IncomeExpenseTable class (which is the form data in the controller action) via asp-for tag helper.

    @using (Html.BeginForm("Index", "IncomeExpenseTable", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        ...
    
        <input type="file" asp-for="Image"/>
    }
    

    Demo

    enter image description here


    References

    Upload files in ASP.NET Core