3

我有一个 Stream 对象,其中填充了 XSD 文件的内容,作为我正在处理的项目中的嵌入式资源,如下所示:

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

在这个 using 块中,我想通过 Web 上的“保存文件”对话框提示用户,他们可以选择保存流中包含的这个 XSD 文件。

实现这一目标的最佳方法是什么?我完全迷失了,谷歌似乎无法用正确的术语来获得相关答案。

谢谢!

4

4 回答 4

2

如果您不使用 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
于 2009-02-22T05:28:56.770 回答
1

您将需要设置内容处置:

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

您还需要将 Content-Type 设置为 text/plain 并将 Content-Length 设置为文件的大小。然后你写文件的内容。

于 2009-02-22T05:30:14.053 回答
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();
    }
  }
}

我最终使用了上面的这种方法。感谢您在语法 tsilb 方面帮助我。JohannesH,如果资源不是来自不同的程序集,我会使用你的建议(对不起,我应该在我原来的问题中澄清这一点)。

上面的代码有效,但我遇到了一个相当奇怪的问题......方法完成并下载完成后,页面似乎仍然没有恢复活力,鼠标仍然处于沙漏模式,就像它仍然认为工作正在进行一样完毕。关于如何补救的任何想法?

再次感谢你的帮助!

于 2009-02-22T15:24:05.437 回答
0

在我看来,您应该看看 WebResource.axd 处理程序。

微软有一篇关于这个主题的优秀文章

编辑:

似乎 tsilb 比我的回答快了一分钟左右。但是,AssemblyResourceLoader(又名 WebResource.axd)已经实现了为您执行此操作并正确执行此操作,并且不要忘记此小狗支持输出缓存。因此,请继续使用它,以免麻烦。;)

于 2009-02-22T05:29:36.223 回答