2013-04-18 26 views
8

Tôi đang truyền dữ liệu từ máy chủ đến ứng dụng khách để tải xuống bằng cách sử dụng filestream.write. Trong trường hợp đó những gì đang xảy ra là tôi có thể tải xuống tệp nhưng nó không xuất hiện dưới dạng tải xuống trong trình duyệt của tôi. Cửa sổ bật lên cho "Lưu dưới dạng" xuất hiện không phải "Thanh tải xuống" xuất hiện trong phần Tải xuống. Từ nhìn xung quanh, tôi đoán tôi cần phải bao gồm "cái gì đó" trong tiêu đề phản hồi để cho trình duyệt biết rằng có tệp đính kèm với phản hồi này. Ngoài ra tôi muốn đặt cookie. Để thực hiện điều này, đây là những gì tôi đang làm:thêm tiêu đề vào phản hồi http trong một hành động bên trong bộ điều khiển trong asp.net/mvc

 [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"); 
    } 

Tôi nhận lỗi rằng: "System.web.httpcontext.current là một tài sản và được sử dụng như một loại"

Tôi có đang cập nhật tiêu đề ở đúng vị trí không? Có cách nào khác để làm điều này?

Trả lời

11

Có, bạn đang thực hiện nó sai cách thử điều này, bạn nên thêm tiêu đề bên trong hành động của bạn không phải là tiêu đề thuộc tính vào phương thức của bạn.

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

hoặc

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

Cập nhật Như tôi hiểu bạn đang thực hiện cuộc gọi ajax để điều khiển của bạn/hành động mà wont làm việc cho tập tin tải về bằng cách trực tiếp gọi một hành động. Bạn có thể đạt được nó theo cách này.

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"; 
     } 

hoặc

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" 
     }; 
    } 

Trong nút JS của bạn bấm bạn chỉ có thể làm điều gì đó tương tự như sau.

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

tôi đã cố gắng làm điều này.Nhưng nó vẫn không hiển thị hộp thoại "Lưu dưới dạng" và cũng không phải thanh tiến trình tải xuống trong phần tải xuống của trình duyệt. – ezile

+0

Điều này làm việc cho tôi và tôi thấy html xem được tải xuống trong trường hợp thử nghiệm của tôi. Đối với bạn nó có thể là bởi vì bạn đang chuyển hướng hành động. Tôi đã không thử kịch bản này mặc dù. Chỉ cần thử đặt tiêu đề này trong Chỉ mục để thử. – PSL

+0

Tôi sẽ chi tiết hơn một chút. Tôi đang ở trang "Chỉ mục" và sau đó nhấp vào Tải xuống, sau đó gọi Tải xuống hành động thông qua JavaScript. Đoạn mã trên được viết trong hành động Tải xuống. Và sau khi phát trực tuyến tệp cho người dùng, tôi chuyển hướng đến trang Chỉ mục. Tôi bối rối như trong khi nào tôi nên nói với trình duyệt rằng có một tải xuống. Tôi có nghĩa là tôi đang gửi các công cụ bằng cách sử dụng FileStream.WriteSync, vì vậy tôi đoán tôi cần phải nói với trình duyệt trước khi gửi tệp có tệp đính kèm và do đó nó sẽ bật lên hộp thoại "lưu dưới dạng". Tôi nghĩ rằng tôi đang bối rối trong công việc ở đây và do đó không khi nào và ở đâu tôi nên thực hiện thay đổi. – ezile

3

Hãy xem here.

Sau đây được lấy từ trang web được tham chiếu.

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

Sửa 1:

Thêm mục nào đó mà có thể có nhiều quan tâm của bạn từ ol tốt của chúng tôi' SO. Bạn có thể kiểm tra đầy đủ chi tiết 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

Thay đổi:

return RedirectToAction("Index"); 

tới:

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

Và di chuyển tuyên bố quay trở lại bên trong câu lệnh using bạn.

0

Trước đây tôi đã xây dựng một danh sách cho phép để cho phép một số miền đặt iframe trang web của tôi. Nhớ bộ nhớ cache hình ảnh của Google được sử dụng cho các trang web khung nội tuyến.

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; 
    } 
Các vấn đề liên quan