2011-08-23 17 views
8

Estoy usando MVC 3 Me gustaría crear dinámicamente un archivo CSV para descargar, pero no estoy seguro del correcto enfoque orientado a MVC.Controlador MVC mediante Response Stream

En ASP.net convencional, habría escrito algo como:

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

He mirado en la acción ContentResult pero parece que necesitaría para crear el resultado como una cadena, es decir

devolver contenido (myData, "text/csv");

Podría, supongo, construir una cadena, pero dado que estos archivos podrían tener varios miles de líneas de longitud, esto me parece ineficiente.

¿Podría alguien señalarme en la dirección correcta? Gracias.

+0

Cree un tipo ActionResult personalizado como se detalla en esta publicación: [http://stackoverflow.com/questions/989927/recommended-way-to-create-an-actionresult-with-aile-file-extension?rq=1] [1] [1]: http://stackoverflow.com/questions/989927/recommended-way-to-create-an-actionresult-with-a-file-extension?rq=1 –

+0

Parece de hecho como un duplicado de http://stackoverflow.com/q/943122/1178314 que tiene una respuesta bastante buena imho (http://stackoverflow.com/a/13456219/1178314) –

Respuesta

5

pasé algún tiempo en el problema similar ayer, y aquí está cómo hacerlo correctamente:

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

¿Estás seguro de usar (serverPipe)? se usará en FileStreamResult (clientPipe. ¿Qué sucede si la tarea se ejecuta rápidamente? – Slava

+0

@Slava system administrará el flujo de datos entre dos extremos de la tubería, por lo que no debería ser una preocupación. No permitirá que la tarea cierre el conducto del servidor hasta que esté capaz de consumir todos los datos. En otras palabras, la tarea no se cerrará abruptamente, sino que se llevará a cabo ya sea en escritura o en flujo cerrado. Pruébelo, funciona. – galets

3

intenta volver uno de los FileResult s: http://msdn.microsoft.com/en-us/library/system.web.mvc.fileresult.aspx

también vemos este ejemplo: http://forums.asp.net/t/1491579.aspx/1

+0

Actualmente estoy usando algo similar con File (Encoding.UTF8.GetBytes (sb) .ToString()), "text/csv", fileName) pero aún parece ser un problema potencial para construir todo el resultado en la memoria antes de comprometerse con la vista/respuesta. – Neilski

+0

Investigue las otras sobrecargas de File(). Por favor, eche un vistazo a los enlaces que publiqué. Algunas de las sobrecargas no requieren que construyas el archivo en la memoria. –

+0

¿No está construyendo una matriz de bytes (byte []) aún finalizando los datos de salida en la memoria antes de enviarlos al File ActionResult? Ejemplo: return File (imageData, "image/jpeg", "fileName.jpg"); – Neilski

13

he encontrado una posible solución a este problema. Simplemente puede definir el método de acción para devolver un EmptyResult() y escribir directamente en la secuencia de respuesta. Por ejemplo:

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

Parece que funciona sin problemas. No sabe cómo 'MVC' es ...

+0

Es un truco, se supone que un controlador MVC no debe escribir directamente en el flujo de respuesta.Se supone que esto es el trabajo del método ExecuteResult de un objeto de resultado de acción. –

-1

intentar algo como esto:

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

Esto anula por completo el objetivo de Streams. Por favor, no hagas esto en el código de producción. – makhdumi

Cuestiones relacionadas