2013-04-18 10 views
8

Przesyłam dane z serwera do klienta do pobrania przy użyciu filestream.write. W takim przypadku mogę pobrać plik, ale nie jest on wyświetlany w mojej przeglądarce. Wyskakujące okienko "Zapisz jako" nie pojawia się "Pasek pobierania" pojawia się w sekcji Pobieranie. Od rozglądania się, myślę, że muszę umieścić "coś" w nagłówku odpowiedzi, aby poinformować przeglądarkę, że istnieje załącznik z tą odpowiedzią. Również chcę ustawić plik cookie. Aby to osiągnąć, to co robie:Dodawanie nagłówka do odpowiedzi HTTP w działaniu wewnątrz kontrolera w 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"); 
    } 

Dostaję komunikat, że: „System.web.httpcontext.current jest własnością i jest używany jako typ”

Czy dokonuję aktualizacji nagłówka we właściwym miejscu? Czy jest jakiś inny sposób na zrobienie tego?

Odpowiedz

11

Tak, robisz to w niewłaściwy sposób, spróbuj tego, powinieneś dodać nagłówek w swojej akcji, nie jako nagłówek atrybutu do twojej metody.

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

lub

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

Aktualizacja jak rozumiem robisz wywołanie ajax do kontrolera/działania, które przyzwyczajenie praca dla pobierania plików poprzez bezpośrednie wywołanie działania. Możesz to osiągnąć w ten sposób.

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

lub

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

W swojej kliknij przycisk JS można po prostu zrobić coś podobnego do tego.

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

Próbowałem to zrobić.Wciąż jednak nie pokazuje okna dialogowego "Zapisz jako" ani paska postępu pobierania w sekcji pobierania w przeglądarce. – ezile

+0

To działa dla mnie i widzę, że html widoku jest pobierany w moim przypadku testowym. Dla ciebie może to być spowodowane przekierowaniem na działanie. Jednak nie próbowałem tego scenariusza. Po prostu spróbuj umieścić ten nagłówek pod Index tylko po wypróbowaniu. – PSL

+0

Będę szczegółowo więcej. Jestem na stronie "Indeks", a następnie klikam Pobierz, a następnie wywołuj akcję Pobierz za pomocą JavaScript. Powyższy kod jest zapisany w akcji Pobierz. Po przesłaniu pliku do użytkownika przekierowuję na stronę indeksu. Jestem zdezorientowany, kiedy powinienem powiedzieć przeglądarce, że jest pobieranie. Chodzi mi o to, że wysyłam te rzeczy za pomocą FileStream.WriteSync, więc domyślam się, że muszę wysłać przeglądarkę przed wysłaniem pliku, że jest załącznik i tym samym wyskoczy okno dialogowe "zapisz jako". Myślę, że jestem zdezorientowany w przepływie pracy, a zatem nie mam czasu i miejsca, gdzie powinienem dokonać zmiany. – ezile

3

Proszę spojrzeć na here.

Następujące elementy pochodzą ze strony z odniesieniami.

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

Edit 1:

Dodawanie coś, co może być bardziej zainteresowanie z naszej dobrej ol”SO. Możesz sprawdzić pełny szczegół 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

Zmiana:

return RedirectToAction("Index"); 

do:

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

i przesunąć return do wewnątrz przy użyciu instrukcji.

0

W przeszłości tworzyłem białą listę, aby niektóre domeny mogły korzystać z mojej witryny. Pamiętaj, że pamięć podręczna obrazów Google służy również do obsługi stron internetowych.

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; 
    } 
Powiązane problemy