在 asp.net 中下载 SQL 备份文件

Posted

技术标签:

【中文标题】在 asp.net 中下载 SQL 备份文件【英文标题】:download a SQL back up file in asp.net 【发布时间】:2021-12-10 16:15:00 【问题描述】:

我正在尝试下载 sql 备份文件但出现错误: respone.end() 附近的“无法评估表达式,因为代码已优化或本机框架位于调用堆栈顶部”

protected void btnDownload_Click(object sender, EventArgs e)
    
        try
        
            string backupDestination = backupPath;
            string dbNAme = dbName;
            string dateStamp = DateTime.Now.ToString("yy-MM-dd@HHmm");
            string backupfile = backupDestination + '\\' + dbNAme + " of " + dateStamp + ".bak";

            DataTable dt = blu.queryFunction("BACKUP database " + dbNAme + " to disk='" + backupDestination + "\\" + dbNAme + " of " + dateStamp + ".Bak'");

            WebClient req = new WebClient();
            HttpResponse response = HttpContext.Current.Response;

            response.Clear();
            response.ClearContent();
            response.ClearHeaders();
            response.Buffer = true;

            response.AddHeader("content-disposition", "attachment; filename= " + dbNAme + ".bak");
            
            byte[] data = req.DownloadData(backupfile);
            response.ContentType = "application/sql";
            response.BinaryWrite(data);
            response.End();
        
        catch (Exception ex)
        
            ScriptManager.RegisterStartupScript(this, this.GetType(), "alertscipt", "swal('Error!','Database Backup Failed." + ex.ToString() + "','warning')", true);
        
    

【问题讨论】:

字符串备份目的地 = "C:\SQLBackUpFolder";字符串 dbNAme = "测试"; 只是一个想法;您是否尝试过在不使用 try/catch 的情况下运行它,以确保您不会碰巧以某种方式隐藏原始异常? @Culme 我也试过了,它没有显示任何错误,但文件没有被下载 您是否尝试过提前创建备份文件,只测试代码的文件下载部分?在您尝试传输备份文件时,备份文件似乎尚未完全创建。 @Culme 我在尝试下载之前检查了备份是否已经完成,我像你说的那样尝试过,仍然发生同样的错误 【参考方案1】:

我看到的一个问题是缓冲区 - 将 response.Buffer = true; 更改为 false

response.Buffer = false;

对于大文件,这是错误的,因为它会将其放在缓冲区中,但您想将其直接发送给用户...

同时删除 catch (Exception ex) 以查看代码中的其他问题 - 从您更改标头的那一刻起,ScriptManager.RegisterStartupScript 就不会运行。所以这个问题对你来说是隐藏的。

另一种更好、更正确的方法是创建一个处理程序并从那里下载文件。

【讨论】:

【参考方案2】:

如果运行应用程序的服务器上存在备份文件,则不应使用 WebClient。从本地磁盘读取文件的东西,例如TransmitFile() 就足够了——像这样:

string backupDestination = backupPath;
string dbNAme = dbName;
string dateStamp = DateTime.Now.ToString("yy-MM-dd@HHmm");
string backupfile = backupDestination + '\\' + dbNAme + " of " + dateStamp + ".bak";

DataTable dt = blu.queryFunction("BACKUP database " + dbNAme + " to disk='" + backupDestination + "\\" + dbNAme + " of " + dateStamp + ".Bak'");

HttpResponse response = HttpContext.Current.Response;

response.Clear();
response.ClearContent();
response.ClearHeaders();
response.Buffer = true;

response.AddHeader("content-disposition", "attachment; filename= " + dbNAme + ".bak");

response.ContentType = "application/octet-stream";
response.TransmitFile(backupfile);
response.Flush();

【讨论】:

代码运行但没有下载文件 奇怪...如果您同时执行 Response.Flush() 和 Response.End() 会怎样?您是否从服务器得到任何响应,或者当您单击按钮时会发生什么?【参考方案3】:

好的,所以 72 小时后我发现了错误。下载按钮位于更新面板内,所以我得到“无法评估表达式,因为代码已优化或本机框架位于调用堆栈顶部”

protected void btnDownload_Click(object sender, EventArgs e)
    
        try
        
            string dbNAme = dbName;
            string backupDestination = Server.MapPath("~/BackUp");
            string dateStamp = DateTime.Now.ToString("yyyy-MM-dd@HH_mm");
            string fileName = dbName + " of " + dateStamp + ".Bak";

            if (!Directory.Exists(backupDestination))
            
                Directory.CreateDirectory(backupDestination);
            

            DataTable dt = blu.queryFunction("BACKUP database " + dbNAme + " to disk='" + backupDestination + "\\" + fileName + "'");


            byte[] bytes = File.ReadAllBytes(Path.Combine(backupDestination, fileName));
            // Delete .bak file from server folder.
            if (Directory.Exists(backupDestination))
            
                Directory.Delete(backupDestination, true);
            
            Response.Clear();
            Response.Buffer = false;
            Response.Charset = "";
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.ContentType = "application/octet-stream";
            Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
            Response.BinaryWrite(bytes);
            Response.Flush();
            Response.End();
        
        catch(Exception ex)
        
            string exception = ex.ToString();
                    
    

【讨论】:

以上是关于在 asp.net 中下载 SQL 备份文件的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.NET MVC 操作中获取绝对 URL

asp.net程序已经被注入了,该怎么办?

[ASP.NET][C#]下载文件时中文文件名出现乱码

sql文件乱码

备份SQL Server数据库到Azure Storage

极佳SQL数据库备份工具 免费下载 有效防御勒索病毒加密数据库备份