How to upload file and view those file in modal popup using gridview

Gani_tpt 1,546 Reputation points
2024-04-17T14:56:04.6833333+00:00

I need help in gridview.

i am using normal add, edit and delete functionalities in gridview. This is working fine.

Initially i am saving the records using textbox controls and save button.

This contains including file upload also.

After saving the records, i want to display in gridview.

suppose, if end user want to edit, we should allow them to edit in gridview including file upload and update/delete.

i am struggling to upload file in gridview while editing the records.

How to achieve this to do simple coding in gridview.?

pls. help this is urgent.

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,262 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,263 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Michael Taylor 48,396 Reputation points
    2024-04-17T15:14:30.2566667+00:00

    So you have a Web Forms app then since you're using GridView? If so then put a button or whatnot in the edit grid to allow the user to select the file to upload along with a FileUpload control. When the user clicks the button to upload and selects the file then the button event handler will get the file as part of the posted data. You can see a full example of how to do this in the online help.

    If you want to allow uploads while the user is editing then you'll most likely want to wait to upload the file until the user "saves" their changes. At that point the uploaded file is just more data being passed to whatever handler you are already using to save the updated data.

    If you don't want to refresh the entire page using a server side button then you'll have to do this in javascript. To do that you'll need to have a javascript handler for your button (not server-side) that uploads the file to the server and then makes an API call (using AJAX) to process the file on the server. All this will be done outside the current page's logic. You can read about one approach here.


  2. Lan Huang-MSFT 25,556 Reputation points Microsoft Vendor
    2024-04-18T05:15:48.4233333+00:00

    Hi @Gani_tpt,

    Based on your needs, I tested an example, hope it can help you.

     <asp:FileUpload ID="FileUpload2" runat="server" />
     <asp:Button ID="AddUsers" runat="server" Text="Insert" OnClick="Insert" />
     <hr />
     <asp:GridView runat="server" ID="gvFiles" AutoGenerateColumns="false" AutoGenerateDeleteButton="true"
         AutoGenerateEditButton="true" OnRowCancelingEdit="OnRowCancelingEdit" OnRowDeleting="OnRowDeleting"
         OnRowEditing="OnRowEditing" OnRowUpdating="OnRowUpdating" DataKeyNames="Id">
         <Columns>
             <asp:BoundField DataField="Name" HeaderText="File Name"></asp:BoundField>
             <asp:TemplateField HeaderText="Files">
                 <ItemTemplate>
                     <asp:LinkButton ID="lnkDownload" runat="server" Text="Download" OnClick="DownloadFile"
                         CommandArgument='<%# Eval("Id") %>'></asp:LinkButton>
                 </ItemTemplate>
                 <EditItemTemplate>
                     <asp:FileUpload ID="fuFile" runat="server" />
                 </EditItemTemplate>
             </asp:TemplateField>
         </Columns>
     </asp:GridView>
    
     string str = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
     protected void Page_Load(object sender, EventArgs e)
     {
         if (!this.IsPostBack)
         {
             BindGridView();
         }
     }
     protected void Insert(object sender, EventArgs e)
     {
         string filename = Path.GetFileName(FileUpload2.PostedFile.FileName);
         string contentType = FileUpload2.PostedFile.ContentType;
         using (Stream fs = FileUpload2.PostedFile.InputStream)
         {
             using (BinaryReader br = new BinaryReader(fs))
             {
                 byte[] bytes = br.ReadBytes((Int32)fs.Length);
                 string constr = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
                 using (SqlConnection con = new SqlConnection(constr))
                 {
                     string query = "INSERT INTO tblFiles(Name,ContentType,Data) VALUES(@Name,@ContentType,@Data)";
                     using (SqlCommand cmd = new SqlCommand(query))
                     {
                         cmd.Connection = con;
                         cmd.Parameters.AddWithValue("@Name", filename);
                         cmd.Parameters.AddWithValue("@ContentType", contentType);
                         cmd.Parameters.AddWithValue("@Data", bytes);
                         cmd.Connection = con;
                         con.Open();
                         cmd.ExecuteNonQuery();
                         con.Close();
                         Response.Redirect(Request.Url.AbsoluteUri);
                     }
                 }
             }
         }
     }
     protected void OnRowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
     {
         gvFiles.EditIndex = -1;
         BindGridView();
     }
     protected void OnRowEditing(object sender, GridViewEditEventArgs e)
     {
         gvFiles.EditIndex = e.NewEditIndex;
         BindGridView();
     }
     protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e)
     {
         BindGridView();
     }
     protected void OnRowUpdating(object sender, GridViewUpdateEventArgs e)
     {
         GridViewRow row = gvFiles.Rows[e.RowIndex];
         int id = Convert.ToInt32(gvFiles.DataKeys[e.RowIndex].Values[0]);
         FileUpload FileUpload1 = row.FindControl("fuFile") as FileUpload;
         string fileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
         string contentType = "";
         byte[] bytes = null;
         if (FileUpload1.HasFile)
         {
             contentType = FileUpload1.PostedFile.ContentType;
             using (Stream fs = FileUpload1.PostedFile.InputStream)
             {
                 using (BinaryReader br = new BinaryReader(fs))
                 {
                     bytes = br.ReadBytes((Int32)fs.Length);
                 }
             }
         }
         using (SqlConnection con = new SqlConnection(str))
         {
             string query = "UPDATE tblFiles SET Name = @Name,ContentType = @ContentType,Data=@Data WHERE id = @Id";
             using (SqlCommand cmd = new SqlCommand(query))
             {
                 cmd.Connection = con;
                 cmd.Parameters.AddWithValue("@Id", id);
                 cmd.Parameters.AddWithValue("@Name", fileName);
                 cmd.Parameters.AddWithValue("@ContentType", contentType);
                 cmd.Parameters.AddWithValue("@Data", bytes == null ? new byte[] { } : bytes);
                 con.Open();
                 cmd.ExecuteNonQuery();
                 con.Close();
             }
         }
         gvFiles.EditIndex = -1;
         BindGridView();
     }
     protected void DownloadFile(object sender, EventArgs e)
     {
         int id = int.Parse((sender as LinkButton).CommandArgument);
         byte[] bytes;
         string fileName, contentType;
         using (SqlConnection con = new SqlConnection(str))
         {
             using (SqlCommand cmd = new SqlCommand())
             {
                 cmd.CommandText = "SELECT Name, Data, ContentType from tblFiles where Id=@Id";
                 cmd.Parameters.AddWithValue("@Id", id);
                 cmd.Connection = con;
                 con.Open();
                 using (SqlDataReader sdr = cmd.ExecuteReader())
                 {
                     sdr.Read();
                     bytes = (byte[])sdr["Data"];
                     contentType = sdr["ContentType"].ToString();
                     fileName = sdr["Name"].ToString();
                 }
                 con.Close();
             }
         }
         Response.Clear();
         Response.Buffer = true;
         Response.Charset = "";
         Response.Cache.SetCacheability(HttpCacheability.NoCache);
         Response.ContentType = contentType;
         Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
         Response.BinaryWrite(bytes);
         Response.Flush();
         Response.End();
     }
     private void BindGridView()
     {
         using (SqlConnection con = new SqlConnection(str))
         {
             using (SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM tblFiles", con))
             {
                 using (DataTable dt = new DataTable())
                 {
                     da.Fill(dt);
                     gvFiles.DataSource = dt;
                     gvFiles.DataBind();
                 }
             }
         }
     }
    

    User's image

    Best regards,
    Lan Huang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  3. Albert Kallal 4,651 Reputation points
    2024-04-19T19:49:58.49+00:00

    Ok, so the approach here, and how you want this to look?

    Well, you really have near unlimited choices here. Some like to display the main record, and then popup a search edit. Some like to display a grid, and then the user clicks on one row to edit, and then we popup a form to edit the record (and in your question, also allow uploading of files).

    The first suggestion is to find and adopt a good popup library. I had great success using the dialog from jQuery.UI. So, I will assume that you have both jQuery, and jQuery.UI installed for this to work.

    The next issue of course is uploading files. I recommend using a good quality up-loader control, and one that allows say multiple files, works in a update panel, and one that does not require a post-back for each file uploaded. There are many such uploaders available, but I using the AjaxFileUploader from the ajax tool kit.

    So, say we have a simple GridView with this markup:

        <asp:GridView ID="GridView1" 
            runat="server" CssClass="table table-hover" AutoGenerateColumns="false"
            width="48%" DataKeyNames="ID" OnRowDataBound="GridView1_RowDataBound"  >
            <Columns>
                <asp:BoundField DataField="FirstName" HeaderText="First Name"  />
                <asp:BoundField DataField="LastName" HeaderText="Last Name"    />
                <asp:BoundField DataField="HotelName" HeaderText="Hotel Name"  ItemStyle-Width="160"  />
                <asp:BoundField DataField="Description" HeaderText="Description" ItemStyle-Width="270" />
                <asp:TemplateField HeaderText="Edit" ItemStyle-HorizontalAlign="Center">
                    <ItemTemplate>
                        <asp:LinkButton ID="cmdEdit" runat="server" 
                            class="btn myshadow"
                            OnClick="cmdEdit_Click" >
                            <span aria-hidden="true" class="glyphicon glyphicon-floppy-saved">&ensp;Edit</span>
                        </asp:LinkButton>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    
    

    Ok, now the code to load above, rather simple:

            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                    LoadData();
            }
            void LoadData()
            {
                string strSQL = "SELECT * FROM tblHotelsA ORDER BY HotelName";
                DataTable rstData = General.MyRst(strSQL);
                GridView1.DataSource = rstData;
                GridView1.DataBind();
            }
    
    

    And now the result looks like this:

    User's image

    So, now we need to wire up the edit button.

    As noted, we will use a jQuery.UI dialog.

    So, when we click a row, we load up the markup with the one record. I'll not post all of the markup, but the jQuery.UI dialog pops a div on the page.

    So, I have this markup:

    
        <div id="EditRecord" runat="server" 
            style="float:left;padding:15px;display:none">
    
                <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                    <ContentTemplate>
            <asp:RadioButtonList ID="RBmenu" runat="server" RepeatDirection="Horizontal"
                CssClass="rMyChoice"
                AutoPostBack="true"
                OnSelectedIndexChanged="RBmenu_SelectedIndexChanged"
                >
                <asp:ListItem Selected="True">Edit Hotel</asp:ListItem>
                <asp:ListItem>Upload Files</asp:ListItem>
            </asp:RadioButtonList>
            <br />
    
            <div id="hoteltab" runat="server">
    
            <div style="float: left" class="iForm">
                <label>HotelName</label>
                <asp:TextBox ID="txtHotel" runat="server" Width="280" f="HotelName" /><br />
                <label>First Name</label>
                <asp:TextBox ID="tFN" runat="server" Width="140" f="FirstName" /><br />
                <label>Last Name</label>
                <asp:TextBox ID="tLN" runat="server" Width="140" f="LastName" ClientIDMode="Static" /><br />
                <label>City</label>
                <asp:TextBox ID="tCity" runat="server" Width="140" f="City" ClientIDMode="Static" /><br />
                <label>Province</label>
                <asp:TextBox ID="tProvince" runat="server" Width="75" f="Province" /><br />
            </div>
    
    

    I have not posted all the markup, but the concept is a simple div, and inside I placed a update panel, since in "genreal", any post-back will collopse such dialogs. However, introduction of a update panel means the popup can have postbacks and remain open.

    So, the row edit button click looks like this:

            protected void cmdEdit_Click(object sender, EventArgs e)
            {
                LinkButton btn = sender as LinkButton;
                GridViewRow gRow = btn.NamingContainer as GridViewRow;
                int PKID = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
                Session["PKID"] = PKID;
    
                string strSQL = $"SELECT * FROM tblHotelsA WHERE ID = {PKID}";
                DataRow rstData = General.MyRst(strSQL).Rows[0];
                General.FLoader(this.hoteltab, rstData);
    
                LoadPictures(PKID);
    
    
                string sJava = $"pophotel('{btn.ClientID}');";
                ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "mypopedit", sJava, true);
    
            }
    
    

    So, we get the current row database PK value. We load up our simple markup with the record (floader), and then we pop the div by injecting JavaScript into the page.

    The resulting effect is this:

    upgrid2

    So, not a lot of code so far. The code to save the record being edited is this:

            protected void cmdSave_Click(object sender, EventArgs e)
            {
                int PKID = (int)Session["PKID"];
                General.FWriter(this.hoteltab, PKID, "tblHotelsA");
                LoadData();  // re-load grid to show any changes
            }
    
    

    But, if you look close at the save button, I have both a client side code stub (to close the dialog), and then the above code to write the changes back to the database, and then I re-load the grid to show any edits/changes done.

    so, that save button markup looks like this:

                    <asp:LinkButton ID="cmdSave" runat="server" class="btn myshadow"
                        OnClick="cmdSave_Click"
                        OnClientClick="MyClose();">
                <span aria-hidden="true" class="glyphicon glyphicon-floppy-saved">Save</span>
                    </asp:LinkButton>
    
    

    And the client side JavaScript again is not much. This:

        <script>
    
            function pophotel(btnT) {
                var btn = $('#' + btnT)
                var mydiv = $("#EditRecord")
                var target = $(this)
                mydiv.dialog({
                    modal: true, appendTo: "form",
                    title: "Edit Hotel", closeText: "",
                    width: "85%",
                    dialogClass: "dialogWithDropShadow",
                    position: { my: 'top+40', at: 'top', of: target }
                });
            }
    
            function MyClose() {
                popdiv = $('#EditRecord')
                popdiv.dialog('close')
            }
    
            function alldone() {
                // runs when all files uploaded.
                $('#cmdAllDone').click()
    
            }
        </script>
    
    

    The uploader code (that allows multiple pictures to be up-loaded) is this:

            protected void AjaxFileUpload1_UploadComplete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
            {
                int PKID = (int)Session["PKID"];
    
                // append database pk so no collsion occures for uploaded file names
                string sUFile = 
                    $"{Path.GetFileNameWithoutExtension(e.FileName)}{PKID.ToString()}" + 
                    Path.GetExtension(e.FileName);
    
                string sFile = 
                    Server.MapPath($@"~/Content/Hotels/{sUFile}"); 
    
                AjaxFileUpload1.SaveAs(sFile);
    
                string strSQL =
                    @"INSERT INTO tblHotelPictures (Hotel_ID, FileName, UpLoaded)
                    VALUES (@Hotel_ID, @FileName, @UpLoaded)";
    
                SqlCommand cmdSQL = new SqlCommand(strSQL);
                cmdSQL.Parameters.Add("@Hotel_ID",SqlDbType.Int).Value = PKID;
                cmdSQL.Parameters.Add("@FileName",SqlDbType.NVarChar).Value = sUFile;
                cmdSQL.Parameters.Add("@UpLoaded",SqlDbType.DateTime).Value = DateTime.Now;
    
                General.MyRstE(cmdSQL);
    
    
            }
    
    

    So, the above should give some ideas here as to how to allow a popup row edit, but also allow uploading of files in that dialog. I used a raditobutton list for my "menu" that allows ones to toggle between up-loading and editing. I suppose you could use some kind of fancy tab control, but I just used 2 div, and hide/show either div based on what radiobutton is selected.

    All in all, not a lot of code was written here, but that's much due to having some helper routines such as floader, and MyRst etc. I can post some additional bits and code, but more important here is the general ideas here.

    The markup in the popup div for uploading is this:

            <div id="uploadfiles" runat="server" style="display:none">
                <h3>Upload pictures for Hotel</h3>
    
                <ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server" Width="400px"
                    OnUploadComplete="AjaxFileUpload1_UploadComplete"
                    OnClientUploadCompleteAll="alldone"
                    />
    
    
                 <asp:Button ID="cmdAllDone" runat="server" Text="All done"
                     ClientIDMode="Static"
                    OnClick="cmdAllDone_Click" style="display:none"
                    />
    
    
            </div>
    
    

    And to display the pictures? I had this markup:

                <div style="float:left;margin-left:30px;margin-top:-60px">
                    <asp:Repeater ID="Repeater1" runat="server">
                        <ItemTemplate>
                            <asp:Image ID="Image1" runat="server"
                                width="356px"
                                ImageUrl='<%# "~/Content/Hotels/" + Eval("FileName") %>'
                                CssClass="myshadow"
                                />                            
                            <br />
                            <br />
    
                        </ItemTemplate>
                    </asp:Repeater>
    
                </div>
    
    

    So, I used a repeater to display 1 or many images.

    The Load pictures code is this:

            void LoadPictures(int PKID)
            {
                string strSQL = 
                    "SELECT * FROM tblHotelPictures WHERE Hotel_ID = @ID";
                SqlCommand cmdSQL = new SqlCommand(strSQL);
                cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = PKID;
    
                DataTable rstPictures = General.MyRstP(cmdSQL);
                Repeater1.DataSource = rstPictures;
                Repeater1.DataBind();
    
            }
    
    
    0 comments No comments