使用web服务创建PDF仅在直接调用该服务时有效

本文关键字:服务 调用 有效 web 创建 PDF 使用 | 更新日期: 2023-09-27 18:01:46

我是一个web服务的新手,所以这个问题难倒了我。我已经创建了一个web服务,它将(最终)接受html块并从中创建pdf文件。为了简单起见,目前我没有向服务传递任何参数;我只是创建了一个pdf文档,里面有"hello world"。在调试模式下,当我直接调用服务(即从那个asmx页面开始调试)时,我可以调用exportPDF()方法,结果非常完美——它创建了我所希望的pdf。

问题是当我从javascript调用web服务时,什么都没有发生。我在服务内部设置了一个断点,所以我知道它正在被调用,正如我提到的,没有参数被传递进来,所以我不明白为什么它在直接调用时工作,但当它从javascript调用调用时却不工作。

我的javascript和webservice代码如下…任何帮助将是非常,非常感激!!

Javascript:

    function getPDF(elem) {
    var param = { html: elem.innerHTML };
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=UTF-8",
        url: "../WebServices/exporting.asmx/exportPDF",
        data: "{ }",
        dataType: "json",
        success: function (response) {
        }
    })
}
虽然WebService: <<p> /strong>
using DMC.Classes;
using NReco.PdfGenerator;
using System;
using System.IO;
using System.Web;
using System.Web.Services;
using System.Web.UI;
namespace DMC.WebServices
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class exporting : System.Web.Services.WebService
    {
        [WebMethod]
        public void exportPDF()
        {
            WriteDocument("htmlToPDF.pdf", "application/pdf", ConvertHtmlToPDF());
        }
        public byte[] ConvertHtmlToPDF()
        {
            HtmlToPdfConverter nRecohtmltoPdfObj = new HtmlToPdfConverter();
            nRecohtmltoPdfObj.Orientation = PageOrientation.Portrait;
            nRecohtmltoPdfObj.PageFooterHtml = CreatePDFFooter();
            nRecohtmltoPdfObj.CustomWkHtmlArgs = "--margin-top 35 --header-spacing 0 --margin-left 0 --margin-right 0";
            return nRecohtmltoPdfObj.GeneratePdf(CreatePDFScript() + "Hello world" + "</body></html>");
        }
        public string CreatePDFScript()
        {
            return "<html><head><style>td,th{line-height:20px;} tr { page-break-inside: avoid }</style><script>function subst() {var vars={};var x=document.location.search.substring(1).split('&');for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}" +
            "var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];for(var i in x) {var y = document.getElementsByClassName(x[i]);" +
            "for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];}}</script></head><body onload='"subst()'">";
        }
        public string CreatePDFFooter()
        {
            return "<div style='text-align:center;font-family:Tahoma; font-size:9px;'>Page <span class='"page'"></span> of <span class='"topage'"></span></div>";
        }
        public void WriteDocument(string fileName, string contentType, byte[] content)
        {
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ContentType = contentType;
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
            HttpContext.Current.Response.CacheControl = "No-cache";
            HttpContext.Current.Response.BinaryWrite(content);
            HttpContext.Current.Response.Flush();
        }
    }
}

使用web服务创建PDF仅在直接调用该服务时有效

谢谢你的回复,Mason!我一直在研究这个问题,并找到了一个解决方案;虽然我承认它并不完美,但我不认为它太糟糕。从我读过的所有不同的材料中,我开始感觉到web服务更像是传递数据的"中间人",而不是真正用来处理发布PDF文档之类的功能。它可以让您在调试和直接调用它时避开它,但仅此而已。

所以我没有使用web服务,而是创建了一个类对象。我还在html中创建了一个隐藏字段。当有人点击"导出到PDF"按钮时,该字段通过JavaScript填充所需的div.innerHtml内容。在回发时,我的代码隐藏检查隐藏字段是否为空,如果不是,则调用exportPDF函数,该函数反过来实例化创建/下载PDF的类对象。这样做的最大的陷阱,有些人可能认为这是一个很大的陷阱,是在代码中读取有html标记的字段时,你必须关闭对网页的验证,这显然为恶意攻击打开了你的代码。

下面是我的代码的亮点:

网络。配置

添加requestValidationMode = "2.0"到web。配置文件

<system.web>
  <httpRuntime 
    requestValidationMode="2.0" 
    targetFramework="4.5" 
  />
</system.web>

。aspx页面:

设置ValidateRequest="false"

<%@ Page Title="Referrals" Language="C#" MasterPageFile="~/Behavior/Behavior.master" AutoEventWireup="true" CodeBehind="Referrals.aspx.cs"
Inherits="DMC.Behavior.Referrals" ClientIDMode="Static" EnableEventValidation="false" ValidateRequest="false" %>
.
.
.
    <asp:LinkButton ID="LinkButton2" runat="server" OnClientClick="createPDF();">
        <img src='../Images/icons/pdf.png'>PDF</asp:LinkButton>
.
.
.
<div id="export_pdf" class="pdfWidth_Portrait pdfSection" style="margin-top: 10px;" runat="server">
    <div class="alert-info text-center" style="margin: 0; padding: 0;">
        <table class="table table-condensed" style="margin-top: 0; padding: 30px; width: 100%;">
    .
    .
    .   
        </table>
    </div>
</div>
.
.
.
<asp:HiddenField ID="pdfData" runat="server" />
.
.
.
<script type="text/javascript">
    function createPDF() {
        document.getElementById("pdfData").value = document.getElementById("export_pdf").innerHTML;
    }
</script>

代码:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //Set the hidden pdf field to null initially
            pdfData.Value = "";
        }
        //If this field is no longer null, it means somebody is wanting to export into PDF
        if (pdfData.Value != "")
        {
            exportPDF();
        }
    }
    public void exportPDF()
    {
        string fileName = null;
        export dmc = new export();
        fileName = lblLocation.Text + " Behavior Statistics YTD " + lblDate.Text;
        dmc.exportPDF(fileName, "Portrait", pdfData.Value);
        //PDF downloaded, reset value to ""
        pdfData.Value = "";
    }
出口类

using NReco.PdfGenerator;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace DMC.Classes
{
    public class export 
    {
        public void exportPDF(string fileName, string Orientation, string html)
        {
            HtmlToPdfConverter pdf = new HtmlToPdfConverter();
            //Remove these control characters, they interfere with the formatting of the pdf document
            html = html.Replace("'n", "");
            html = html.Replace("'t", "");
            html = html.Replace("'r", "");
            switch (Orientation)
            {
                case "Portrait":
                    pdf.Orientation = PageOrientation.Portrait;
                    break;
                case "Landscape":
                    pdf.Orientation = PageOrientation.Landscape;
                    break;
                default:
                    pdf.Orientation = PageOrientation.Default;
                    break;
            }
            //In case needed for future
            //pdf.CustomWkHtmlArgs = "--margin-top 35 --header-spacing 0 --margin-left 0 --margin-right 0";
            pdf.Margins.Top = 25;
            pdf.PageFooterHtml = createPDFFooter();
            var pdfBytes = pdf.GeneratePdf(createPDFScript() + html + "</body></html>");
            HttpContext.Current.Response.ContentType = "application/pdf";
            HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + fileName + ".pdf");
            HttpContext.Current.Response.BinaryWrite(pdfBytes);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }
        private string createPDFScript()
        {
            return "<html><head><style>td,th{line-height:20px;} tr { page-break-inside: avoid }</style><script>function subst() {var vars={};var x=document.location.search.substring(1).split('&');for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}" +
        "var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];for(var i in x) {var y = document.getElementsByClassName(x[i]);" +
        "for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];}}</script></head><body onload='"subst()'">";
        }
        private string createPDFFooter()
        {
            return "<div><table style='font-family:Tahoma; font-size:9px; width:100%'><tr><td style='text-align:left'>Research Dept|RR:mm:jpg</td><td style='text-align:right'>Page <span class='"page'"></span> of <span class='"topage'"></span></td></div>";
        }
    }
}