Q:

How to make a Single Button Photo Upload from a GridView row in c# ASP.net

I'm trying to accomplish a photo upload from within a row in GridView.   I want details taken from my row when creating the file name.   I have a working version of this, however it will not work across multiple browsers. 
This currently works in,
Microsoft Internet Explorer
Mozilla Fire Fox
Where I've identified it as not working,
Chrome
Here's what I've written so far,
On my ASP Page
I've used the File Upload, however I've hidden its button and field. 
        <asp:FileUpload id="imageupload" runat="server" Style="display: none"/>
    <asp:Button ID="btnUpload" Text="Upload" runat="server" OnClick="Upload" Style="display: none" />

My Gridview  - In my Lbl template field i have a button which launches my PromptUploader method in the code behind.   This begins the process and carries out the row selection so after postback the next methods continue.  
<asp:GridView ID="LocationView" runat="server" AutoGenerateColumns="False" 
CssClass="table table-hover table-striped basepadding" GridLines="None">
      <Columns>
            <asp:TemplateField HeaderText="Product">
                <ItemTemplate>
                    <asp:Label ID="lblproduct" runat="server" Text='<%# Bind("product") %>'></asp:Label><br />
                    <asp:Label ID="lblorderh" runat="server" Text="SO:" Font-Italic="True" ForeColor="#000066" Font-Size="12px"></asp:Label><br />
                    <asp:Label ID="lblorderno" runat="server" Text='<%# Bind("Order_No") %>' Font-Italic="True" ForeColor="Maroon" Font-Size="12px"></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Qty">
                <ItemTemplate>
                    <asp:Label ID="lblcqty" runat="server" Text='<%# Bind("Qtycomplete") %>'></asp:Label><br />
                    <asp:Label ID="lbllineh" runat="server" Text="LNE:" Font-Italic="True" ForeColor="#000066" Font-Size="12px"></asp:Label><br />
                    <asp:Label ID="lblline" runat="server" Text='<%# Bind("Line_no") %>' Font-Italic="True" ForeColor="Maroon" Font-Size="12px"></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Time">
                <ItemTemplate>
                    <asp:Label ID="lbllogtime" runat="server" Text='<%# Bind("opslogtime") %>'></asp:Label><br />
                    <asp:Label ID="lbluserh" runat="server" Text="USR:" Font-Italic="True" ForeColor="#000066" Font-Size="12px"></asp:Label><br />
                    <asp:Label ID="lbluser" runat="server" Text='<%# Bind("opsusername") %>' Font-Italic="True" ForeColor="Maroon" Font-Size="12px"></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="LBl">
                <ItemTemplate>
                    <asp:Label ID="lbllabelno" runat="server" Text='<%# Bind("Labelno") %>'></asp:Label><br />
                    </br>                       
                    <asp:Button ID="btnimagescan" runat="server" text="Image" commandname="Select" CssClass="btn edit btn-primary" OnClick="PromptUploader"/>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

For the button to work I've had to include some Javascript - (i've very little experience with it)
        <script type="text/javascript">
        function UploadFile(fileUpload) {
            if (fileUpload.value ! = '') {
                document.getElementById("<%=btnUpload. ClientID %>").click();
            }
        }
    </script>
    <script type="text/javascript">
        function importClick() {
            document.getElementById("<%=imageupload. ClientID%>").click();
        }
    </script>

In the Code behind i've added the line to trigger onchange with the fileupload box.   This means when i select my image/file the fileuploader will trigger the next piece of javascript UploadFile(fileUpload)
protected void Page_Load(object sender, EventArgs e)
    {            
        imageupload. Attributes["onchange"] = "UploadFile(this)";
    }

The PromtUploader method.   This adds a bool to a session so that on my postback i can (if true) register a startup script which launches my importclick() method.   I change the gridview selected index here also for row identification in next method. 
        public void PromptUploader(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        GridViewRow gvr = (GridViewRow)btn. NamingContainer;

        LocationView. SelectedIndex = gvr. RowIndex;
        _activateimport = true;
        Session["importsetting"] = _activateimport;

    }

On the PreRender Event i've added,  -- This is basically a check on a bool that is set and stored in a session prior this point.    If it exists it will check if its true before adding the next motion to the script manager.   This runs the upload() java script method. 
        private bool _activateimport;

    protected void Page_PreRender(object sender, EventArgs e)
    {
        if (Session["importsetting"] ! = null)
        {
            _activateimport = (bool)Session["importsetting"];
            if (_activateimport)
            {
                ScriptManager. RegisterStartupScript(this, GetType(), "text", "importClick();", true);
                Session. Remove("importsetting");
            }
        }
    }

Upload Method.   This takes the information from the gridview and uses another method which carries over the fileupload and finishes the process.   There's a resizer in this method which is configured on object creation. 
        public void Upload(object sender, EventArgs e)
    {
        UploadResize fileUpld = new UploadResize(1024, 768, System. Drawing. Color. Black);

        GridViewRow gvr = LocationView. SelectedRow;

        PackLabel labelClicked = new PackLabel();

        labelClicked.order_no = ((Label)gvr. FindControl("lblorderno")).Text. Trim();
        labelClicked.order_line_no = ((Label)gvr. FindControl("lblline")).Text. Trim();
        labelClicked.label_no = Convert. ToInt32(((Label)gvr. FindControl("lbllabelno")).Text. Trim());
        labelClicked.product = ((Label)gvr. FindControl("lblproduct")).Text. Trim();
        labelClicked.pack_qty = Convert. ToInt32(((Label)gvr. FindControl("lblcqty")).Text. Trim());

        fileUpld. Upload(imageupload, txtlocation. Text. Trim(), labelClicked);

        if (! fileUpld. IsUploaded)
        {
            lblstatus. Text = fileUpld. UploadError;
        }

    }

My real question is.   Why won't this work in Chrome?   Is there better/more optimised way to carry out this procedure.   

A:

I managed to solve my own issue here.    I found that the order in which Internet Explorer and Chrome post can be slightly different.   Chrome appeared to be posting on a button click immediately before my Javascript was completing its course.   This was resolved by returning false. 
I've also changed my method a fair bit to reduce the necessary postbacks. 
My Gridview
        <asp:GridView ID="LocationView" runat="server" AutoGenerateColumns="False" CssClass="table table-hover table-striped basepadding" GridLines="None" OnRowDataBound="LocationView_RowDataBound">
        <Columns>
            <asp:TemplateField HeaderText="Product">
                <ItemTemplate>
                    <asp:Label ID="lblproduct" runat="server" Text='<%# Bind("product") %>'></asp:Label><br />
                    <asp:Label ID="lblorderh" runat="server" Text="SO:" Font-Italic="True" ForeColor="#000066" Font-Size="12px"></asp:Label><br />
                    <asp:Label ID="lblorderno" runat="server" Text='<%# Bind("Order_No") %>' Font-Italic="True" ForeColor="Maroon" Font-Size="12px"></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Qty">
                <ItemTemplate>
                    <asp:Label ID="lblcqty" runat="server" Text='<%# Bind("Qtycomplete") %>'></asp:Label><br />
                    <asp:Label ID="lbllineh" runat="server" Text="LNE:" Font-Italic="True" ForeColor="#000066" Font-Size="12px"></asp:Label><br />
                    <asp:Label ID="lblline" runat="server" Text='<%# Bind("Line_no") %>' Font-Italic="True" ForeColor="Maroon" Font-Size="12px"></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Time">
                <ItemTemplate>
                    <asp:Label ID="lbllogtime" runat="server" Text='<%# Bind("opslogtime") %>'></asp:Label><br />
                    <asp:Label ID="lbluserh" runat="server" Text="USR:" Font-Italic="True" ForeColor="#000066" Font-Size="12px"></asp:Label><br />
                    <asp:Label ID="lbluser" runat="server" Text='<%# Bind("opsusername") %>' Font-Italic="True" ForeColor="Maroon" Font-Size="12px"></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="LBl">
                <ItemTemplate>
                    <asp:Label ID="lbllabelno" runat="server" Text='<%# Bind("Labelno") %>'></asp:Label><br />
                    </br>
                    <asp:FileUpload id="imageupload" runat="server" Style="display: none"/>                      
                    <asp:ImageButton id="btnimagescan" runat="server" Text="Image" class="btn edit btn-primary" ImageUrl="~/Images/whitecamera25px.png"  />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

I've configured the OnDataBond event so it can check for uploaded files to display if an image has been received or not.   Here i also add the attribute on the individual FileUpload for the onchange event to trigger my java script. 
The imagebutton i've added the method importClick to the onclientclick.   This sends through the clientid for the fileupload so it can be found by the javascript for clicking.  originally my onclientclick event for the btnimgscan button was causing a post back on chrome and not IE.  I resolved by adding return false; to the onclientclick script for the imagebutton.   
    protected void LocationView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row. RowType == DataControlRowType. DataRow)
        {
            string order_no = ((Label)e. Row. FindControl("lblorderno")).Text. Trim();
            string order_line_no = ((Label)e. Row. FindControl("lblline")).Text. Trim();
            string label_no = ((Label)e. Row. FindControl("lbllabelno")).Text. Trim();

            string imagefile = DefaultFileName + LocationDat. Location + @"\" + order_no. Trim().Replace("/", "-") +
            @"\" + order_line_no. Trim() + @"\" + label_no + ".jpg";

            FileUpload rowimageupload = (e.Row. FindControl("imageupload") as FileUpload);
            ImageButton btnimagescan = (e.Row. FindControl("btnimagescan") as ImageButton);
            Button btnstart = (e.Row. FindControl("btnstart") as Button);              
            btnimagescan. OnClientClick = "importClick('" + rowimageupload. ClientID.Trim() + "');return false;";
            rowimageupload. Attributes["onchange"] = "UploadFile();";

            try
            {
                if (File. Exists(imagefile))
                {
                    btnimagescan. ImageUrl = "~/Images/completewhite25px.png";
                }
            }
            catch (Exception Ex)
            {
                lblstatus. Text = Ex. Message;
            }

        }
    }

I've added one button on the main page.   Hidden also like the FileUpload on the gridview. 
        <asp:Button ID="btnpost" OnClick="FindUpload" runat="server" Text="" Style="display: none"/>

This button triggers a method FindUpload which iterates through my gridview checking if any of the objects have a file.   when found this in turn triggers the upload method. 
    public void FindUpload(object sender, EventArgs e)
    {
        if (Session["package"] ! = null)
        {
            foreach (GridViewRow row in LocationView. Rows)
            {
                FileUpload file = ((FileUpload)row. FindControl("imageupload"));

                if (file ! = null)
                {
                    if (file. HasFile)
                    {
                        Upload(file, row);
                    }
                }
            }
        }
    }

Below the Upload method has been updated to receive the objects and carry out the usual actions including conditional formatting for the button when a successful upload completes. 
    public void Upload(FileUpload file, GridViewRow gvr)
    {
        FileUpload fileupload = file;
        UploadResize fileUpld = new UploadResize(1024, 768, System. Drawing. Color. Black);

        PackLabel labelClicked = new PackLabel();

        labelClicked.order_no = ((Label)gvr. FindControl("lblorderno")).Text. Trim();
        labelClicked.order_line_no = ((Label)gvr. FindControl("lblline")).Text. Trim();
        labelClicked.label_no = Convert. ToInt32(((Label)gvr. FindControl("lbllabelno")).Text. Trim());
        labelClicked.product = ((Label)gvr. FindControl("lblproduct")).Text. Trim();
        labelClicked.pack_qty = Convert. ToInt32(((Label)gvr. FindControl("lblcqty")).Text. Trim());

        var btnImageScan = (ImageButton)gvr. FindControl("btnimagescan");

        fileUpld. Upload(fileupload,txtlocation. Text. Trim(),labelClicked);
        if (! fileUpld. IsUploaded)
        {
            lblstatus. Text = fileUpld. UploadError;
        }
        else
        {
            btnImageScan. ImageUrl = "~/Images/completewhite25px.png";
        }
    }

I changed the Javascript slightly.   The upload method no longer checks a file exists but now activates the check on the grid for possible file upload.   This is the one and only post back. 
<script type="text/javascript">
    function importClick(ClientId)
    {
        if (ClientId ! = '')
        {
            document.getElementById(ClientId).click();
        }               
    }
</script>
<script type="text/javascript">
    function UploadFile()
    {
        document.getElementById("<%=btnpost. ClientID%>").click();
    }
</script>

Below are a couple of screen shots of the solution,

