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

AJAX中Byte[]返回数据类型问题:控制器返回byte[]但AJAX调用失败

Fixing AJAX Failure When Retrieving PDF Byte Array from Controller

Let's break down why your current setup is failing and walk through the correct approach to handle PDF downloads via AJAX.

The Core Issues

  1. Incorrect Controller Return Type: Using JsonResult to return a byte[] is not ideal. JSON serialization converts the byte array into a huge array of integers, which is inefficient to transfer and hard for the frontend to parse back into a valid PDF.
  2. Mismatched AJAX Data Type: You've set dataType: 'json', but the controller is sending raw byte data (or a serialized integer array) instead of valid JSON, so AJAX can't parse it and triggers the error callback.
  3. Suboptimal Binary Data Handling: GET requests have length limits, and default AJAX settings don't handle binary blobs correctly out of the box.

Step 1: Fix the Controller Code

Instead of JsonResult, use FileContentResult to directly return the PDF binary stream with the correct MIME type. This is the standard way to serve files from an ASP.NET controller.

public FileContentResult GeneratePDF(string orderQuoteId)
{
    byte[] pdfData = ServiceCall();
    // Return the PDF with appropriate MIME type and optional download filename
    return File(pdfData, "application/pdf", $"OrderQuote_{orderQuoteId}.pdf");
}

This tells the browser exactly what type of content it's receiving and suggests a filename for download.


Step 2: Update the AJAX Call

Modify your AJAX to handle binary blob data instead of JSON, and adjust settings to match the controller's response:

$.ajax({
    url: '@Url.Action("GeneratePDF", "AccountDetail")',
    type: 'POST', // Use POST if your PDF is large (avoids GET length limits); GET works for small files
    contentType: 'application/x-www-form-urlencoded; charset=utf-8', // Standard for form data
    data: { 'orderQuoteId': orderQuoteId },
    xhrFields: {
        responseType: 'blob' // Critical: tells AJAX to expect binary blob data
    },
    success: function (pdfBlob) {
        // Create a temporary download link to trigger the browser's PDF download
        const downloadUrl = window.URL.createObjectURL(pdfBlob);
        const link = document.createElement('a');
        
        link.href = downloadUrl;
        // Use the filename from the controller, or set your own
        link.download = `OrderQuote_${orderQuoteId}.pdf`;
        
        document.body.appendChild(link);
        link.click();
        
        // Clean up to free browser resources
        window.URL.revokeObjectURL(downloadUrl);
        document.body.removeChild(link);
        
        alert('PDF generated successfully!');
    },
    error: function (xhr, status, error) {
        // Log details for debugging
        console.error('PDF Generation Error:', status, error);
        alert('Error occurred while creating PDF');
    }
});

Key Explanations

  • responseType: 'blob': Ensures jQuery doesn't try to parse the response as JSON, which would fail with binary data.
  • FileContentResult: Properly sets HTTP headers (like Content-Type and Content-Disposition) that browsers understand for file downloads.
  • Blob Handling: Converts the binary response into a downloadable file using browser APIs, which is the reliable way to handle PDFs in the frontend.

If for some reason you need to stick with returning JSON, you can convert the byte array to a Base64 string in the controller and parse it back to a blob in the frontend. This is less efficient but works:

Controller Code

public JsonResult GeneratePDF(string orderQuoteId)
{
    byte[] pdfData = ServiceCall();
    string base64Pdf = Convert.ToBase64String(pdfData);
    return Json(base64Pdf);
}

AJAX Code

$.ajax({
    url: '@Url.Action("GeneratePDF", "AccountDetail")',
    type: 'GET',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    data: { 'orderQuoteId': orderQuoteId },
    success: function (base64Result) {
        // Convert Base64 string back to byte array and blob
        const byteChars = atob(base64Result);
        const byteNumbers = new Array(byteChars.length);
        for (let i = 0; i < byteChars.length; i++) {
            byteNumbers[i] = byteChars.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        const pdfBlob = new Blob([byteArray], { type: 'application/pdf' });
        
        // Same download logic as before
        const downloadUrl = window.URL.createObjectURL(pdfBlob);
        const link = document.createElement('a');
        link.href = downloadUrl;
        link.download = `OrderQuote_${orderQuoteId}.pdf`;
        document.body.appendChild(link);
        link.click();
        window.URL.revokeObjectURL(downloadUrl);
        document.body.removeChild(link);
        
        alert('PDF generated successfully!');
    },
    error: function () {
        alert('Error occurred while creating PDF');
    }
});

But again, the first approach (using FileContentResult and blob response) is the standard, efficient way to handle file downloads.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:43:35