Deserialize Image in ASP.NET WebForm

1

I have a question about the deserialization of an image in webforms, I am working with Oracle Database which is my context and using the entity framework for image I am using BLOB, I was able to serialize and commit in bd, but not I can deserialize. Code:

public partial class WebForm2 : System.Web.UI.Page
{
    int t = 0; //Variavel de teste - BreakPoint
    ProjetoContext bd = new ProjetoContext();
    protected void Page_Load(object sender, EventArgs e)
    //{
    //    if(!IsPostBack)
    //    {
    //        this.CarregarGrind();
    //    }

    }

    //Inserindo imagem 
    protected void Button1_Click(object sender, EventArgs e)
    {
        string filename = Path.GetFileName(FileUp.PostedFile.FileName);
        string contentType = FileUp.PostedFile.ContentType;
        using (Stream fs = FileUp.PostedFile.InputStream)
        {
            using(BinaryReader br = new BinaryReader(fs))
            {
                byte[] bytes = br.ReadBytes((Int32)fs.Length);
                IMG_PRODUTO img = new IMG_PRODUTO();
                img.IMAGEM = bytes;
                img.DESCRICAO = "computador";
                img.PRODUTOes = null;

                bd.IMG_PRODUTO.Add(img);

                bd.SaveChanges();

               // bd.IMG_PRODUTO(img);
            }
        }
        Response.Redirect(Request.Url.AbsoluteUri);
    }


    //private void CarregarGrind() //Entra no metodo mas não realiza o build
    //{
    //        var img = bd.IMG_PRODUTO.ToList();

    //        gvImages.DataSource = img.ToString();
    //        gvImages.DataBind();
    //}

  /*  protected void gvImages_RowDataBound(object sender, GridViewRowEventArgs e)
    {

        if (e.Row.RowType == DataControlRowType.DataRow) //Nem entra nesse if ele já pula fora, mesmo com blob salvo no BD
        {
            byte[] bytes = (byte[])(e.Row.DataItem, DataRowView)["IMAGEM"];
            string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
            (e.Row.FindControl("Imagem1") as Image).ImageUrl = "data:image/png;base64," + base64String;
        }
        e.Row.
        byte[] byteDaImagem;


    }/*
}
    
asked by anonymous 24.11.2017 / 13:07

1 answer

1

I'll propose an example using an example template, because in your current template there are missing some fields referring to ContentType and physical size of the file to show the image correctly coming from the database, example minimum:

Model and Table used with Entity Framework (nothing prevents it from being done by any ORM or Micro or even purely with the .NET Framework has):

  

afterthatthepagethatcontainsaGridViewcomponent:

<htmlxmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
                <Columns>
                    <asp:ImageField
                      DataImageUrlField="Id" 
                      DataImageUrlFormatString="Load.ashx?Id={0}">
                    </asp:ImageField>
                </Columns>
            </asp:GridView>
        </div>            
    </form>
</body>
</html>

In this example of page ASPX has GridView and a ImageField column with two important parameters:

  • DataImageUrlField="Id"

This setting specifies the image ID in the database, commonly called the primary key.

  • DataImageUrlFormatString="Load.ashx?Id={0}"

and this setting is to call another file with the extension ashx ( Generic Handler ) that has the function to execute only code or bald page as it is called by some developers.

On this page you have the code responsible for generating your image:

using System.Web;
using WebApplication15.Models;

namespace WebApplication15
{

    public class Load : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            if (int.TryParse(context.Request.QueryString["Id"].ToString(), out var id))
            {
                using (BaseDadosEntities db = new BaseDadosEntities())
                {
                    Imagens img = db.Imagens.Find(id);
                    if (img != null)
                    {
                        context.Response.ContentType = img.ContentType;
                        context.Response.OutputStream.Write(img.Picture, 0, (int)img.Size);
                    }
                }
            }
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

Since in your current model you do not have ContentType and Size it is the size of the image it is difficult to know the type and generate the image with the correct size are items that need to exist in your table.

Code remark:

To write the image with array of bytes in your database does not need that code, the component FileUpload itself gives you the data needed to save the image, eg:

if (FileUpload1.HasFile)
{
    using (BaseDadosEntities db = new BaseDadosEntities())
    {
        Imagens img = new Imagens();
        img.ContentType = FileUpload1.PostedFile.ContentType;
        img.Extension = Path.GetExtension(FileUpload1.PostedFile.FileName);
        img.Size = FileUpload1.PostedFile.ContentLength;
        img.Picture = FileUpload1.FileBytes;
        db.Imagens.Add(img);
        db.SaveChanges();
        Call_Grid(db);
    }
}

Ideal code and without using other means that in my opinion are totally unnecessary for the specific case.

Another way would be with Event RowDataBound with a TemplateField as follows, in GridView put layout like this:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
    OnRowDataBound="GridView1_RowDataBound">
    <Columns>
        <asp:BoundField DataField="Id" />
        <asp:TemplateField>                        
            <ItemTemplate>
                <asp:Image ID="Image1" runat="server" Width="100" Height="100" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

and in the GridView1_RowDataBound(object sender, GridViewRowEventArgs e) method write the code:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if (int.TryParse(e.Row.Cells[0].Text, out var id))
        {                    
            Imagens im = db.Imagens.Find(id);
            if (im != null)
            {
                Image img = (Image)e.Row.Cells[1].FindControl("Image1");
                img.ImageUrl = 
                    $"data:{im.ContentType};base64,{Convert.ToBase64String(im.Picture)}";
            }                    
        }
    }
}

Complete Code:

public partial class WebForm3 : System.Web.UI.Page
{
    protected BaseDadosEntities db;
    protected void Call_Grid()
    {            
        GridView1.DataSource = db.Imagens.ToList();
        GridView1.DataBind();
        db.Dispose();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (db == null) db = new BaseDadosEntities();
        if (Page.IsPostBack == false)
        {
            Call_Grid();
        }
    }

    protected void Page_Unload(object sender, EventArgs e)
    {
        if (db != null) db.Dispose();
    }

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            if (int.TryParse(e.Row.Cells[0].Text, out var id))
            {                    
                Imagens im = db.Imagens.Find(id);
                if (im != null)
                {
                 Image img = (Image)e.Row.Cells[1].FindControl("Image1");
                 img.ImageUrl = 
                  $"data:{im.ContentType};base64,{Convert.ToBase64String(im.Picture)}";
                }                    
            }
        }
    }
}

References:

24.11.2017 / 14:18