如何在 c# ASP.net 中从 GridView 行进行单按钮照片上传

Posted

技术标签:

【中文标题】如何在 c# ASP.net 中从 GridView 行进行单按钮照片上传【英文标题】:How to make a Single Button Photo Upload from a GridView row in c# ASP.net 【发布时间】:2018-07-01 00:52:40 【问题描述】:

我正在尝试从 GridView 的一行中完成照片上传。我想在创建文件名时从我的行中获取详细信息。我有这个的工作版本,但是它不能跨多个浏览器工作。

目前适用于,

微软 Internet Explorer Mozilla 火狐

我发现它不起作用,

这是我到目前为止所写的,

在我的 ASP 页面上

我使用了文件上传,但是我隐藏了它的按钮和字段。

        <asp:FileUpload id="imageupload" runat="server" Style="display: none"/>
    <asp:Button ID="btnUpload" Text="Upload" runat="server" OnClick="Upload" Style="display: none" />

我的 Gridview - 在我的 Lbl 模板字段中,我有一个按钮,可以在后面的代码中启动我的 PromptUploader 方法。这将开始该过程并执行行选择,以便在回发后继续下一个方法。

<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>

为了使按钮工作,我必须包含一些 javascript -(我对它的经验很少)

        <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>

在后面的代码中,我添加了通过文件上传框触发 onchange 的行。这意味着当我选择我的图像/文件时,文件上传器将触发下一段 javascript UploadFile(fileUpload)

protected void Page_Load(object sender, EventArgs e)
                
        imageupload.Attributes["onchange"] = "UploadFile(this)";
    

PromtUploader 方法。这会在会话中添加一个布尔值,以便在我的回发中我可以(如果为真)注册一个启动脚本,该脚本启动我的 importclick() 方法。我在这里更改了 gridview 选择的索引,也用于下一个方法中的行标识。

        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;

    

在我添加的 PreRender 事件中,-- 这基本上是对在此之前的会话中设置和存储的布尔值的检查。如果存在,它将在将下一个动作添加到脚本管理器之前检查其是否为真。这将运行 upload() java 脚本方法。

        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");
            
        
    

上传方法。这从 gridview 获取信息并使用另一种方法来进行文件上传并完成该过程。此方法中有一个调整大小,在创建对象时配置。

        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;
        

    

我真正的问题是。为什么这在 Chrome 中不起作用?是否有更好/更优化的方法来执行此过程。

【问题讨论】:

【参考方案1】:

我设法在这里解决了我自己的问题。我发现 Internet Explorer 和 Chrome 发布的顺序可能略有不同。 Chrome 似乎在我的 Javascript 完成其课程之前立即发布按钮单击。这已通过返回 false 解决。

我还稍微改变了我的方法以减少必要的回发。

我的网格视图

        <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>

我已经配置了 OnDataBond 事件,因此它可以检查上传的文件以显示是否接收到图像。在这里,我还在单个 FileUpload 上添加了 onchange 事件的属性以触发我的 java 脚本。

我已将方法 importClick 添加到 onclientclick 的 imagebutton。这通过用于文件上传的 clientid 发送,以便 javascript 可以找到它以进行单击。最初我的 btnimgscan 按钮的 onclientclick 事件导致在 chrome 而不是 IE 上回发。我通过添加 return false 来解决;到 imagebutton 的 onclientclick 脚本。

    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;
            

        
    

我在主页上添加了一个按钮。也像 gridview 上的 FileUpload 一样隐藏。

        <asp:Button ID="btnpost" OnClick="FindUpload" runat="server" Text="" Style="display: none"/>

这个按钮触发一个 FindUpload 方法,它遍历我的 gridview 检查是否有任何对象有文件。当发现这反过来触发上传方法。

    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);
                    
                
            
        
    

以下 Upload 方法已更新,可在成功上传完成时接收对象并执行包括条件格式设置在内的常规操作。

    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";
        
    

我稍微更改了 Javascript。上传方法不再检查文件是否存在,但现在激活网格上的检查以检查可能的文件上传。这是唯一的回帖。

<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>

以下是解决方案的几个屏幕截图,

【讨论】:

以上是关于如何在 c# ASP.net 中从 GridView 行进行单按钮照片上传的主要内容,如果未能解决你的问题,请参考以下文章

在 asp.net core 5 MVC 视图中从 C# 代码调用 JavaScript 函数

如何在 C# 中从外部站点的 url 读取 PDF 文件 [关闭]

如何在wpf c#中从数据表导出到excel文件

如何在 asp.net 中从 javascript 调用代码隐藏函数?

如何在asp.net核心中从客户端调用web api方法?

如何在 asp.net 核心中从返回零计数的主体正确映射数组