C#:在 Web 服务返回的 byte[] 的新选项卡中显示 PDF

C#: Display PDF in a new tab from byte[] returned by Web Service

当用户单击图标 link 时,我的应用程序试图显示存储在数据库中的 PDF。

单击 link 时,将触发对 Web 服务的 Ajax 调用,该调用使用 ID 检索 byte[] 数组中的 PDF 数据。

html 组件:

    <a href="#" onclick="getSPOD(<%=TransportationDocument != null ? TransportationDocument.BusinessID.ToString() : String.Empty %>);return false;">
        <img alt="SPOD" src="images/icons/adobe_acrobat_icon.png">
    </a>

Ajax 调用:

function getSPOD(id) {
    $.ajax({
        type: "GET",
        url: `Services/MyService.asmx/RetrieveSPODData?id='${id}'`,
        contentType: 'application/json; charset=utf-8',
        success: function (data) {
            console.log(data);
        },
        error: function (textStatus, errorThrown) {
            console.log(textStatus);
            console.log(errorThrown);
        }
    });
}

网络服务方式:

[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
[WebMethod]
public HttpResponse RetrieveSPODData(string id)
{
    string query = @"Select * from dcmnts 
                         where BUSNSS_ID = :BUSNSS_ID";
    DataTable dataTable = new DataTable();
    OracleCommand command = null;
    OracleDataAdapter adapter = null;

    string ConnString = ConfigurationManager.ConnectionStrings["DbConnEnc"].ToString();

    byte[] data = null;
    using (OracleConnection connection = new OracleConnection(BaseEncryptor.DecryptString(ConnString)))
    {
        try
        {
            if (connection.State != ConnectionState.Open)
                connection.Open();
            command = new OracleCommand(query, connection);
            command.Parameters.Add(new OracleParameter("BUSNSS_ID", id));
            adapter = new OracleDataAdapter(command);

            adapter.Fill(dataTable);
            foreach (DataRow row in dataTable.AsEnumerable())
            {
                data = row.Field<byte[]>("SUMMARY_SPOD");
            }
            HttpContext.Current.Response.ClearHeaders();
            HttpContext.Current.Response.AddHeader("Content-Disposition", "inline;filename=file.pdf");
            HttpContext.Current.Response.ContentType = "application/pdf";
            HttpContext.Current.Response.BinaryWrite(data);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();

            return HttpContext.Current.Response;
        }
        finally
        {
            if (adapter != null) { adapter.Dispose(); adapter = null; }
            if (command != null) { command.Dispose(); command = null; }
        }
    }
}

语法方面,没有问题。但是,我不知道如何从那里显示 pdf。通过使用 HttpContext.Current.Response 方法,如果我 运行 Web 服务直接从 visual studio,我可以在新选项卡中打开 PDF。但是,如果我通过已实现的 Web 界面执行此操作,则什么也没有发生。因此,虽然我可能需要 return HttpContext.Current.Response,但我尝试记录它以查看数据中的内容,但我收到了无法读取的数据。

我应该如何显示来自网络服务的 byte[] 的 PDF?我的 Web 服务需要做什么才能提供生成的文件?

方法二:Return字节[]数据到ajax调用并使用如下:

var file = new Blob([data.d], { type: 'application/pdf' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL);

这样一来,PDF文件就好像损坏了一样无法正常打开

AJAX 不需要:

    <a href="Services/ProofOfDeliveryData.asmx/RetrieveSPODData?id=<%=TransportationDocument != null ? TransportationDocument.BusinessID.ToString() : String.Empty %>" Target="_blank">
        <img alt="SPOD" src="images/icons/adobe_acrobat_icon.png">
    </a>

只需要 link 就可以直接访问 Web 服务,而且效果很好。