简体   繁体   English

MemoryStream到HttpResponseMessage

[英]MemoryStream to HttpResponseMessage

I have generated a Pdf on the server, and need to return it as a response to my web client, so that I get a 'Save As' dialog. 我在服务器上生成了一个Pdf,需要将其作为对Web客户端的响应返回,以便获得“另存为”对话框。

The pdf is generated, and saved to a Memory stream... which is then returned to my method which will return the HttpResponseMessage. 生成pdf,并将其保存到Memory流中……然后返回到我的方法,该方法将返回HttpResponseMessage。

The is the method: 方法是:

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

However, the document renders as a blank file, and although it has a file size, and properties of the document I created (pdf information if File Properties is all right, as well as page width and height), the document displays as blank. 但是,该文档呈现为空白文件,尽管具有文件大小和我创建的文档的属性(如果“文件属性”没问题,还包括页面宽度和高度,则为pdf信息),但文档显示为空白。

If I un-comment the code that is commented out, to save locally, the file is perfect. 如果我取消注释掉已注释掉的代码以保存在本地,则该文件是完美的。 File size is 228,889 bytes. 文件大小为228,889字节。 However, when I let it go to my web page and save it, it's 405,153 bytes and the filename is 'undefined'. 但是,当我将其转到我的网页并保存时,它是405,153字节,文件名是“未定义”。

If I breakpoint, I see these results: 如果出现断点,则会看到以下结果:

在此处输入图片说明

On the front end script, I handle the downloaded object like this: 在前端脚本上,我像这样处理下载的对象:

$.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);
        });

I'm unsure where the file is being corrupted. 我不确定文件在哪里损坏。 What am I doing wrong? 我究竟做错了什么?

Edit: Using the following code as suggested: 编辑:根据建议使用以下代码:

$.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 code: .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;

It seems I am losing data. 看来我正在丢失数据。 The alert is the length of the 'data.length' in my javascript, after I get data back from the call. 警报是我从调用中获取数据后,javascript中“ data.length”的长度。 The file properties is the original pdf file info. 文件属性是原始pdf文件信息。

在此处输入图片说明

File sends from api, size is 227,564, which matches the byte size on disk if I save it. 从api发送的文件,大小为227,564,如果我将其保存,则与磁盘上的字节大小匹配。 So it SEEMS the sending is OK. 因此,SEEMS发送正常。 But on the javascript size, when I read in the file, it's 424946, when I do: var file = new Blob([data], { type: 'application/pdf' }); 但是在javascript大小上,当我读文件时,它是424946,当我这样做时:var file = new Blob([data],{type:'application / pdf'}); (Where data is the response from the server). (其中数据是来自服务器的响应)。

The ContentLength setting looks somewhat suspicious (not consequent): ContentLength设置看起来有点可疑(并非必然):

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM