J’ai besoin de diffuser un fichier qui entraînera l’enregistrement sous forme d’invite dans le navigateur. Le problème est que le répertoire dans lequel se trouve le fichier est virtuellement mappé. Je ne peux donc pas utiliser Server.MapPath pour déterminer son emplacement réel. Le répertoire ne se trouve pas au même endroit (ou même sur le serveur physique des boîtes live) que le site Web.
Je voudrais quelque chose comme ce qui suit, mais cela me permettra de passer une URL Web, et non un chemin de fichier de serveur.
Je devrais peut-être finir par construire mon chemin de fichier à partir d’un chemin de base de configuration, puis append le rest du chemin, mais j’espère pouvoir le faire de cette façon.
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", Ssortingng.Format("attachment;filename=\"{0}\"", filePath)); Response.AddHeader("Content-Length", fileInfo.Length.ToSsortingng()); Response.WriteFile(filePath); Response.End();
Vous pouvez utiliser HttpWebRequest pour obtenir le fichier et le retransmettre au client. Cela vous permet d’obtenir le fichier avec une URL. Un exemple de cela que j’ai trouvé (mais je ne me souviens pas où donner du crédit) est
//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.ToSsortingng()); 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(); } }
Je le fais un peu et j’ai pensé pouvoir append une réponse plus simple. Je l’ai configuré comme une classe simple ici, mais je l’exécute tous les soirs pour collecter des données financières sur les sociétés que je suis en train de suivre.
class WebPage { public static ssortingng Get(ssortingng uri) { ssortingng 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; } }
Dans ce cas, je passe une url et renvoie la page au format HTML. Si vous voulez faire quelque chose de différent avec le stream, vous pouvez facilement le changer.
Vous l’utilisez comme ceci:
ssortingng page = WebPage.Get("http://finance.yahoo.com/q?s=yhoo");
Téléchargez l’URL en octets et convertissez les octets en stream:
using (var client = new WebClient()) { var content = client.DownloadData(url); using (var stream = new MemoryStream(content)) { ... } }
Deux ans plus tard, j’ai utilisé la réponse de Dallas, mais j’ai dû remplacer HttpWebRequest
par FileWebRequest
car je me connectais à des fichiers directs. Je ne suis pas sûr que ce soit le cas partout, mais je pensais l’append. Aussi, j’ai enlevé
var resp = Http.Current.Resonse
et juste utilisé Http.Current.Response
en place partout où resp
était référencé.
Vous pouvez essayer d’utiliser la classe DirectoryEntry avec le préfixe de chemin 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", Ssortingng.Format("attachment;filename=\"{0}\"", filePath)); Response.AddHeader("Content-Length", fileInfo.Length.ToSsortingng()); Response.WriteFile(filePath); Response.End();