2011-08-23 16 views
8

Używam MVC 3 Chciałbym dynamicznie utworzyć plik CSV do pobrania, ale nie jestem pewien co do właściwego podejścia zorientowanego na MVC.Kontroler MVC korzystający ze strumienia odpowiedzi

W konwencjonalnym ASP.net, bym napisał coś takiego:

Response.ClearHeaders(); 
Response.ContentType = "text/csv"; 
Response.AddHeader("content-disposition", attachment;filename='Test.csv'"); 
Response.Write("1,2,3"); 
Response.End(); 

Mam spojrzał na działanie ContentResult ale wydaje się, że będzie trzeba utworzyć wynik jako ciąg znaków, tj

return Content (myData, "text/csv");

Mogę, jak sądzę, zbudować ciąg znaków, ale ponieważ te pliki mogą mieć kilka tysięcy linii, wydaje mi się to mało skuteczne.

Czy ktoś może wskazać mi właściwy kierunek? Dzięki.

+0

Utwórz niestandardowy typ ActionResult opisany w tym wpisie: [http://stackoverflow.com/questions/989927/recommended-way-to-create-an-actionresult-w--file-extension?rq=1] [1] [1]: http://stackoverflow.com/questions/989927/recommended-way-to-create-an-actionresult-with-a-file-extension?rq=1 –

+0

Wygląda rzeczywiście na duplikat http://stackoverflow.com/q/943122/1178314 który ma dość dobrą odpowiedź imho (http://stackoverflow.com/a/13456219/1178314) –

Odpowiedz

5

Spędziłem trochę czasu na podobny problem wczoraj, a oto jak to zrobić właściwą drogę:

public ActionResult CreateReport() 
{ 
    var reportData = MyGetDataFunction(); 
    var serverPipe = new AnonymousPipeServerStream(PipeDirection.Out); 
    Task.Run(() => 
    { 
     using (serverPipe) 
     { 
      MyWriteDataToFile(reportData, serverPipe) 
     } 
    }); 

    var clientPipe = new AnonymousPipeClientStream(PipeDirection.In, 
      serverPipe.ClientSafePipeHandle); 
    return new FileStreamResult(clientPipe, "text/csv"); 
} 
+0

czy jesteś pewien/czego używać (serverPipe)? będzie używany w FileStreamResult (clientPipe) Co się stanie, jeśli zadanie zostanie uruchomione szybko? – Slava

+0

@Slava system będzie zarządzał przepływem danych między dwoma końcami rury, więc nie powinno to być problemem. Potrafi pochłonąć wszystkie dane, innymi słowy, zadanie nie zostanie nagle zakończone, zostanie wstrzymane albo w formie zapisu, albo w bliskim strumieniu. Spróbuj, działa. – galets

3

spróbować powrocie jeden z FileResult s: http://msdn.microsoft.com/en-us/library/system.web.mvc.fileresult.aspx

patrz też poniższy przykład: http://forums.asp.net/t/1491579.aspx/1

+0

Używam obecnie czegoś podobnego z File (Encoding.UTF8.GetBytes (sb .ToString()), "text/csv", fileName), ale nadal wydaje się być potencjalnym problemem do zbudowania całego wyjścia w pamięci przed zatwierdzeniem widoku/odpowiedzi. – Neilski

+0

Zbadaj pozostałe przeciążenia pliku(). Proszę spojrzeć na linki, które zamieściłem. Niektóre przeciążenia nie wymagają budowania pliku w pamięci. –

+0

Nie buduje tablicy bajtów (bajt []), która wciąż finalizuje dane wyjściowe w pamięci przed jej zatwierdzeniem w pliku ActionResult? Przykład: return File (imageData, "image/jpeg", "fileName.jpg"); – Neilski

13

Znalazłem jedno możliwe rozwiązanie tego problemu. Możesz po prostu zdefiniować metodę akcji, która zwróci EmptyResult() i zapisze bezpośrednio w strumieniu odpowiedzi. Na przykład:

public ActionResult RobotsText() { 
    Response.ContentType = "text/plain"; 
    Response.Write("User-agent: *\r\nAllow: /"); 
    return new EmptyResult(); 
} 

To wydaje się działać bez żadnych problemów. Nie wiem, jak „MVC” to jest ...

+0

To jest hack, kontroler MVC nie powinien pisać bezpośrednio do strumienia odpowiedzi.To powinno być zadaniem metody ExecuteResult obiektu wyniku działania. –

-1

Spróbuj czegoś takiego:

public ActionResult CreateReport(string report, string writer) 
{ 
    var stream = new MemoryStream(); 
    var streamWriter = new StreamWriter(stream); 

    _generateReport.GenerateReport(report, writer); 

    streamWriter.Flush(); 
    stream.Seek(0, SeekOrigin.Begin); 

    return new FileStreamResult(stream, writer.MimeType); 
} 
+1

To całkowicie pokonuje cel strumieni. Nie rób tego w kodzie produkcyjnym. – makhdumi

Powiązane problemy