我从事一个项目有一个星期,该项目具有上载和下载pdf和jpg文件的功能,该项目来自一个朋友,但由于他出差而被分配给我。
关键是这种上传和下载文件的功能非常有趣,我进行了一些更改,这使我在下载文件时遇到了严重问题。
最初,我们有一个Web表单(ASPX),它是MasterPage的一部分,在该表单的一部分中,实现了ASCX控件,该控件是具有所有文件加载和卸载功能的控件。是一个用于添加文件加载器(HyperLink)的按钮,另一个是用于下载(带有标志runat =“ server”的按钮)的按钮,最后一部分是GridView,代码如下:
<%@ Control Language="C#" CodeBehind="MultiUpload.ascx.cs" Inherits="D_Soft.DynamicData.FieldTemplates.MultiUpload" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" Tagprefix="cc1" %>
<fieldset class="fUploadControl">
<legend>
<h1>Upload Files</h1>
</legend>
<asp:UpdatePanel ID="upMultiUpload" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Panel ID="pnlUpload" runat="server">
<asp:FileUpload ID="upldFile_0" CssClass="form-control" runat="server" />
</asp:Panel>
<br />
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-2 col-lg-2">
<asp:HyperLink ID="lnkAddFileUpload" CssClass="btn btn-block btn-primary" NavigateUrl="javascript:addFileUploadCtrl();" runat="server"><i class="fa fa-plus"></i> Add</asp:HyperLink>
</div>
<div class="col-xs-12 col-sm-12 col-md-2 col-lg-2">
<button runat="server" id="btnUpload" data-ajax="false" type="button" onserverclick="btnUpload_Click" class="btn btn-block btn-primary"><i class="fa fa-upload"></i> Upload</button>
</div>
</div>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnUpload" />
</Triggers>
</asp:UpdatePanel>
<br />
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div style="width: 100%; overflow: auto">
<asp:GridView ID="GridFiles" runat="server"
AutoGenerateColumns="False" CellPadding="3" DataKeyNames="RowId,File,Path,Exists"
Font-Names="Calibri" Font-Size="10pt" OnRowDeleting="GridFilesArchivos_RowDeleting" OnSelectedIndexChanged="GridFiles_SelectedIndexChanged"
ForeColor="#333333" GridLines="Both" Height="25px"
Width="500px"
Style="font-size: 10pt"
CssClass="mGrid" PagerStyle-CssClass="pgr" AlternatingRowStyle-CssClass="alt">
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<Columns>
<asp:BoundField DataField="RowId" SortExpression="RowId" Visible="False" />
<asp:BoundField DataField="File" HeaderText="FILE" SortExpression="File">
<HeaderStyle HorizontalAlign="Center" />
<ItemStyle Width="85%" HorizontalAlign="Center" />
</asp:BoundField>
<asp:BoundField DataField="Path" SortExpression="Path" Visible="False" />
<asp:BoundField DataField="Exists" SortExpression="Exists" Visible="False" />
<asp:CommandField ItemStyle-Width="15%" ItemStyle-HorizontalAlign="Center" ShowCancelButton="false" HeaderText="ACTION" ButtonType="Image" Visible="true" DeleteImageUrl="~/img/trash.png" ShowDeleteButton="True" ShowSelectButton="true" SelectImageUrl="~/img/download.png" />
</Columns>
</asp:GridView>
</div>
</div>
</div>
</fieldset>
GUI如下所示:
对于代码C#,有一个文件上传和文件下载事件,但是,我必须进行更改,因为某些Web表单控件适用于回发调用,并且我不希望页面再次加载,您会看到类似这个:
protected void Page_Load(object sender, EventArgs e)
{
Page.Form.Attributes.Add("enctype", "multipart/form-data");
}
protected void btnUpload_Click(object sender, EventArgs e)
{
UploadFiles();
}
public bool UploadFiles()
{
DataTable dtFiles = new DataTable();
dtFiles.Columns.Add(new DataColumn("RowId", typeof(int)));
dtFiles.Columns.Add(new DataColumn("File", typeof(string)));
dtFiles.Columns.Add(new DataColumn("Path", typeof(string)));
dtFiles.Columns.Add(new DataColumn("Exists", typeof(string)));
//Number of files, here the files to be uploaded are captured,
//before uploading any file valid the size, name and extension of the
//file, this code I have omitted because I do not think it is necessary
HttpFileCollection col = Request.Files;
int cantFiles = 0;
//This code allows me to save each of the files in Request.Files
for (int i = 0; i < fcol.Count; i++)
{
HttpPostedFile postedF = col[i];
if (postedF.ContentLength > 0)
{
string tmpsave = string.Format("{0}\\{1}", dirPath, Path.GetFileName(postedF.FileName));
//Create a temporary file name that will be used for checking duplicates
string tempfileName = "";
// Check if there is already a file with the same name to load
if (System.IO.File.Exists(tmpsave))
{
int counter = 2;
while (System.IO.File.Exists(tmpsave))
{
tempfileName = counter.ToString() +"_"+ Path.GetFileName(postedF.FileName);
tmpsave= string.Format("{0}\\{1}", dirPath, tempfileName);
counter++;
}
}
//Save File in server
postedF.SaveAs(tmpsave);
//Update Rows
DataRow dwRow = dtFiles.NewRow();
dwRow["RowId"] = cantFiles;
dwRow["File"] = Path.GetFileName(postedF.FileName);
dwRow["Path"] = tmpsave;
dwRow["Exists"] = "NO";
dtFiles.Rows.Add(dwRow);
cantFiles++;
}
}
//Update GridView
GridFiles.DataSource = dtFiles;
GridFiles.DataBind();
}
protected void GridArchivos_SelectedIndexChanged(object sender, EventArgs e)
{
string stPathDes = this.GridFiles.DataKeys[this.GridFiles.SelectedIndex][2].ToString();
DownloadFile(HttpContext.Current, stPathDes, Path.GetFileNameWithoutExtension(stPathDes) + Path.GetExtension(stPathDes).ToLower());
}
public static void DownloadFile(System.Web.HttpContext context, string stUbication, string stName)
{
stUbication can be: "D:\\Project\\ProjectUpload\\ProjectUpload.Web\\Files\\anyfolder\\\\123.pdf"
stName can be: "123.pdf"
try
{
System.IO.FileInfo toDownload = new System.IO.FileInfo(stUbication);
System.Web.HttpResponse response = context.Response;
if (toDownload.Exists)
{
response.ClearContent();
response.Clear();
response.AddHeader("Content-Disposition", "attachment; filename=" + stName);
response.AddHeader("Content-Length", toDownload.Length.ToString());
response.ContentType = "application/octet-stream";
response.WriteFile(stUbication);
response.Flush();
//response.End();
context.ApplicationInstance.CompleteRequest();
}
}
catch (Exception ex)
{
throw ex;
}
}
Page_Load方法的第一行以及UpdatePanel和PostBackTrigger的实现允许我加载多个文件,之所以这样做是因为Request.File变量始终为空。
现在,文件上传可以正常工作了。行response.End();之所以被注释,是因为我生成了一个类型为“由于代码已优化或本机框架位于调用堆栈顶部而无法评估表达式”的异常。
问题是从不下载按钮来下载文件,而不会触发进度条,除此之外,JavaScript控制台中还会发生错误(“无法读取未定义的属性'PRM_ParserErrorDetails'”):>
该错误没有太多的文档,我真的不知道我是在错误地构建代码还是需要实现其他东西。
此控件通过Web表单(ASPX)实现,如下所示:
<%@ Page Title="" Language="C#" MasterPageFile="~/TheMaster.Master" AutoEventWireup="true" CodeBehind="MyForm.aspx.cs" Inherits="ProjectUpload.Web.MyForm" MaintainScrollPositionOnPostback="true" %>
<%@ Register Src="~/Controls/MultiUpload.ascx" TagPrefix="uc1" TagName="MultiUpload" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:UpdatePanel ID="upPanelRequest" runat="server">
<ContentTemplate>
//In this UpdatePanel I have a button (btnButtonSave)
//I do this to not refresh the page again, this button performs a process with the database,
//therefore, it is delayed and I need to do the Return to show a progress bar (gif)
<uc1:MultiUpload runat="server" id="MultiUpload" />
<button runat="server" type="button" id="btnButtonSave" onclick="DisableButton(this);" onserverclick="btnButtonSave_ServerClick" class="btn btn-success btn-block">
<i class="fa fa-save"></i> SAVE
</button>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnButtonSave" />
<asp:AsyncPostBackTrigger ControlID="MultiUpload" />
</Triggers>
</asp:UpdatePanel>
</asp:Content>
我注意到的一件奇怪的事是,当我上传文件时,表单会完全重新加载。我可能用错了什么?
有人可以帮助我吗?
答案 0 :(得分:0)
我找到了一个解决方案,它很简单,您只需要将GridView放在UpdatePanel中并指向该控件中的PostBackTrigger:
<asp:UpdatePanel ID="upMultiUpload" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:GridView ID="GridFiles" runat="server"> ... </asp:GridView>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnUpload" />
<asp:PostBackTrigger ControlID="GridFiles" />
</Triggers>
</asp:UpdatePanel>
与此相关的JavaScript问题消失了,但是有必要修改代码以撤消文件:
response.ClearContent();
response.Clear();
response.AddHeader("Content-Disposition", "attachment; filename=" + stName);
response.AddHeader("Content-Length", toDownload.Length.ToString());
response.ContentType = "application/octet-stream";
response.WriteFile(stUbication);
response.Flush();
但是,如果没有回发,它将无法工作,因为必须重新加载页面以发送文件,所以我在Internet上发现的某些实现是通过AsyncFileUpload控件实现的,但由于我负责,因此它不适用于我的项目多个文件,其他实现使用AJAX和ASHX,但就我而言,我需要GridView ...我仍然不知道是否有解决此问题的方法。
这些链接对于理解该问题很有帮助:
File upload is not working with AsyncPostBackTrigger in ASP.Net
https://forums.asp.net/t/1669892.aspx?Request+Files+is+empty