Deserialize Image in ASP.NET Webform

Asked

Viewed 193 times

1

Well I am with a doubt about the deserialization of an image in webforms, I am working with Oracle database that is my context and using the Entity framework for image I am using BLOB, I was able to serialize and commit in bd, but I can not 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;


    }/*
}
  • 1

    But I can’t unserialize where? how do you want to do this.

  • Well, as I said above, I have the image saved in the BD in Blob, in the event Rowdatabound was to deserializar the image, I would like to use techniques of the Entity that the view was in the grid

  • 1

    There are some ways to do this, one of them is with a page that only runs code maybe is the best solution.

  • Is there any example of code? or website because I am debugging and never enters my if. if (e.Row.Rowtype == Datacontrolrowtype.Datarow) //Even if it jumps out already, even with blob saved in BD

  • 1

    Let me find out what’s best for you

  • Okay, I’ll be waiting

Show 2 more comments

1 answer

1


I will propose an example using an example model, because in its current model there are some fields referring to ContentType and physical file size to display the image correctly coming from the database, minimum example:

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

inserir a descrição da imagem aqui

after that page containing a component GridView:

<html xmlns="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 page example ASPX has Gridview and a column ImageField with two important parameters:

  • DataImageUrlField="Id"

this setting specifies the identification of the image 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) which has the function of executing only code or bald page as it is called by some developers.

On this page you have the code responsible to generate 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;
            }
        }
    }
}

as its current model does not have ContentType and Size which 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 observation:

To save the image with byte array to your database you don’t need that code, the component itself FileUpload provides the data needed to record the image, example:

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 view are totally unnecessary for the specific case.


Another way would be with Event Rowdatabound with a Templatefield as follows, in GridView put a layout thus:

<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 method GridView1_RowDataBound(object sender, GridViewRowEventArgs e) writes 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:

Browser other questions tagged

You are not signed in. Login or sign up in order to post.