2010-08-30 15 views
5

Chcę włączyć pobieranie pliku w mojej aplikacji MVC, bez korzystania z hiperłącza. Planuję użyć obrazu lub podobnego i sprawię, że będzie można go klikać za pomocą jQuery. W tej chwili mam prosty test.Pobieranie pliku w Asp.Net MVC 2

Znalazłem wyjaśnienie, jak wykonać pobieranie za pomocą metody akcji, ale niestety przykład nadal zawierał linki akcji.

Teraz mogę wywołać metodę akcji pobierania, ale nic się nie dzieje. Chyba muszę coś zrobić z wartością zwracaną, ale nie wiem, co i jak.

Oto sposób działania:

public ActionResult Download(string fileName) 
    { 
     string fullName = Path.Combine(GetBaseDir(), fileName); 
     if (!System.IO.File.Exists(fullName)) 
     { 
      throw new ArgumentException("Invalid file name or file does not exist!"); 
     } 

     return new BinaryContentResult 
     { 
      FileName = fileName, 
      ContentType = "application/octet-stream", 
      Content = System.IO.File.ReadAllBytes(fullName) 
     }; 
    } 

Oto klasa BinaryContentResult:

public class BinaryContentResult : ActionResult 
{ 
    public BinaryContentResult() 
    { } 

    public string ContentType { get; set; } 
    public string FileName { get; set; } 
    public byte[] Content { get; set; } 

    public override void ExecuteResult(ControllerContext context) 
    { 

     context.HttpContext.Response.ClearContent(); 
     context.HttpContext.Response.ContentType = ContentType; 

     context.HttpContext.Response.AddHeader("content-disposition", 

               "attachment; filename=" + FileName); 

     context.HttpContext.Response.BinaryWrite(Content); 
     context.HttpContext.Response.End(); 
    } 
} 

I wywołać metodę działania poprzez:

<span id="downloadLink">Download</span> 

która jest wykonana klikalne poprzez:

$("#downloadLink").click(function() { 
    file = $(".jstree-clicked").attr("rel") + "\\" + $('.selectedRow .file').html(); 
    alert(file); 
    $.get('/Customers/Download/', { fileName: file }, function (data) { 
     //Do I need to do something here? Or where? 
    }); 
}); 

Zwróć uwagę, że parametr nazwa_pliku został poprawnie odebrany przez metodę akcji i wszystko, po prostu nic się nie dzieje, więc myślę, że muszę jakoś obsłużyć wartość zwrotu?

+0

Twoja klasa 'BinaryContentResult' nie powinna istnieć. Użyj 'FileResult'. – SLaks

+0

Ok, czy to standardowa klasa czy coś takiego? Jak to pomoże mi rozwiązać problem? – Anders

Odpowiedz

4

Nie chcesz pobierać pliku za pomocą AJAX, chcesz, aby przeglądarka go pobrała. Funkcja $ .get() pobierze ją, ale nie ma sposobu na zapisanie lokalnie z Javascript, ze względów bezpieczeństwa konieczne jest włączenie przeglądarki. Po prostu przekieruj do lokalizacji pobierania, a przeglądarka zrobi to za Ciebie.

+0

Ok, czy mógłbyś podać, co masz na myśli? Chodzi mi o to, że mógłbym użyć prostych linków do tego, jak w przykładzie, z którego to zrobiłem, a strona nie załaduje się ponownie, ale po prostu otwórz okno zapisu jako. Chcę tego samego zachowania, ale klikając na zakres (zamiast tego, który plik ma być pobrany przez klasę wyboru). Czy mógłbyś podać jakiś kod? Dzięki! – Anders

+1

Użyj "document.location.href = ...", aby poinformować przeglądarkę, aby przejść do adresu URL w celu pobrania pliku. Zobaczy nagłówek treści i wyświetli go jako pobranie, nie jako stronę. –

+0

Idealnie! Jeszcze jedno pytanie, zanim zamknę ten problem: Kiedy pojawi się okno dialogowe Zapisz jako, zawiera ono nazwę pliku połączoną z podkreśleniami ze ścieżki i nazwy pliku, na przykład: folder_folder_plik.txt. Dlaczego? Mam na myśli, że pobieranie działa i wszystko, ale chcę, żeby miał swoją oryginalną nazwę pliku. (Przechodzenie przez metodę akcji i BinaryContentResult Zmienna FileName ma regularną ścieżkę: folder \\ folder \\ plik.txt Nie mogę określić, gdzie ma miejsce ta konkatenacja z podkreśleniami. Wszelkie pomysły? – Anders

Powiązane problemy