1

我正在尝试将 HyperLink 控件的NavigateUrl路径设置为文件,以便用户可以单击链接并下载文件。在我的 C# 和 ASPX 代码中,URL 似乎设置正确,但单击链接不会导致任何事情发生;右键单击链接并尝试保存链接尝试保存download.htm.

在幕后,我在 temp 目录中创建文件并将其移动到可用位置以供下载。这部分有效;我把它包括在内以供参考。

    private string MoveFile(string file_name, string file_path)
    {
        string tempdir = HttpContext.Current.Server.MapPath( ConfigurationManager.AppSettings["docs_folder"] );
        string new_file_name = Path.Combine( tempdir, Path.GetFileName( file_name ) );
        try
        {
            if (File.Exists( new_file_name ))
            {
                File.Delete( new_file_name );
            }
            File.Move( file_name, new_file_name );
        }
        catch (Exception e)
        {
            string message = e.Message;
        }
        return new_file_name;
    }

以下是我目前设置 URL 的方式:

        string download_file = downloader.DownloadFiles(); //Ultimately returns the path from the MoveFile method
        hl_download.NavigateUrl = "file:///" + HttpUtility.UrlPathEncode( download_file ).Replace("\\","//");
        hl_download.Visible = true;

我的输出看起来像: file:///C://users//codes%20with%20hammer//documents//visual%20studio%202012//Projects//Download%20File//Download%20File//Archive_to_download.zip

当我将此 URL 直接放入浏览器时,文件会正确下载。那么为什么它在超链接上不起作用呢?

我还尝试在静态超链接上设置属性。结果相同。为了比较: <asp:HyperLink ID="HyperLink1" runat="server" Visible="True" NavigateUrl="file:///C:/users/codes%20with%20hammer/documents/visual%20studio%202012/Projects/Download%20File//Download%20File//Archive_to_download.zip">click me</asp:HyperLink>

修改

我的 ASHX 页面中包含以下代码ProcessRequest

        context.Response.Clear();
        context.Response.ContentType = "application/octet-stream";
        context.Response.AddHeader( "Content-Disposition", "attachment; filename=" + Path.GetFileName(  download_file ));
        context.Response.WriteFile( context.Server.MapPath( download_file ) );
        context.Response.End();

也许我应该把它移到我的代码隐藏文件中?

4

3 回答 3

1

警告 - 前面有不安全的代码,不要使用。仅供演示。

因为您正在制作一个 HttpHandler(根据评论),所以您将如何设置 NavigateUrl:

string download_file = downloader.DownloadFiles(); //Ultimately returns the path from the MoveFile method
hl_download.NavigateUrl = "~/Handler.ashx?file="+download_file; //simply append the path
hl_download.Visible = true;

现在,问题在于 的值download_file将是服务器上的实际物理路径。如果您盲目地获取该值并使用它从文件系统中读取文件,那么黑客可以使用相同的技术从您的服务器下载任何文件,至少在您的应用程序文件夹中。

这更安全一些,根据您的情况可能可以使用

如果您决定使用该HttpHandler选项,则必须创建某种唯一令牌,从而将令牌与磁盘上文件的物理路径相关联。如果这是一个超链接,只需要在会话的整个生命周期内生成一次,您可以执行以下操作:

string token = System.Guid.NewGuid().ToString();
Session[token]=download_file; //put the token in the Session dictionary
hl_download.NavigateUrl = "~/Handler.ashx?file="+token;
hl_download.Visible = true;

现在,HttpHandler您可以简单地执行以下操作:

string file = Session[Request.QueryString["file"]];

if (file!=null)
{
     Response.Clear();
     Response.ContentType = "application/octet-stream";
     Response.AddHeader(string.Format("Content-Disposition", "attachment; filename={0}",Path.GetFileName(file)));                                            
     Response.WriteFile(Server.MapPath(file));
     Response.End();
}

为了能够在您的处理程序中访问 Session,您还必须实现IReadOnlySessionState

像这样的东西(完整代码,未经测试):

public class Handler : IHttpHandler, IReadOnlySessionState
{
   public bool IsReusable { get { return true; } }

   public void ProcessRequest(HttpContext ctx)
   {
        string file = ctx.Session[Request.QueryString["file"]];

        if (file!=null)
        {
           Response.Clear();
           Response.ContentType = "application/octet-stream";
           Response.AddHeader(string.Format("Content-Disposition", "attachment; filename={0}",Path.GetFileName(file)));                                            
           Response.WriteFile(Server.MapPath(file));
           Response.End();
         }
   }
}

当然,超链接仅在 Session 仍处于活动状态时才有效。如果您需要永久维护超链接,则需要完全不同地实现这一点。

这更安全,因为令牌不唯一的可能性非常小。也因为它只将令牌存储在会话中,所以如果另一个用户设法“猜测”令牌或尝试暴力方法,他仍然不会得到任何东西,因为价值根本不在他的会话上,而是在别人的.

于 2013-08-14T15:42:24.513 回答
0

终于让这个工作了。我使用了相对路径,./Archive_to_download.zip. 我已经为下一个 sprint 记录了 ASHX 方法。

于 2013-08-14T15:39:00.890 回答
0
 lb.NavigateUrl = "~/Picture/" + files[i].Name;
于 2016-09-06T16:44:12.010 回答