2009-02-22 5 views
3

J'ai un objet Stream qui est avec le contenu d'un fichier XSD je en tant que ressource incorporée à un projet sur lequel je travaille comme ceci:Meilleur moyen d'enregistrer un flux dans un fichier dans asp.net 3.5?

using (Stream xsdStream = assembly.GetManifestResourceStream(xsdFile)) 
{ 
    // Save the contents of the xsdStream here... 
} 

Dans ce en utilisant le bloc, je voudrais demander à l' utilisateur avec une boîte de dialogue Enregistrer le fichier sur le Web où ils peuvent choisir d'enregistrer ce fichier XSD contenu dans le flux.

Quelle est la meilleure façon d'y parvenir? Je suis complètement perdu et ne peux pas sembler à Google les bons termes pour obtenir une réponse pertinente.

Merci!

Répondre

2

Si vous n'utilisez pas AJAX, vous pouvez utiliser Response.WriteFile. Sinon j'utiliserais un MemoryStream. Voilà comment je l'ai fait here. Désolé, c'est dans VB.NET, je ne l'ai pas transcodé. Notez que cela vous permet également de télécharger un fichier sur le serveur Web, c'est-à-dire si votre fichier se trouve sur un serveur d'application sans accès public.

Imports System.Data 
Imports System.Data.SqlClient 
Imports System.Data.Sql 
Imports System.Net 
Imports System.IO 

Partial Class DownloadFile 
Inherits System.Web.UI.Page 

Protected Sub page_load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load 
Dim url As String = Request.QueryString("DownloadUrl") 
If url Is Nothing Or url.Length = 0 Then Exit Sub 

'Initialize the input stream 
Dim req As HttpWebRequest = WebRequest.Create(url) 
Dim resp As HttpWebResponse = req.GetResponse() 
Dim bufferSize As Integer = 1 

'Initialize the output stream 
Response.Clear() 
Response.AppendHeader("Content-Disposition:", "attachment; filename=download.zip") 
Response.AppendHeader("Content-Length", resp.ContentLength.ToString) 
Response.ContentType = "application/download" 

'Populate the output stream 
Dim ByteBuffer As Byte() = New Byte(bufferSize) {} 
Dim ms As MemoryStream = New MemoryStream(ByteBuffer, True) 
Dim rs As Stream = req.GetResponse.GetResponseStream() 
Dim bytes() As Byte = New Byte(bufferSize) {} 
While rs.Read(ByteBuffer, 0, ByteBuffer.Length) > 0 
Response.BinaryWrite(ms.ToArray()) 
Response.Flush() 
End While 

'Cleanup 
Response.End() 
ms.Close() 
ms.Dispose() 
rs.Dispose() 
ByteBuffer = Nothing 
End Sub 
End Class 
0

Il me semble que vous devriez jeter un oeil au gestionnaire WebResource.axd.

Microsoft ont un excellent article sur le sujet.

Edit:

Il semble que tsilb battre ma réponse en une minute. Cependant, AssemblyResourceLoader (alias WebResource.axd) est déjà implémenté pour faire cela pour vous et pour le faire correctement, et n'oubliez pas que ce chiot supporte la mise en cache de sortie. Alors allez-y, utilisez plutôt cela et épargnez-vous le problème. ;)

1

Vous voulez mettre la disposition de contenu:

Response.AddHeader "Content-Disposition","attachment; filename=" & xsdFile 

Vous également définir le type de contenu text/plain et Content-Length à la taille du fichier. Ensuite, vous écrivez le contenu du fichier.

+0

Bien que cette réponse fournisse des informations précieuses, c'est-à-dire si Rob voulait lancer son propre flux, il ne répond pas à la question de savoir comment diffuser le fichier en premier lieu. Si Rob voulait aller dans cette direction, je pense que tsilb a une meilleure réponse. Cependant je pense toujours que mon chemin est beaucoup plus facile ...;) – JohannesH

1
private void DownloadEmbeddedResource( 
    string resourceName, Assembly resourceAssembly, string downloadFileName) 
{ 
    using (Stream stream = resourceAssembly.GetManifestResourceStream(resourceName)) 
    { 
    if (stream != null) 
    { 
     Response.Clear(); 
     string headerValue = string.Format("attachment; filename={0}", downloadFileName); 
     Response.AppendHeader("Content-Disposition:", headerValue); 
     Response.AppendHeader("Content-Length", stream.Length.ToString()); 
     Response.ContentType = "text/xml"; 

     var byteBuffer = new Byte[1]; 

     using (var memoryStream = new MemoryStream(byteBuffer, true)) 
     { 
     while (stream.Read(byteBuffer, 0, byteBuffer.Length) > 0) 
     { 
      Response.BinaryWrite(memoryStream.ToArray()); 
      Response.Flush(); 
     } 
     } 

     Response.End(); 
    } 
    } 
} 

J'ai fini par utiliser cette méthode ci-dessus. Merci de m'avoir aidé avec la syntaxe tsilb. JohannesH, j'aurais utilisé votre recommandation si la ressource ne provenait pas déjà d'un assemblage différent (désolé, j'aurais dû l'éclaircir dans ma question initiale). Le code ci-dessus fonctionne mais je rencontre un problème assez étrange ... Une fois la méthode terminée et le téléchargement terminé, la page ne semble toujours pas revenir à la vie et la souris est toujours en mode sablier comme toujours pense que le travail est fait. Une idée sur la façon de remédier à cela?

Merci encore pour votre aide!