You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET MVC中如何向控制器传文件及属性并接收PDF二进制响应

解决Ajax接收并展示PDF的问题

我来帮你搞定这个困扰多日的问题!核心问题出在Ajax对二进制PDF数据的处理方式错误,同时可能存在参数传递和服务器端PDF生成的细节疏漏,下面一步步拆解解决:

1. 先修正Ajax请求的核心配置

你当前设置dataType: 'json'完全不对——控制器返回的是二进制PDF文件,不是JSON格式,这就是你拿到二进制却没法解析的根源。需要改成处理blob类型,同时调整请求配置:

$.ajax({
    url: "/Home/PDF",
    type: "POST",
    // 关键:指定响应类型为二进制blob
    xhrFields: {
        responseType: 'blob'
    },
    data: { 
        Id : $("#ID").val(), 
        String : $("#String").html(), 
        Type: type, 
        Image: Item, 
        Image2: Item2 
    },
    success: function (blob) {
        // 方案1:直接触发PDF下载(最常用)
        const pdfUrl = window.URL.createObjectURL(blob);
        const downloadLink = document.createElement('a');
        downloadLink.href = pdfUrl;
        downloadLink.download = 'mobile.pdf';
        document.body.appendChild(downloadLink);
        downloadLink.click();
        // 清理临时URL,避免内存泄漏
        window.URL.revokeObjectURL(pdfUrl);
        document.body.removeChild(downloadLink);

        // 方案2:在页面内嵌入展示PDF(用iframe)
        // const pdfIframe = document.createElement('iframe');
        // pdfIframe.src = pdfUrl;
        // pdfIframe.width = '100%';
        // pdfIframe.height = '600px';
        // document.body.appendChild(pdfIframe);
    },
    error: function(xhr, status, error) {
        // 调试用:打印错误信息,方便排查服务器端问题
        console.error('请求出错:', error);
        console.error('服务器返回详情:', xhr.responseText);
    }
});

2. 服务器端Action的优化与排错

(1)图片参数的正确处理

如果前端传的Image和Image2是base64格式的图片字符串(比如通过canvas.toDataURL()生成的),你需要先把它转成byte[]才能用iTextSharp插入到PDF里:

public ActionResult PDF(string Id, string String, string Type, string Image, string Image2)
{
    // 用using包裹MemoryStream,确保自动释放资源
    using (var memoryStream = new System.IO.MemoryStream())
    {
        var document = new iTextSharp.text.Document();
        PdfWriter.GetInstance(document, memoryStream);
        document.Open();

        // 处理第一张图片:去除base64前缀(如果有的话)
        if (!string.IsNullOrEmpty(Image))
        {
            var base64Content = Image.Replace("data:image/png;base64,", "")
                                  .Replace("data:image/jpeg;base64,", "");
            var imageBytes = Convert.FromBase64String(base64Content);
            using (var imageStream = new MemoryStream(imageBytes))
            {
                var pdfImage = iTextSharp.text.Image.GetInstance(imageStream);
                // 可选:调整图片大小适配PDF页面
                pdfImage.ScaleToFit(500, 700);
                document.Add(pdfImage);
            }
        }

        // 同理处理第二张图片Image2...
        
        // 添加字符串内容到PDF
        document.Add(new iTextSharp.text.Paragraph(String));
        document.Add(new iTextSharp.text.Paragraph($"ID: {Id}, Type: {Type}"));

        document.Close();
        var pdfBytes = memoryStream.ToArray();
        return File(pdfBytes, "application/pdf", "mobile.pdf");
    }
}

(2)避免内部服务器错误的小技巧

  • 确保iTextSharp版本和你的.NET框架兼容:如果是.NET Core请用iText7,iTextSharp只支持.NET Framework
  • 检查图片参数是否完整传递:base64字符串可能很长,需要确保服务器允许足够大的请求体(可以在web.config里调整maxRequestLength)
  • 加try-catch捕获异常,方便调试:
public ActionResult PDF(string Id, string String, string Type, string Image, string Image2)
{
    try
    {
        // 原PDF生成代码...
    }
    catch (Exception ex)
    {
        // 调试阶段返回错误信息,正式环境可以换成统一错误响应
        return Content($"PDF生成失败:{ex.Message}", "text/plain");
    }
}

3. 如果前端是上传File对象的情况

如果你的Item和Item2是通过文件上传控件获取的File对象,那不能直接作为字符串传递,需要用FormData来上传:

const formData = new FormData();
formData.append('Id', $("#ID").val());
formData.append('String', $("#String").html());
formData.append('Type', type);
formData.append('Image', Item); // Item是File对象
formData.append('Image2', Item2);

$.ajax({
    url: "/Home/PDF",
    type: "POST",
    xhrFields: { responseType: 'blob' },
    data: formData,
    contentType: false, // 必须设置,让浏览器自动处理请求头
    processData: false, // 必须设置,不自动处理FormData格式
    success: function(blob) {
        // 同之前的下载/展示逻辑
    }
});

对应的控制器Action要改成接收HttpPostedFileBase类型的参数:

public ActionResult PDF(string Id, string String, string Type, HttpPostedFileBase Image, HttpPostedFileBase Image2)
{
    using (var memoryStream = new MemoryStream())
    {
        var document = new iTextSharp.text.Document();
        PdfWriter.GetInstance(document, memoryStream);
        document.Open();

        if (Image != null && Image.ContentLength > 0)
        {
            var pdfImage = iTextSharp.text.Image.GetInstance(Image.InputStream);
            pdfImage.ScaleToFit(500, 700);
            document.Add(pdfImage);
        }

        // 处理Image2和字符串内容...

        document.Close();
        return File(memoryStream.ToArray(), "application/pdf", "mobile.pdf");
    }
}

内容的提问来源于stack exchange,提问作者Ricardo Melo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:28:18