1

ユーザーがリンクをクリックしてファイルをダウンロードできるように、HyperLink コントロールのNavigateUrlパスをファイルに設定しようとしています。私の C# および ASPX コードでは、URL が適切に設定されているように見えますが、リンクをクリックしても何も起こりません。リンクを右クリックしてリンクを保存しようとすると、download.htm.

舞台裏では、一時ディレクトリにファイルを作成し、ダウンロード可能な場所に移動しています。この部分は機能します。参考までに載せておきます。

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

ハンドラーでセッションにアクセスできるようにするには、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();
         }
   }
}

もちろん、ハイパーリンクはセッションがまだアクティブな間のみ有効です。ハイパーリンクを永久に維持する必要がある場合は、これをまったく別の方法で実装する必要があります。

トークンが一意ではない可能性が非常に低いため、これはより安全です。また、セッションにトークンを保存するだけであるため、別のユーザーがトークンを「推測」したり、ブルートフォースアプローチを試みたりしても、値は単に彼のセッションではなく他の誰かのセッションにあるため、何も取得できません。 .

于 2013-08-14T15:42:24.513 に答える
0

最後にこれを機能させました。相対パスを使用しました./Archive_to_download.zip。次のスプリントの ASHX メソッドを文書化しました。

于 2013-08-14T15:39:00.890 に答える