2014-02-05 97 views
0

我生成我的MVC應用程序的報告女巫然後出口到PDF和女巫然後保存在我的~/Reports/Invoices/目錄。我想逐一下載這些文件。文件下載MVC

這裏是我的類:

public class DownloadResult : ActionResult 
{ 

    public DownloadResult() 
    { 
    } 

    public DownloadResult(string virtualPath) 
    { 
     this.VirtualPath = virtualPath; 
    } 

    public string VirtualPath 
    { 
     get; 
     set; 
    } 

    public string FileDownloadName 
    { 
     get; 
     set; 
    } 

    public override void ExecuteResult(ControllerContext context) { 
     if (!String.IsNullOrEmpty(FileDownloadName)) { 
      context.HttpContext.Response.AddHeader("content-disposition", 
      "attachment; filename=" + this.FileDownloadName); 
     } 

     string filePath = context.HttpContext.Server.MapPath(this.VirtualPath); 
     context.HttpContext.Response.TransmitFile(filePath); 
    } 
} 

,這裏是我的控制器操作:

public ActionResult Download(int id) 
{ 

    return new DownloadResult 
       { 
        VirtualPath = "~/Reports/Invoices/" + Table.Where(x => x.ID == id).FirstOrDefault().ID + ".pdf", 
        FileDownloadName = Table.Where(x => x.ID == id).FirstOrDefault().ID.ToString() 
       }; 

} 

當我嘗試使用此代碼它是所有填充符號就像當你的局部視圖嘗試在記事本中打開一個二進制文件。

我在做什麼錯的任何想法?

我已經試過這樣:

 public FileResult Download(int id) 
     { 
      byte[] fileBytes = System.IO.File.ReadAllBytes(Server.MapPath("~/Reports/Invoices/" + Table.Where(x => x.ID == id).FirstOrDefault().ID + ".pdf")); 
      string fileName = Table.Where(x => x.ID == id).FirstOrDefault().ID.ToString(); 
      return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Pdf, fileName); 
     } 

,並得到相同的結果

Invoices.GridLoadDone = function() { 
$.contextMenu({ 
    selector: '#gbox_invoiceGrid', 
    callback: function (key, options) { 
     var m = "clicked: " + key; 
     switch (key) { 
      case "view": 
       Globals.PerformAjaxFromHyperlink(null, '#/Invoice/View/' + Invoices.CurrentRow, true, Invoices.CurrentRow); 
       Globals.SetUrl('#/Invoice/View/' + Invoices.CurrentRow, false); 
       return true; 
       break; 
      case "email": 
       Globals.PerformAjaxFromHyperlink(null, '/Invoice/Email/' + Invoices.CurrentRow, false); 
       break; 
      case "download": 
       Globals.PerformAjaxFromHyperlink(null, '/Invoice/Download/' + Invoices.CurrentRow, false); 
       //$("#readingsGrid").jqGrid('editRow', Readings.CurrentRow, 

       break; 

     } 
    }, 
    items: { 
     "view": { 
      name: "View Invoice" 
     }, 
     "email": { 
      name: "Email Invoice" 
     }, 
     "download": { 
      name: "Download Invoice" 
     }, 

    } 
}); 
+9

你爲什麼要重新創造'File()'helper和'FileResult'類? – SLaks

+0

你能告訴我如何用File()和FileResult類來做這件事嗎?我以前沒有與這方面的任何工作。 – Hydro

+0

不是一個確切的重複,但看看http://stackoverflow.com/questions/3604562/download-file-of-any-type-in​​-as-net-mvc-using-fileresult – Yuck

回答

1

恕我直言,你可能想從您的網站結構內以書面形式物理文件望而卻步。

這不僅會阻止您將應用程序部署到webfarm上的多個服務器,還可能會使使用WebDeploy等工具部署複雜化。

您可能想要考慮將它們存儲在數據庫或IIS Web應用程序之外的其他某個共享位置。

另外,對於文件下載,不需要使用ajax,標準的GET會做,比如只使用常規的超鏈接。但是,我不會推薦將虛擬路徑作爲參數從客戶端傳遞到服務器。 相反,如何在DownloadController中執行名爲Report的操作,該操作僅接收ID作爲參數? http://somewhere.com/download/report/3http://somewhere.com/download/report?id=3

在這一動作,你可以只使用在評論中提到的方法,使用​​和FileResult

你可以用更友好的URL,如結束。有了這些,您可以直接返回byte[]內容或虛擬路徑,例如:File("~/virtualpath", [content-type]),也可以爲下載的文件指定名稱。

您可能會看到二進制內容的原因是因爲您沒有發佈標準GET並讓瀏覽器處理響應,而是使用ajax代替。

+0

這是此項目的標準。這是一個非常大的項目,我們有很多開發人員正在研究它,所以我必須堅持這些標準。我想要下載的文件是動態生成的報告,然後導出爲pdf並下載,這就是爲什麼它們不在數據庫或其他目錄中。有沒有其他的方式做文件下載,如果這不會與ajax一起工作? – Hydro

0

下面你會發現我的最新嘗試。即使我指定content typeapplication/pdfapplication/octet-stream,它仍然會以文本的形式將它返回到視圖中。

public static void TransmitFile(string url) 
    { 
     string ext = url.Substring(url.LastIndexOf("."), url.Length - url.LastIndexOf(".")); 
     string filename = url.Substring(url.LastIndexOf("/") + 1, url.Length - ext.Length - url.LastIndexOf("/") - 1).Replace(" ", "_"); 

     if (filename + ext == url) 
     { 
      filename = filename.Replace(AppDomain.CurrentDomain.BaseDirectory, "").Replace("\\", "/"); 
      filename = filename.Substring(filename.LastIndexOf("/") + 1, filename.Length - filename.LastIndexOf("/") - 1); 
     } 

     if (url.Contains("\\")) 
      url = url.Replace(AppDomain.CurrentDomain.BaseDirectory, "").Replace("\\", "/"); 

     RegistryKey key = Registry.ClassesRoot.OpenSubKey(ext); 
     string contentType = key.GetValue("Content Type").ToString(); 

     try 
     { 
      HttpContext.Current.Response.Clear(); 
      HttpContext.Current.Response.ContentType = contentType; 
      HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename + ext); 
      HttpContext.Current.Response.TransmitFile(HttpContext.Current.Server.MapPath(url)); 
      HttpContext.Current.Response.End(); 
     } 
     catch { } 
    } 
}