MemoryStream到HttpResponseMessage

时间:2017-07-16 00:53:20

标签: javascript c# asp.net pdf

我在服务器上生成了一个Pdf,并且需要将其作为对我的Web客户端的响应返回,以便我得到一个“另存为”对话框。

生成pdf,并将其保存到内存流...然后返回到我的方法,该方法将返回HttpResponseMessage。

方法是:

[Route("GeneratePdf"), HttpPost]
public HttpResponseMessage GeneratePdf(PlateTemplateExtendedDto data)
{

    var doc = GeneratePdf(DataForThePdf);

    //using (var file = File.OpenWrite("c:\\temp\\test.pdf"))
    //    doc.CopyTo(file); // no need for manual stream copy and buffers

    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);

    byte[] buffer = new byte[0];
    //get buffer
    buffer = doc.GetBuffer();
    //content length for use in header
    var contentLength = buffer.Length;

    response.Headers.AcceptRanges.Add("bytes");
    response.StatusCode = HttpStatusCode.OK;
    response.Content = new StreamContent(doc);
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("render");
    response.Content.Headers.ContentDisposition.FileName = "yes.pdf";
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
    response.Content.Headers.ContentLength = doc.Length;

    return response;
}

但是,文档呈现为空白文件,虽然它有文件大小和我创建的文档的属性(pdf信息,如果文件属性可以,以及页面宽度和高度),文档显示空白。

如果我取消注释已注释掉的代码,要在本地保存,该文件是完美的。文件大小为228,889字节。但是,当我让它进入我的网页并保存时,它是405,153字节,文件名是'未定义'。

如果我断点,我会看到这些结果:

enter image description here

在前端脚本上,我按照以下方式处理下载的对象:

$.post("/api/PlateTemplate/GeneratePdf", data).done(function (data, status, headers) {

            // headers = headers();

            var filename = headers['x-filename'];
            var contentType = headers['content-type'];
            //Create a url to the blob
            var blob = new Blob([data], { type: contentType });
            var url = window.URL.createObjectURL(blob);
            var linkElement = document.createElement('a');
            linkElement.setAttribute('href', url);
            linkElement.setAttribute("download", filename);

            //Force a download
            var clickEvent = new MouseEvent("click", {
                "view": window,
                "bubbles": true,
                "cancelable": false
            });
            linkElement.dispatchEvent(clickEvent);
        });

我不确定文件被破坏的位置。我做错了什么?

编辑:使用建议的以下代码:

$.post("/api/PlateTemplate/GeneratePdf", data).done(function (data, status, headers) {
            alert(data.length);

            var xhr = new XMLHttpRequest();

            $("#pdfviewer").attr("src", URL.createObjectURL(new Blob([data], {
                type: "application/pdf"
            })))

.Net代码:

var doc = GeneratePdf(pdfParams);

            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);

            byte[] buffer = new byte[0];
            //get buffer
            buffer = doc.ToArray();
            //content length for use in header
            var contentLength = buffer.Length;

            response.Headers.AcceptRanges.Add("bytes");
            response.StatusCode = HttpStatusCode.OK;
            response.Content = new StreamContent(doc);
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("render");
            response.Content.Headers.ContentDisposition.FileName = "yes.pdf";
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
            response.Content.Headers.ContentLength = doc.Length;

            return response;

似乎我正在丢失数据。 在我从通话中获取数据后,警报是我的javascript中'data.length'的长度。 文件属性是原始的pdf文件信息。

enter image description here

文件从api发送,大小为227,564,如果保存,它与磁盘上的字节大小匹配。所以它看起来发送没问题。但是在javascript大小上,当我读入文件时,它是424946,当我这样做时:var file = new Blob([data],{type:'application / pdf'}); (数据是来自服务器的响应)。

2 个答案:

答案 0 :(得分:0)

ContentLength设置看起来有点可疑(不是结果):

       //content length for use in header
        var contentLength = buffer.Length;
        response.Content.Headers.ContentLength = doc.Length;

答案 1 :(得分:0)

我已修复'通过使用.Net控制器中的base64编码字符串到javascript web api调用结果,然后允许浏览器通过指定类型将其转换为二进制(' application / pdf')。