Search code examples
c#asp.netasp.net-mvcasp.net-coremodel-view-controller

How can I display a byte array in my database as an image?


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?


Solution

  • 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");
    }