2013-04-18 7 views
8

filestream.writeを使用してサーバーからクライアントにストリーミングデータをダウンロードしています。その場合、何が起こっているのですか?私はファイルをダウンロードすることができますが、それはブラウザにダウンロードとして表示されません。 [ダウンロード]セクションに[名前を付けて保存]のポップアップが表示されず、[ダウンロードバー]が表示されません。見て回ってみると、レスポンスヘッダーに「何か」を含めて、このレスポンスに添付ファイルがあることをブラウザに伝える必要があると思います。また、私はクッキーを設定したい。asp.net/mvcのコントローラー内のアクション内でHTTP応答にヘッダーを追加

 [HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=" & name)] 
    public ActionResult Download(string name) 
    { 
      // some more code to get data in inputstream. 

      using (FileStream fs = System.IO.File.OpenWrite(TargetFile)) 
      { 
       byte[] buffer = new byte[SegmentSize]; 
       int bytesRead; 
       while ((bytesRead = inputStream.Read(buffer, 0, SegmentSize)) > 0) 
       { 
        fs.WriteAsync(buffer, 0, bytesRead); 
       } 
      } 
     } 
     return RedirectToAction("Index"); 
    } 

私はというエラーを取得しています:これを実現するために、これは私がやっているものです「System.web.httpcontext.currentは財産であり、タイプとして使用されています」

適切な場所でヘッダーを更新していますか?これを行うための他の方法はありますか?

答えて

11

はい、間違ったやり方でこれを試しています。あなたのメソッド内の属性ヘッダーではなく、アクション内にヘッダーを追加する必要があります。

HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=" & name) 

または

Request.RequestContext.HttpContext.Response.AddHeader("Content-Disposition", "Attachment;filename=" & name) 

更新 私はあなたが直接アクションを呼び出すことによって、ファイルのダウンロードのために仕事を文句を言わないあなたのコントローラ/アクションへのAJAX呼び出しを行っている理解しています。このようにして達成することができます。あなたのJSボタンで

public void Download(string name) 
     { 
//your logic. Sample code follows. You need to write your stream to the response. 

      var filestream = System.IO.File.ReadAllBytes(@"path/sourcefilename.pdf"); 
      var stream = new MemoryStream(filestream); 
      stream.WriteTo(Response.OutputStream); 
      Response.AddHeader("Content-Disposition", "Attachment;filename=targetFileName.pdf"); 
      Response.ContentType = "application/pdf"; 
     } 

または

public FileStreamResult Download(string name) 
    { 
     var filestream = System.IO.File.ReadAllBytes(@"path/sourcefilename.pdf"); 
     var stream = new MemoryStream(filestream); 


     return new FileStreamResult(stream, "application/pdf") 
     { 
      FileDownloadName = "targetfilename.pdf" 
     }; 
    } 

あなただけのこれに似た何かを行うことができます。

$('#btnDownload').click(function() { 
      window.location.href = "controller/download?name=yourargument"; 
    }); 
+0

私はこれをやってみました。しかし、それでもブラウザの[ダウンロード]セクションには[名前を付けて保存]ダイアログボックスとダウンロードプログレスバーは表示されません。 – ezile

+0

これは私のために働いて、私はビューのHTMLが私のテストケースにダウンロードされて参照してください。あなたのためには、あなたが行動へのリダイレクトである可能性があります。私はこのシナリオを試していない。このヘッダをIndexの下に置いて試してみてください。 – PSL

+0

もう少し詳しく説明します。私は「インデックス」ページにいて、次にダウンロードをクリックしてJavaScriptを介してダウンロードアクションを呼び出します。上記のコードはダウンロードアクションで書かれています。ファイルをユーザーにストリーミングした後、私はIndexページにリダイレクトします。私はブラウザにダウンロードがあると言わなければならないときと同じように混乱しています。私は、FileStream.WriteSyncを使用してファイルを送信していることを意味するので、添付ファイルがあることをファイルに送信する前にブラウザに指示する必要があると思われますので、「名前を付けて保存」ダイアログボックスがポップアップ表示されます。私はここのワークフローでは混乱していると思うので、いつ、どこで変更するべきではありません。 – ezile

3

hereをご覧ください。

以下は、参照先のWebサイトから取得したものです。

public FileStreamResult StreamFileFromDisk() 
{ 
    string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/"; 
    string fileName = "test.txt"; 
    return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName); 
} 

編集1:

SOたちの古き良きからご関心のよりかもしれない何かを追加します。 hereの詳細を確認できます。

public ActionResult Download() 
{ 
    var document = ... 
    var cd = new System.Net.Mime.ContentDisposition 
    { 
     // for example foo.bak 
     FileName = document.FileName, 

     // always prompt the user for downloading, set to true if you want 
     // the browser to try to show the file inline 
     Inline = false, 
    }; 
    Response.AppendHeader("Content-Disposition", cd.ToString()); 
    return File(document.Data, document.ContentType); 
} 
0

変更:

return RedirectToAction("Index"); 

へ:

return File(fs, "your/content-type", "filename"); 

そして、あなたの使って文の中にreturn文を移動します。

0

以前は、一部のドメインで自分のサイトのiframeを許可するホワイトリストを作成しました。 iframeのサイトにも使用されていたGoogleのイメージキャッシュを忘れないでください。

static HashSet<string> frameWhiteList = new HashSet<string> { "www.domain.com", 
                "mysub.domain.tld", 
                "partner.domain.tld" }; 

    protected void EnforceFrameSecurity() 
    { 
     var framer = Request.UrlReferrer; 
     string frameOptionsValue = "SAMEORIGIN"; 

     if (framer != null) 
     { 
      if (frameWhiteList.Contains(framer.Host)) 
      { 
       frameOptionsValue = string.Format("ALLOW-FROM {0}", framer.Host); 
      } 

     } 

     if (string.IsNullOrEmpty(HttpContext.Current.Response.Headers["X-FRAME-OPTIONS"])) 
     { 
      HttpContext.Current.Response.AppendHeader("X-FRAME-OPTIONS", frameOptionsValue); 
     } 
    } 
0
public FileResult DownloadDocument(string id) 
     { 
      if (!string.IsNullOrEmpty(id)) 
      { 
       try 
       { 
        var fileId = Guid.Parse(id); 

       var myFile = AppModel.MyFiles.SingleOrDefault(x => x.Id == fileId); 

       if (myFile != null) 
       { 
        byte[] fileBytes = myFile.FileData; 
        return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, myFile.FileName); 
       } 
      } 
      catch 
      { 
      } 
     } 

     return null; 
    } 
関連する問題