如何HttpContext.Current.Response.Binarywrite工作? [英] How does HttpContext.Current.Response.Binarywrite work?

查看:1057
本文介绍了如何HttpContext.Current.Response.Binarywrite工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我说,如果我做这个过于复杂,请,请提供有关如何简化建议开始!我试图创造一些逻辑,可以让用户在屏幕上输出的内容保存到一个PDF文件。内容包含多个highcharts图形,所以我需要的HTML被完全渲染页面,所以我可以抢SVG信息传递到PDF文件。由于页面已被完全呈现,我知道只有这样才能通过呈现的HTML返回到服务器通过Web服务。 Web服务是调用其中的PDF功能位于一个cs文件。我可以在PDF功能的设置到底在cs文件一个破发点,并且它打它。问题是,它返回200 OK parsererror语法错误:意外标记%的错误。

现在,我创造我的C#codebehind一个虚拟的HTML字符串,并呼吁从codebehind的cs文件,并创建没有问题在所有的PDF文件。所以我的问题是,为什么会在班级工作时,正在从codebehind调用,而不是从Web服务?我能想到的唯一的事情,是它有事情做了回发?我的code是如下:

的JavaScript调用该网站Service..I可以通过Web服务和一流的功能步骤一路被调用,他们正在做它到最后,但它返回到错误的功能与200 OK parsererror语法错误:意外的令牌%

 函数checkSplash(){
    timesChecked ++;
    如果(loadImages方式> = document.getElementsByName('IMG')||长* timesChecked&checkInterval GT = maxLoadTime){
        clearInterval(intervalID);        如果(的document.getElementById(exportDiv)!= NULL){
            VAR MYDATA = {
                SRC:的document.getElementById(export_pdf)的innerHTML
            }            $阿贾克斯({
                类型:后,
                的contentType:应用/ JSON的;字符集= UTF-8,
                网址:../WebServices/print.asmx/export
                数据:JSON.stringify(MYDATA)
                数据类型:JSON
                成功:函数(响应){
                    警报(这里);
                    location.reload(真);
                },
                错误:功能(XHR,textStatus,errorThrown){
                    警报(xhr.status +''+ xhr.statusText +''+ textStatus +''+ errorThrown);
                }
            })
        }
    }
}

Web服务调用...这个功能是相同的测试功能,我在codebehind创建。在codebehind测试功能的工作原理,并创建一个没有问题的PDF文档。但是,当这会从JavaScript调用,则返回错误

 使用DMC.Classes;
使用系统;
使用System.Collections.Generic;
使用System.Data.SqlClient的;
使用的System.Web;
使用System.Web.Services;
使用System.Web.UI程序;
使用System.Web.UI.WebControls;命名空间DMC.WebServices
{
    [WebService的空间(namespace =htt​​p://tempuri.org/)]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)
    [System.ComponentModel.ToolboxItem(假)]
    [System.Web.Script.Services.ScriptService]    公共类印刷:System.Web.Services.WebService
    {
        [的WebMethod]
        公共BOOL出口(字符串SRC)
        {
            字符串文件名= NULL;
            出口DMC =新的出口();            文件名=行为统计YTD;            dmc.exportPDF(文件名,人像,SRC);            返回true;
        }
    }
}

最后,所用的.cs方法:

 使用iTextSharp.text;
使用iTextSharp.text.html.simpleparser;
使用iTextSharp.text.pdf;
使用NReco.PdfGenerator;
使用System.Configuration;
使用System.Data这;
使用System.Data.SqlClient的;
使用System.IO;
使用System.Text;
使用的System.Web;
使用System.Web.UI程序;
使用System.Web.UI.HtmlControls;
使用System.Web.UI.WebControls;命名空间DMC.Classes
{
    公共类出口
    {
        公共无效exportPDF(字符串文件名,字符串方向,串HTML)
        {
            HtmlToPdfConverter PDF =新HtmlToPdfConverter();            HTML = html.Replace(\\ n,);
            HTML = html.Replace(\\ t的,);
            HTML = html.Replace(\\ r,);
            的HTML = html.Replace(\\,');            开关(方向)
            {
                案画像:
                    pdf.Orientation = PageOrientation.Portrait;
                    打破;
                案风景:
                    pdf.Orientation = PageOrientation.Landscape;
                    打破;
                默认:
                    pdf.Orientation = PageOrientation.Default;
                    打破;
            }            pdf.Margins.Top = 25;
            pdf.PageFooterHtml = createPDFFooter();            VAR pdfBytes = pdf.GeneratePdf(createPDFScript()+ HTML +< /身体GT;< / HTML>中);            HttpContext.Current.Response.ContentType =应用程序/ PDF
            HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
            HttpContext.Current.Response.AddHeader(内容处置,附件;文件名=+文件名+.PDF);
            HttpContext.Current.Response.BinaryWrite(pdfBytes);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }        私人字符串createPDFScript()
        {
            回归< HTML>< HEAD><花柱> TD,TH {线高度:20像素;} TR {分页符-内部:避免}< /风格与GT;<脚本>功能SUBST(){VAR瓦尔= {};变种X = document.location.search.su​​bstring(1).split('和;');对(变种i的x)的{风险Z = X [i]于.split(=,2 );瓦尔[Z [0]] = UNESCAPE(Z [1]);}+
        变种X = ['frompage','topage,网页,网页,节,款,subsubsection'];为(VAR我在X){VAR Y = document.getElementsByClassName(X [一世]); +
        对于(VAR J = 0; J< y.length ++ j)条Y [J] .textContent =瓦尔[X [I]];}}< / SCRIPT>< /头><身体的onload = \\SUBST()\\>中;
        }        私人字符串createPDFFooter()
        {
            回归< D​​IV><表样式=FONT-FAMILY:宋体; FONT-SIZE:9px;宽度:100%>< TR>< TD风格=文本对齐:左'>研究部| RR:MM:JPG< / TD>< TD风格=文本对齐:右'&LT的;>页面<跨度类= \\页\\>< / SPAN&GT跨度类= \\ topage \\>< / SPAN>< / TD>< / DIV>中;
        }
    }
}


解决方案

引用的HttpContext 从PDF创建者类中实在不是一个好主意,因为它违反的主要关注的分离的。更好的办法是你的 exportPDF 方法返回 pdfBytes 阵列,并有主叫方可以适当地处理它。

所以你的 exportPDF 方法结束了寻找这样的:

 字节公众[] exportPDF(字符串文件名,字符串方向,串HTML)
{
    //等等。    VAR pdfBytes = pdf.GeneratePdf(createPDFScript()+ HTML +< /身体GT;< / HTML>中);    返回pdfBytes;
}

和您的Web方法是这样的:

  [的WebMethod]
公众的byte []出口(字符串SRC)
{
    字符串文件名= NULL;
    出口DMC =新的出口();    文件名=行为统计YTD;    Context.Response.ContentType =应用程序/ PDF
    Context.Response.ContentEncoding = System.Text.Encoding.UTF8;
    Context.Response.AddHeader(内容处置,附件;文件名=+文件名+.PDF);    返回dmc.exportPDF(文件名,人像,SRC);
}

有一件事情是我不明白的是你计划如何处理JavaScript的响应。这是什么是返回PDF文件的内容。什么是你的JavaScript将与该怎么办?

Let me start by saying if I'm making this overly complicated, please, please offer suggestions on how to simplify!! I'm trying to create some logic that will let users export the contents on the screen to a PDF file. The contents contains multiple highcharts graphs, so I need for the html to be rendered completely to the page so I can grab the svg information to pass into the PDF file. Since the page has been rendered completely, the only way I know to pass the rendered html back to the server is through Web Services. Web Services is calling a .cs file where the PDF functionality is located. I can set a break point in the .cs file at the end of the pdf function, and it is hitting it. The problem is, it's returning an error of "200 OK parsererror SyntaxError: Unexpected token %".

Now, I create a dummy html string in my C# codebehind and call the .cs file from the codebehind, and it creates a PDF file with no issues at all. So my question is, why would the class work when being called from a codebehind, but not from Web Services? The only thing I can think of, is that it has something to do with a postback? My code is below:

JavaScript that is calling the Web Service..I can step all the way through the web service and class functions being called, they are making it to the end, but it's returning to the error function with 200 OK parsererror SyntaxError: Unexpected token %

function checkSplash() {
    timesChecked++;
    if (loadImages >= document.getElementsByName('img').length || timesChecked * checkInterval >= maxLoadTime) {
        clearInterval(intervalID);

        if (document.getElementById("exportDiv") != null) {
            var mydata = {
                src: document.getElementById("export_pdf").innerHTML
            }

            $.ajax({
                type: "post",
                contentType: "application/json; charset=UTF-8",
                url: "../WebServices/print.asmx/export",
                data: JSON.stringify(mydata),
                dataType: "json",
                success: function (response) {
                    alert("here");
                    location.reload(true);
                },
                error: function (xhr, textStatus, errorThrown) {
                    alert(xhr.status + ' ' + xhr.statusText + ' ' + textStatus + ' ' + errorThrown);
                }
            })
        }
    }
}

Web Service being called...this function is identical the a test function I created in the codebehind. The codebehind test function works and creates the PDF document with no issues. But when this gets called from the javascript, it returns the error

using DMC.Classes;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace DMC.WebServices
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]

    public class print : System.Web.Services.WebService
    {
        [WebMethod]
        public bool export(string src)
        {
            string fileName = null;
            export dmc = new export();

            fileName = " Behavior Statistics YTD ";

            dmc.exportPDF(fileName, "Portrait", src);

            return true;
        }
    }
}

Finally, the .cs methods being used:

using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;
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();

            html = html.Replace("\n", "");
            html = html.Replace("\t", "");
            html = html.Replace("\r", "");
            html = html.Replace("\"", "'");

            switch (Orientation)
            {
                case "Portrait":
                    pdf.Orientation = PageOrientation.Portrait;
                    break;
                case "Landscape":
                    pdf.Orientation = PageOrientation.Landscape;
                    break;
                default:
                    pdf.Orientation = PageOrientation.Default;
                    break;
            }

            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>";
        }
    }
}

解决方案

Referencing HttpContext from within the PDF creator class really is not a good idea as it violates the principal of Separation of Concerns. A better way would be for your exportPDF method to return the pdfBytes array and have the caller can handle it appropriately.

So your exportPDF method ends up looking like this:

public byte[] exportPDF(string fileName, string Orientation, string html)
{
    // etc.

    var pdfBytes = pdf.GeneratePdf(createPDFScript() + html + "</body></html>");

    return pdfBytes;
}

And your web method looks like this:

[WebMethod]
public byte[] export(string src)
{
    string fileName = null;
    export dmc = new export();

    fileName = " Behavior Statistics YTD ";

    Context.Response.ContentType = "application/pdf";
    Context.Response.ContentEncoding =  System.Text.Encoding.UTF8;
    Context.Response.AddHeader("content-disposition", "attachment; filename=" + fileName + ".pdf");

    return dmc.exportPDF(fileName, "Portrait", src);
}

One thing that isn't clear to me is how you are planning to handle the response in the JavaScript. What this returns is the PDF file content. What is your JavaScript going to do with that?

这篇关于如何HttpContext.Current.Response.Binarywrite工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆