C# jQuery和ASP.NET从数据库下载文件
我查看了许多在线资源并构建了我的脚本,但它似乎仍然没有给我文件。它只是加载页面“client-home2.aspx/downloadAttachment”,而不是执行代码并传递文件 以下是我的代码:C# jQuery和ASP.NET从数据库下载文件,c#,jquery,asp.net,webforms,C#,Jquery,Asp.net,Webforms,我查看了许多在线资源并构建了我的脚本,但它似乎仍然没有给我文件。它只是加载页面“client-home2.aspx/downloadAttachment”,而不是执行代码并传递文件 以下是我的代码: [WebMethod] public void downloadAttachment(string id) { DbProviderFactory dbf = DbProviderFactories.GetFactory(); using (
[WebMethod]
public void downloadAttachment(string id)
{
DbProviderFactory dbf = DbProviderFactories.GetFactory();
using (IDbConnection con = dbf.CreateConnection())
{
string sSQL;
sSQL = "select top 1 " + ControlChars.CrLf
+ " FILENAME, FILE_MIME_TYPE, ATTACHMENT" + ControlChars.CrLf
+ " from vwATTACHMENTS_CONTENT" + ControlChars.CrLf
+ " where 1 = 1 " + ControlChars.CrLf;
//Debug.Print(sSQL);
using (IDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = sSQL;
Sql.AppendParameter(cmd, id.ToString(), "ATTACHMENT_ID");
cmd.CommandText += " order by DATE_ENTERED desc" + ControlChars.CrLf;
using (DbDataAdapter da = dbf.CreateDataAdapter())
{
((IDbDataAdapter)da).SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
da.Fill(dt);
if (dt.Rows.Count > 0)
{
foreach (DataRow r in dt.Rows)
{
string name = (string)r["FILENAME"];
string contentType = (string)r["FILE_MIME_TYPE"];
Byte[] data = (Byte[])r["ATTACHMENT"];
// Send the file to the browser
Response.AddHeader("Content-type", contentType);
Response.AddHeader("Content-Disposition", "attachment; filename=" + name);
Response.BinaryWrite(data);
Response.Flush();
Response.End();
}
}
else
{
}
}
}
}
}
}
以下是我的jQuery:
$('.attachmentLink').click(function () {
var id = $(this).attr('id');
/*
$.ajax({
type: "POST",
url: "client-home2.aspx/downloadAttachment",
data: '{id:\'' + id + '\'}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
//alert(msg.d);
}
});
*/
$.download('client-home2.aspx/downloadAttachment', 'id=' + id);
return false;
});
我正在使用此功能
问题是,它从不给我文件;它只是导航到client-home2.aspx/downloadAttachment
如何解决此问题以便下载文件
谢谢。每个WebMethod调用只能发送一个HTTP响应。这意味着一次只有一个文件。使用
Response.End()。解决这个问题的唯一方法是从jQuery代码中调用WebMethod 20次,并使用一个参数来知道如果查询中有多个结果,每次返回哪个文件。即使这样也可能行不通
但我怀疑你真的想让ID字段只产生一条记录。在这种情况下,你需要意识到两件事。首先,当您更改CommandText
属性时,SqlCommand类型将重置其参数集合。因此,您需要在添加ID参数之前完成整个sql字符串文本的创建。第二个问题是,您的ID参数现在甚至不重要,因为您的sql代码从未引用该参数
我很犹豫是否发布这段代码,因为还有其他可能出错的地方,但这应该比您现有的有所改进。请注意,我最后也做了同样的工作,但代码要少得多:
以下是我过去的做法,但我的做法有所不同:
视图:
请放心,这很简单。我知道了。我必须创建一个单独的文件,因为已经发送了标题。因此,我的单独文件称为“downloadAttachment”,如下所示:
using System;
using System.Data;
using System.Data.Common;
using System.Configuration;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Globalization;
using System.Threading;
using System.Diagnostics;
using System.Net;
using System.Net.Mail;
using System.Data.SqlClient;
using System.Web.Services;
using System.Text;
using System.Web.Script.Services;
using System.Text.RegularExpressions;
using System.IO;
namespace SplendidCRM.WebForms
{
public partial class downloadAttachment : System.Web.UI.Page
{
string HostedSite;
protected DataView vwMain;
protected void Page_Load(object sender, EventArgs e)
{
if (Sql.IsEmptyGuid(Security.USER_ID))
Response.Redirect("~/Webforms/client-login.aspx");
HostedSite = Sql.ToString(HttpContext.Current.Application["Config.hostedsite"]);
string id = Request.QueryString["ID"].ToString();
DbProviderFactory dbf = DbProviderFactories.GetFactory();
using (IDbConnection con = dbf.CreateConnection())
{
string sSQL;
sSQL = "select top 1 " + ControlChars.CrLf
+ " FILENAME, FILE_MIME_TYPE, ATTACHMENT" + ControlChars.CrLf
+ " from vwATTACHMENTS_CONTENT" + ControlChars.CrLf
+ " where 1 = 1 " + ControlChars.CrLf;
//Debug.Print(sSQL);
using (IDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = sSQL;
Sql.AppendParameter(cmd, id.ToString(), "ATTACHMENT_ID");
cmd.CommandText += " order by DATE_ENTERED desc" + ControlChars.CrLf;
using (DbDataAdapter da = dbf.CreateDataAdapter())
{
((IDbDataAdapter)da).SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
da.Fill(dt);
if (dt.Rows.Count > 0)
{
foreach (DataRow r in dt.Rows)
{
string name = (string)r["FILENAME"];
string contentType = (string)r["FILE_MIME_TYPE"];
Byte[] data = (Byte[])r["ATTACHMENT"];
// Send the file to the browser
Response.AddHeader("Content-type", contentType);
Response.AddHeader("Content-Disposition", "attachment; filename=" + MakeValidFileName(name));
Response.BinaryWrite(data);
Response.Flush();
Response.End();
}
}
else
{
}
}
}
}
}
}
public static string MakeValidFileName(string name)
{
string invalidChars = Regex.Escape(new string(System.IO.Path.GetInvalidFileNameChars()));
string invalidReStr = string.Format(@"[{0}]+", invalidChars);
string replace = Regex.Replace(name, invalidReStr, "_").Replace(";", "").Replace(",", "");
return replace;
}
}
}
使用jQuery执行此操作有什么特殊原因吗?我可以避免吗?我希望单击按钮即可下载该文件。您不是下载一个文件:您正试图通过一个http请求下载20个文件。那是行不通的。总是有两个——不多也不少:一个请求和一个响应。@JoelCoehoorn我只想下载一个文件。我可以去掉这个循环。我更新了代码selecttop1
@christorrayl,为了避免使用jQuery,我将链接替换为,但它仍然没有提供文件。不过,这个答案同样适用于MVC/Razor,而不是Web表单。我的错。我希望我用的是MVC!从未听说过“货物崇拜”
。。。仅仅是wikipedia的itAlso,Response.End()
永远不应该被直接调用。相反,正确的应该是Context.ApplicationInstance.CompleteRequest()
。首先,感谢您的发布,但是我在cmd.ExecuteReader()上有一个语法错误error 94无法隐式地将类型“System.Data.IDataReader”转换为“System.Data.Common.DbDataReader”。存在显式转换(是否缺少转换?)我将DbDataReader rdr
更改为IDataReader rdr
,然后它消失了,我现在要测试它……不幸的是,它仍然没有呈现文件。它只是打开没有样式表的页面。可能是if(){}块顶部的Response.Clear()。另外,检查您的查询是否返回记录。
foreach (var file in foo.Uploads)
{
<tr>
<td>@Html.ActionLink(file.Filename ?? "(no filename)", "Download", "Upload", new { id = file.UploadId }, null)</td>
</tr>
}
public ActionResult Download(Guid id)
{
var upload = this.GetUpload(id);
if (upload == null)
{
return NotFound();
}
return File(upload.Data, upload.ContentType, upload.Filename);
}
private Upload GetUpload(Guid id)
{
return (from u in this.DB.Uploads
where u.UploadId == id
select u).SingleOrDefault();
}
using System;
using System.Data;
using System.Data.Common;
using System.Configuration;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Globalization;
using System.Threading;
using System.Diagnostics;
using System.Net;
using System.Net.Mail;
using System.Data.SqlClient;
using System.Web.Services;
using System.Text;
using System.Web.Script.Services;
using System.Text.RegularExpressions;
using System.IO;
namespace SplendidCRM.WebForms
{
public partial class downloadAttachment : System.Web.UI.Page
{
string HostedSite;
protected DataView vwMain;
protected void Page_Load(object sender, EventArgs e)
{
if (Sql.IsEmptyGuid(Security.USER_ID))
Response.Redirect("~/Webforms/client-login.aspx");
HostedSite = Sql.ToString(HttpContext.Current.Application["Config.hostedsite"]);
string id = Request.QueryString["ID"].ToString();
DbProviderFactory dbf = DbProviderFactories.GetFactory();
using (IDbConnection con = dbf.CreateConnection())
{
string sSQL;
sSQL = "select top 1 " + ControlChars.CrLf
+ " FILENAME, FILE_MIME_TYPE, ATTACHMENT" + ControlChars.CrLf
+ " from vwATTACHMENTS_CONTENT" + ControlChars.CrLf
+ " where 1 = 1 " + ControlChars.CrLf;
//Debug.Print(sSQL);
using (IDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = sSQL;
Sql.AppendParameter(cmd, id.ToString(), "ATTACHMENT_ID");
cmd.CommandText += " order by DATE_ENTERED desc" + ControlChars.CrLf;
using (DbDataAdapter da = dbf.CreateDataAdapter())
{
((IDbDataAdapter)da).SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
da.Fill(dt);
if (dt.Rows.Count > 0)
{
foreach (DataRow r in dt.Rows)
{
string name = (string)r["FILENAME"];
string contentType = (string)r["FILE_MIME_TYPE"];
Byte[] data = (Byte[])r["ATTACHMENT"];
// Send the file to the browser
Response.AddHeader("Content-type", contentType);
Response.AddHeader("Content-Disposition", "attachment; filename=" + MakeValidFileName(name));
Response.BinaryWrite(data);
Response.Flush();
Response.End();
}
}
else
{
}
}
}
}
}
}
public static string MakeValidFileName(string name)
{
string invalidChars = Regex.Escape(new string(System.IO.Path.GetInvalidFileNameChars()));
string invalidReStr = string.Format(@"[{0}]+", invalidChars);
string replace = Regex.Replace(name, invalidReStr, "_").Replace(";", "").Replace(",", "");
return replace;
}
}
}