在我的 aspx 页面上,我有一个动态创建的菜单,其中包含指向存储在 Oracle 数据库中的文档的链接。
当用户单击菜单中的链接时,它调用一个 JScript 函数,该函数在代码隐藏页面中调用 WebMethod 修饰的 vb.net 过程。此函数传递用于查询 Oracle 数据库的元素 ID,并返回相应的 blob 对象,即用户请求的文档。
当我测试它时,我将它连接到一个按钮,对所有内容进行硬编码,然后能够将文档返回到浏览器,并且没有任何问题。下面是我用来将 blob 对象返回给浏览器的内容。
Response.Clear()
Response.ClearContent()
Response.ClearHeaders()
Response.Buffer = True
Response.AddHeader("Content-Disposition", "attachment; filename=" + docname)
Response.ContentType = "application/pdf"
Response.BinaryWrite(bytes)
现在我已将代码移动到可调用方法中。我刚刚了解到我不能使用 Response 将我从数据库中提取的文件写入浏览器。或者,如果可以做到,我不知道该怎么做。下面是代码。
ASPX page.
<%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Site.Master" CodeBehind="FrmBookMain.aspx.vb" Inherits="ccc.com.FormsBook" %>
<%@ Register Assembly="Obout.Ajax.UI" Namespace="Obout.Ajax.UI.TreeView" TagPrefix="obout" %>
<%@ Register assembly="obout_Splitter2_Net" namespace="OboutInc.Splitter2" tagprefix="obspl" %>
<%@ Register assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" namespace="System.Web.UI" tagprefix="cc1" %>
<%@ Register assembly="obout_Interface" namespace="Obout.Interface" tagprefix="cc2" %>
<%@ Register assembly="obout_EasyMenu_Pro" namespace="OboutInc.EasyMenu_Pro" tagprefix="oem" %>
<%@ Register assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" namespace="System.Web.UI.HtmlControls" tagprefix="cc3" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<div style="width:900px; height:450px">
<obspl:Splitter ID="spl1" runat="server">
<leftpanel>
<content>
<asp:PlaceHolder ID="placeHolder1" EnableViewState="false" runat="server"></asp:PlaceHolder>
</content>
</leftpanel>
<RightPanel>
<Content>
<div class="tdText" style="width:400px;height:80%;padding-left:30px;padding-top:30px">
<h2>Document Repository</h2>
Choose a document from the left menu...
</div>
</Content>
</RightPanel>
</obspl:Splitter>
</div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"/>
<script type="text/javascript" src="../Java/Frm_JScript.js"/>
</asp:Content>
JavaScript Code
function GetDocument(src) {
PageMethods.wbmGetDocument(src);
}
VB.net Module
Module modGetDoc_Frm
<WebMethod()>
Public Sub wbmGetDocument(ByVal sID As String)
Dim dr As OracleDataReader = Get_DataReader(sSql_GetDocument(sID))
Dim blob As OracleBlob = dr.GetOracleBlob(1)
Dim bytes(blob.Length) As Byte : blob.Read(bytes, 0, blob.Length)
Dim doctype As String = dr(2).ToString()
Dim docname As String = dr(3).ToString()
*** Everything below won't work in module is there an alternative or what am I doing wrong***
Response.Clear()
Response.ClearContent()
Response.ClearHeaders()
Response.Buffer = True
Response.AddHeader("Content-Disposition", "attachment; filename=" + docname)
Response.ContentType = "application/pdf"
Response.BinaryWrite(bytes)
End Sub
End Module
修复
正如@Icarus 在下面所说,我添加了一个从 java 脚本调用它的 .ashx 页面,并允许它处理文件。这样做可以让您从代码隐藏访问响应流。 此链接帮助我更详细地了解 .ashx 页面 http://www.dotnetperls.com/ashx
JavaScript
function GetDocument(id) {
window.open('FrmDocHandler.ashx?ID=' + id);
}
.ashx code
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim sID As String = context.Request.QueryString("id")
Dim fileName As String
Dim fileType As String
Dim bytes() As Byte
bytes = Get_Blob(fileName, fileType, sSql_GetDocument(sID))
context.Response.Clear()
'clear the content of the browser
context.Response.ClearContent()
context.Response.ClearHeaders()
context.Response.Buffer = True
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName)
context.Response.ContentType = GetMIMEType(fileType)
context.Response.BinaryWrite(bytes)
最佳答案
你不能这样做的原因是因为你现在处于 XML HTTP 请求(更广为人知的 AJAX)的上下文中并且你不能将二进制数据直接写入响应,除非你使用 hack 或新的XMLHttpRequest2 中的功能已记录 here .
如果您不想诉诸 hack 或者冒着在某些浏览器中不受广泛支持的风险,一种替代方法是简单地 - 从 Javascript - 打开一个新窗口,并将文档 ID 作为参数传递到 url 中。像这样的东西:
function GetDocument(src) {
window.open('FileHandler.ashx?docId='+src);
}
然后像现在一样流式传输 PDF。
FileHandler.ashx 可以是一个 Http 处理程序,或者如果您想保持简单,可以将其设为普通的 aspx
页面,从 Request.QueryString 获取 id 并流式传输 PDF。
关于javascript - 将文件发送到浏览器/response.write 替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23252603/