2010-11-04 8 views
19

Estamos proporcionando los archivos que se guardan en la base de datos y la única manera de recuperarlos es yendo por su id como en:Obtener el nombre de archivo durante la descarga se

www.AwesomeURL.com/AwesomeSite.aspx?requestedFileId=23

Todo está fichero de trabajo que a mí usando el WebClient Class.

Sólo hay un problema que estoy enfrentando:

¿Cómo puedo obtener la verdadera nombre de archivo?

Mi código es el siguiente atm:

WebClient client = new WebClient(); 

string url = "www.AwesomeURL.com/AwesomeSite.aspx?requestedFileId=23"; 

client.DownloadFile(url, "IDontKnowHowToGetTheRealFileNameHere.txt"); 

único que sé es la Identificación.

Esto no sucede cuando intento acceder a url desde el navegador donde llegar es el nombre propio =>DownloadedFile.xls.

¿Cuál es la forma correcta de obtener la respuesta correcta?

+0

¿Ha encontrado la solución? Si ninguna de las respuestas aquí te ayudó y la encontraste, por favor, compártelo con nosotros. :) –

+0

En realidad, no encontré ninguna solución ... escondí el código y aún esperaba alguna inspiración al azar;) –

+0

¿Qué sucede cuando intentas con el código sugerido en mi respuesta? Nunca has comentado allí ... –

Respuesta

4

Usted puede utilizar cabecera HTTP content-disposition sugerir nombres de archivo para el contenido de su sitio:

Content-Disposition: attachment; filename=downloadedfile.xls; 

Así, en el script AwesomeSite.aspx, se debe establecer la cabecera content-disposition. En su clase WebClient, recuperaría ese encabezado para guardar el archivo según lo sugerido por su sitio AwesomeSite.

+0

No se supone que edite AwesomeSite.aspx. –

9

Usted tiene que mirar en la cabecera content-disposition, a través de:

string disposition = client.ResponseHeaders["content-disposition"]; 

un ejemplo típico sería:

"attachment; filename=IDontKnowHowToGetTheRealFileNameHere.txt" 
+0

No creo que se preocupe por el lado del servidor. –

+0

@Daniel - ¿quién dijo algo sobre el servidor? El * cliente * es responsable de * leer * este encabezado ... –

+0

Gracias por agregar que - No vi que el 'Cliente Web 'tuviera acceso a los encabezados de respuesta. –

23

Aquí está el código completo requerido, asumiendo content-disposition el servidor ha aplicado encabezado:

using (WebClient client = new WebClient()) 
{ 
    using (Stream rawStream = client.OpenRead(url)) 
    { 
     string fileName = string.Empty; 
     string contentDisposition = client.ResponseHeaders["content-disposition"]; 
     if (!string.IsNullOrEmpty(contentDisposition)) 
     { 
      string lookFor = "filename="; 
      int index = contentDisposition.IndexOf(lookFor, StringComparison.CurrentCultureIgnoreCase); 
      if (index >= 0) 
       fileName = contentDisposition.Substring(index + lookFor.Length); 
     } 
     if (fileName.Length > 0) 
     { 
      using (StreamReader reader = new StreamReader(rawStream)) 
      { 
       File.WriteAllText(Server.MapPath(fileName), reader.ReadToEnd()); 
       reader.Close(); 
      } 
     } 
     rawStream.Close(); 
    } 
} 

Si el servidor no configuró este encabezado, tr y depuración y vea qué ResponseHeaders tiene, uno de ellos probablemente contenga el nombre que desea. Si el navegador mostrará el nombre, tiene que venir de alguna parte .. :)

+1

Si no me equivoco, olvidó eliminar las comillas que rodean el nombre del archivo. es decir, '" archivo.txt "' en lugar de 'archivo.txt'. – yellowblood

+0

Por lo que yo sé, no se debe incluir comillas, pero eliminarlas es tan fácil como 'fileName = contentDisposition.Substring (index + lookFor.Length) .Replace (" \ "", ""); ':) –

+1

Quizás fue solo el servidor que utilicé. Otra nota: esto funciona solo para archivos de texto, en la mayoría de los casos creo que es mejor escribir bytes en lugar de texto. Simplemente puede reemplazar el 'StreamReader' por' MemoryStream', y luego use 'rawStream.CopyTo (memStream)' y 'File.WriteAllBytes (path, memStream.ToArray())' (.NET 4 solamente). – yellowblood

25

que tenían el mismo problema, y ​​me encontré con esta clase: System.Net.Mime.ContentDisposition.

using (WebClient client = new WebClient()){ 
    client.OpenRead(url); 

    string header_contentDisposition = client.ResponseHeaders["content-disposition"]; 
    string filename = new ContentDisposition(header_contentDisposition).FileName; 

    ...do stuff... 
} 

La documentación de la clase sugiere que está diseñada para archivos adjuntos de correo electrónico, pero funciona bien en el servidor que utiliza para probar, y es muy agradable para evitar el análisis.

+0

¿Cómo puedo obtener la codificación de nombre de archivo? Si uso HttpWebResponse, puedo usar StreamReader sr = new StreamReader (s, Encoding.GetEncoding (response.CharacterSet)); –

+0

@NimeCloud Estoy bastante seguro de que WebClient intenta leer el encabezado y establecer la codificación automáticamente. Si no está en el encabezado o está dañado, debería poder configurarlo con WebClient.Encoding. – wst

2

Lo consigo con el código de wst.

Aquí está el código completo para descargar el archivo url en c: \ Temp

public static void DownloadFile(string url) 
    { 
     using (WebClient client = new WebClient()) 
     { 
      client.OpenRead(url); 

      string header_contentDisposition = client.ResponseHeaders["content-disposition"]; 
      string filename = new ContentDisposition(header_contentDisposition).FileName; 


      //Start the download and copy the file to the destinationFolder 
      client.DownloadFile(new Uri(url), @"c:\temp\" + filename); 
     } 

    } 
Cuestiones relacionadas