将文件发送到browser / response.write替代

时间:2014-04-23 18:38:46

标签: javascript asp.net vb.net vb.net-2010

在我的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

FIX

正如@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)

1 个答案:

答案 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。