2

I'm trying to display a byte[] image from database in a .NET MVC WebGrid Column. I`m doing the following steps

(EF Model - Articulos)

[Key]
    public int id_Art { get; set; }

    public int id_Pro { get; set; }

    [StringLength(1)]
    public string tipo_Pro { get; set; }

    [Required]
    [StringLength(50)]
    public string nombre_Pro { get; set; }

    [Required]
    [StringLength(100)]
    public string descripcion_Pro { get; set; }

    public byte[] imagen_Pro { get; set; }

    [Required]
    public decimal? precio_Pro { get; set; }

    public int? estatus_Pro { get; set; }

(Controller)

public List<articulos> cargarArticulos(string search, string sort, string sortdir, int skip, int pageSize, out int totalRecord)
    {
        using (DbModel db = new DbModel())
        {
            var v = (from a in db.articulos

                     where
                        a.tipo_Pro.Contains(search) ||
                        a.nombre_Pro.Contains(search) ||
                        a.descripcion_Pro.Contains(search)
                     select a
                     );
            totalRecord = v.Count();
            v = v.OrderBy(sort + " " + sortdir);
            if (pageSize > 0)
            {
                v = v.Skip(skip).Take(pageSize);
            }
            return v.ToList();
        }
    }

(View)

<div>
            @grid.Table(
                    tableStyle: "table table-responsive table-bordered",
                    headerStyle: "webgrid-header",
                    footerStyle: "webgrid-footer",
                    alternatingRowStyle: "webgrid-alternating-row",
                    rowStyle: "webgrid-row-style",
                    columns: grid.Columns(
                        grid.Column(columnName: "imagen_Pro", header: "IMAGEN", format: ),
                        grid.Column(columnName: "tipo_Pro", header: "TIPO"),
                        grid.Column(columnName: "nombre_Pro", header: "NOMBRE"),
                        grid.Column(columnName: "descripcion_Pro", header: "DESCRIPCION"),
                        grid.Column(columnName: "precio_Pro", header: "PRECIO"),
                        grid.Column(header: "⇨", format: (item) => Html.ActionLink("Ver", "Ver", new { }))
    )
)

Everything else works just fine, i'm succesfully retrieving the list from the controller, and it displays into the Webgrid, the only problem is to display the byte[] image stored in my database, i don´t know how to convert it to base64 before to display in the webgrid or simply adding the righ format in the column. I've been working on this for hours, please help.

grid.Column(columnName: "imagen_Pro", header: "IMAGEN", format: ),

Carlos07
  • 27
  • 6

2 Answers2

1

Here's an approach for converting the byte array to Base64 and embedding the Base64 string in an img tag in the grid. You should be able to add a static method to your controller like this:

public static String ConvertByteArrayToBase64(int id)
{
    using (var db = new DBModel())
    {
        return Convert.ToBase64String(db.Articulos.Where(c => c.id_Art == id).First().imagen_Pro);
    }
}

Then add the column like this:

columns: grid.Columns
(
    grid.Column(header: "IMAGEN", format: @<img src="data:image/jpeg;base64,@YourController.ConvertByteArrayToBase64(@item.id_Art)" alt="">))
)

If it's a png or a gif, replace the image/jpeg with image/png or image/gif respectively.

Max Szczurek
  • 4,324
  • 2
  • 20
  • 32
  • First of all thank you so much, also i think your solution is what i need, the only problem is when i type my controller's name (ArticuloController) in this part @->YourController<-.ConvertByteArrayToBase64(@item.id_Art), i`ve tried with Articulo and ArticuloController, but it displays the following error: "Articulo does not exist in the context", what am i missing? I think that i need to call an instance of the controller, but how? – Carlos07 Jul 28 '17 at 15:42
  • Try qualifying the name with the namespace it's in. It's a static method, so you don't need an instance of the controller, just namespace.class name. In my example, it looks like this: @WebApplication1.Controllers.ImageTablesController.ConvertByteArrayToBase64(@item.id) – Max Szczurek Jul 28 '17 at 15:55
  • I can't thank you enough! That's what i needed, i just didn't figure out how to call a static method from controller within a view. Thank you again! Hope this helps to many people ot there – Carlos07 Jul 28 '17 at 16:30
0

I had the similar task, But in my case I use a very straight forward approach:

Controller

Add the following method that Will search and get the image from you database:

public ActionResult SetImageThrough(int id)
    {
        var fileById = (from fi in _db.InvMasters
                        where fi.UId== id
                        select new {fi.SampleAttach }).ToList().FirstOrDefault();
        return File(fileById.SampleAttach, "image/jpg");
    }

View Page

Add the Use the following approach:

grid.Column(format:<img src="/ProductPricing/SetImageThrough?@item.UId" alt="Sample" height="50" width="70" /></text>, header: "PRODUCTIMAGE"),

Hopefully this will help you to display your pictures. in case of a different extensions, you may change only the following ("image/jpg") to .png if is the case.

Happy Coding!!!!

McElie
  • 140
  • 3
  • 12