c# - example - Descargar/Transmitir archivo desde la URL-asp.net
streamreader to file c# (5)
Necesito transmitir un archivo que dará como resultado guardarlo en el navegador. El problema es que el directorio donde se encuentra el archivo está prácticamente mapeado, por lo que no puedo usar Server.MapPath para determinar su ubicación real. El directorio no está en la misma ubicación (o incluso servidor físico en los cuadros activos) que el sitio web.
Me gustaría algo como lo siguiente, pero eso me permitirá pasar una URL web, y no una ruta de archivo de servidor.
Puede que tenga que terminar construyendo mi ruta de archivo desde una ruta base de configuración, y luego anexar en el resto de la ruta, pero espero poder hacerlo de esta manera.
var filePath = Server.MapPath(DOCUMENT_PATH);
if (!File.Exists(filePath))
return;
var fileInfo = new System.IO.FileInfo(filePath);
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", String.Format("attachment;filename=/"{0}/"", filePath));
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
Response.WriteFile(filePath);
Response.End();
2 años después, utilicé la respuesta de Dallas, pero tuve que cambiar la HttpWebRequest
a FileWebRequest
porque estaba enlazando a archivos directos. No estoy seguro de si este es el caso en todas partes, pero pensé que lo agregaría. Además, quité
var resp = Http.Current.Resonse
y simplemente usé Http.Current.Response
en el lugar donde se hizo referencia a resp
.
Descarga url a bytes y convierte bytes en stream:
using (var client = new WebClient())
{
var content = client.DownloadData(url);
using (var stream = new MemoryStream(content))
{
...
}
}
Hago esto bastante y pensé que podría agregar una respuesta más simple. Lo configuré como una clase simple aquí, pero lo ejecuto todas las noches para recopilar datos financieros de las empresas que estoy siguiendo.
class WebPage
{
public static string Get(string uri)
{
string results = "N/A";
try
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
results = sr.ReadToEnd();
sr.Close();
}
catch (Exception ex)
{
results = ex.Message;
}
return results;
}
}
En este caso, paso una url y devuelve la página como HTML. Si quieres hacer algo diferente con la transmisión, puedes cambiar esto fácilmente.
Lo usas así:
string page = WebPage.Get("http://finance.yahoo.com/q?s=yhoo");
Podría intentar usar la clase DirectoryEntry con el prefijo de ruta IIS:
using(DirectoryEntry de = new DirectoryEntry("IIS://Localhost/w3svc/1/root" + DOCUMENT_PATH))
{
filePath = de.Properties["Path"].Value;
}
if (!File.Exists(filePath))
return;
var fileInfo = new System.IO.FileInfo(filePath);
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", String.Format("attachment;filename=/"{0}/"", filePath));
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
Response.WriteFile(filePath);
Response.End();
Puede usar HttpWebRequest para obtener el archivo y transmitirlo nuevamente al cliente. Esto le permite obtener el archivo con una url. Un ejemplo de esto que encontré (pero no puedo recordar dónde dar crédito) es
//Create a stream for the file
Stream stream = null;
//This controls how many bytes to read at a time and send to the client
int bytesToRead = 10000;
// Buffer to read bytes in chunk size specified above
byte[] buffer = new Byte[bytesToRead];
// The number of bytes read
try
{
//Create a WebRequest to get the file
HttpWebRequest fileReq = (HttpWebRequest) HttpWebRequest.Create(url);
//Create a response for this request
HttpWebResponse fileResp = (HttpWebResponse) fileReq.GetResponse();
if (fileReq.ContentLength > 0)
fileResp.ContentLength = fileReq.ContentLength;
//Get the Stream returned from the response
stream = fileResp.GetResponseStream();
// prepare the response to the client. resp is the client Response
var resp = HttpContext.Current.Response;
//Indicate the type of data being sent
resp.ContentType = "application/octet-stream";
//Name the file
resp.AddHeader("Content-Disposition", "attachment; filename=/"" + fileName + "/"");
resp.AddHeader("Content-Length", fileResp.ContentLength.ToString());
int length;
do
{
// Verify that the client is connected.
if (resp.IsClientConnected)
{
// Read data into the buffer.
length = stream.Read(buffer, 0, bytesToRead);
// and write it out to the response''s output stream
resp.OutputStream.Write(buffer, 0, length);
// Flush the data
resp.Flush();
//Clear the buffer
buffer = new Byte[bytesToRead];
}
else
{
// cancel the download if client has disconnected
length = -1;
}
} while (length > 0); //Repeat until no data is read
}
finally
{
if (stream != null)
{
//Close the input stream
stream.Close();
}
}