Лучший способ сохранить поток в файл в asp.net 3.5? - PullRequest
3 голосов
/ 22 февраля 2009

У меня есть объект Stream, который заполняется содержимым файла XSD, который у меня есть как встроенный ресурс в проекте, над которым я работаю, вот так:

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

В рамках этого блока я хотел бы предложить пользователю диалоговое окно «Сохранить файл» в Интернете, где он может выбрать сохранение этого XSD-файла, содержащегося в потоке.

Каков наилучший способ сделать это? Я полностью растерялся и не могу представить Google правильные условия, чтобы получить соответствующий ответ.

Спасибо!

Ответы [ 4 ]

2 голосов
/ 22 февраля 2009

Если вы не используете AJAX, вы можете использовать Response.WriteFile. В противном случае я бы использовал MemoryStream. Вот как я это сделал здесь . Извините, это в VB.NET, я не транскодировал его. Обратите внимание, что это также позволяет загружать файл через веб-сервер, т. Е. Если ваш файл находится на сервере приложений без публичного доступа.

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
1 голос
/ 22 февраля 2009
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();
    }
  }
}

Я закончил тем, что использовал этот метод выше. Спасибо, что помогли мне с синтаксисом tsilb. JohannesH, я бы воспользовался вашей рекомендацией, если бы ресурс не был из другой сборки (извините, я должен был это прояснить в своем первоначальном вопросе).

Приведенный выше код работает, но я сталкиваюсь с довольно странной проблемой ... После того, как метод завершен и загрузка завершена, кажется, что страница так и не вернется к жизни, а мышь все еще находится в режиме песочных часов, как и думает работа ведется Есть идеи, как это исправить?

Еще раз спасибо за вашу помощь!

1 голос
/ 22 февраля 2009

Вы хотите установить расположение контента:

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

Вы также захотите установить для Content-Type значение text / plain, а Content-Length - для размера файла. Затем вы пишете содержимое файла.

0 голосов
/ 22 февраля 2009

Мне кажется, что вы должны взглянуть на обработчик WebResource.axd.

У Microsoft есть отличная статья на эту тему.

Edit:

Кажется, что Цильб избил мой ответ на минуту или около того. Тем не менее, AssemblyResourceLoader (aka. WebResource.axd) уже реализован, чтобы сделать это для вас и сделать это правильно, и не забывайте, что этот щенок поддерживает кэширование вывода. Так что используйте это вместо этого и избавьте себя от неприятностей. ;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...