在我的aspx页面上,我有一个动态创建的菜单链接到存储在Oracle数据库中的文档。
当用户点击菜单中的链接时,它会调用一个JScript函数,该函数在代码隐藏页面中调用WebMethod修饰的vb.net过程。此函数传递元素ID,它用于查询Oracle数据库并返回相应的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 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代码
function GetDocument(src) {
PageMethods.wbmGetDocument(src);
}
VB.net模块
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代码
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)
答案 0 :(得分:2)
您无法执行此操作的原因是因为您现在处于XML HTTP请求(更好地称为AJAX)的上下文中,并且您无法将二进制数据直接写入响应,除非您使用hack或XMLHttpRequest2中的新功能记录here。
如果您不想诉诸黑客或冒险在某些浏览器中没有得到广泛支持,则可以选择简单地从Javascript开始 - 打开一个新窗口,其中文档ID作为url中的参数传递。类似的东西:
function GetDocument(src) {
window.open('FileHandler.ashx?docId='+src);
}
然后在您现在正在进行流式传输PDF。
FileHandler.ashx可以是一个Http Handler,或者如果你想保持简单,那就把它变成一个普通的aspx
页面,从Request.QueryString中获取id并传输PDF。