skip to Main Content

Here is my action that leads to a view, in which you upload a file. The file then is stored in my database as a byte array.

[HttpPost]
        public async Task<IActionResult> Upload(ImageViewModel model)
        {
            byte[] data = null;
            using (var ms = new MemoryStream())
            {
                await model.Data.CopyToAsync(ms);
                data = ms.ToArray();
            }

            var picture = new Picture()
            {
                Name = model.Name,
                Image = data
            };

            await context.Images.AddAsync(picture);
            await context.SaveChangesAsync();

            return RedirectToAction("Index", "Home");
        }

Here is my upload page view:

@model ImageViewModel

<form asp-controller="Image" asp-action="Upload" method="post" enctype="multipart/form-data" >
    <div class ="form-group">
        <label asp-for="@Model.Name" class="control-label"></label>
        <input type="text" asp-for="@Model.Name"/>
    </div>
    <div class="form-group">
        <label asp-for="@Model.Data" class="control-label"></label>
        <input type="file" asp-for="@Model.Data" />
    </div>
    <div class="form-group">
        <input type="submit" value="Upload!" class="btn btn-primary" />
    </div>
</form>

My question is what are the ways I can display the image on a view in my MVC project?

Do I need to convert it to a IFormFile or is there another way like converting it to a base64 string?

3

Answers


  1. You have two most common options:

    1- You can read the byte array from database and convert it to base64 and set it as

    2- You can create an new action (e.g. file) which has "id" parameter, as below:

    public async Task<FileContentResult> File(int id){
        // SELECT imageByteArray, contentType from [Images] WHERE Id = id
    
        // return File(imageByteArray, contentType)  // Add fileDownloadName parameter to force the browser to download 
    }
    

    My recommendation would be the later one, because it is more flexible and practical than the first one.

    Login or Signup to reply.
  2. My question is what are the ways I can display the image on a view in
    my MVC project?

    You can use the following code to display the byte array as image in the view:

    <img src="data:image/png;base64,@Convert.ToBase64String(item.Image)" />
    

    Note: But if your images’ format are all different, you need add an extra property to store the format. You could refer to this answer. The second option in this answer would help you.


    A simple working demo you could follow:

    Model

    public class ImageViewModel
    {
        public IFormFile Data { get; set; }
        public string Name { get; set; }
    }
    public class Picture
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public byte[] Image { get; set; }
    }
    

    View(Index)

    @model IEnumerable<Picture>
    
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Image)
                </th>
               
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        <img src="data:image/png;base64,@Convert.ToBase64String(item.Image)" />
    
                    </td>
                    <td>
                        <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                        <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                        <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    

    Controller

    [HttpGet]
    public async Task<IActionResult> Index()
    {
        return View(await context.Images.ToListAsync());
    }
    [HttpPost]
    public async Task<IActionResult> Upload(ImageViewModel model)
    {
        byte[] data = null;
        using (var ms = new MemoryStream())
        {
            await model.Data.CopyToAsync(ms);
            data = ms.ToArray();
        }
    
        var picture = new Picture()
        {
            Name = model.Name,
            Image = data
        };
    
        await context.Images.AddAsync(picture);
        await context.SaveChangesAsync();
    
        return RedirectToAction("Index", "Home");
    }
    
    Login or Signup to reply.
  3. you can save image on a direct path in your server and In order not to have the same name generate a Guid name for image

      string image = Guid.NewGuid().ToString().Replace("-", "") + Path.GetExtension(formFile.FileName); 
      string path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/img", image);
      using (var stream = new FileStream(path, FileMode.Create))
      {   
          await formFile.CopyToAsync(stream);
      }   
    

    you should save image Guid in database and show image in view like this

    <img src="~/wwwroot/img/@item.ImageGuid"/>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search