MVC+AJAX大文件数据库存取:上传报错、UI显示及取回方法求助
Hey Dimitri, let's break down each of your problems and fix them one by one:
1. Fixing Large File AJAX Upload Errors
First, let's diagnose why your AJAX upload fails for files over 0.5MB but works for small ones (and with regular Razor uploads):
Key Issues:
- Incorrect File Size Check in Controller: Your code has
if (file.ContentLength > 4096)— that's only 4KB, which explains why files over 0.5MB get blocked immediately. You probably meant to enforce your stated 10MB limit. - Missing
FormDatain AJAX: Traditional AJAX can't handle binary file data properly. You need to useFormDatato package the file for upload, which is what Razor's default form does under the hood. - ASP.NET Default Upload Limits: The framework has default caps on request size that you need to override in
web.config.
Fixes:
Step 1: Correct the Controller's Size Check
Update the size validation in your UpdateJsionFile action:
// 10MB in bytes = 10 * 1024 * 1024 = 10485760 if (file.ContentLength > 10485760) { return Json(new { success = false, error = "File size is too big, max 10MB" }, JsonRequestBehavior.AllowGet); }
Step 2: Update AJAX to Use FormData
Replace your existing upload logic with this (bind it to your .btnUpload click event):
$('.btnUpload').click(function() { var fileInput = $('#FileUpload')[0]; var selectedFile = fileInput.files[0]; if (!selectedFile) { alert('Please select a file first!'); return; } // Create FormData to package the file and ID var formData = new FormData(); formData.append('file', selectedFile); var fileId = $(this).closest('tr').data('id'); formData.append('id', fileId); $.ajax({ type: "POST", url: "/File/UpdateJsionFile", data: formData, contentType: false, // Critical: let browser set the correct content type processData: false, // Critical: don't let jQuery process the binary data success: function (response) { if (response.success) { alert('File uploaded successfully!'); loadFileData(); // Refresh your file list } else { alert('Upload failed: ' + response.error); } }, error: function (err) { alert("Failed! Please try again. Details: " + err.responseText); } }); });
Step 3: Increase Upload Limits in web.config
Add/update these sections to allow larger requests:
<system.web> <!-- Max request size in KB (10MB = 10240 KB) --> <httpRuntime maxRequestLength="10240" /> </system.web> <system.webServer> <security> <requestFiltering> <!-- Max allowed content length in bytes (10MB = 10485760 bytes) --> <requestLimits maxAllowedContentLength="10485760" /> </requestFiltering> </security> </system.webServer>
2. Displaying Selected File Name in UI
To show the selected file name, add an event listener to your file input and update a display element:
Step 1: Add a Display Element
Modify your HTML (where you render the file input) to include a span for the file name:
<td> <input type="file" id="FileUpload" /> <span id="selectedFileName" style="margin-left: 10px; color: #666;"></span> </td>
Step 2: Add the JavaScript Listener
Add this code to your script (after your loadFileData function):
// Listen for file selection changes $(document).on('change', '#FileUpload', function() { // Extract just the file name (strip the full path) var fileName = $(this).val().split('\\').pop(); $('#selectedFileName').text('Selected: ' + fileName); });
This will update the span with the name of the file the user picks.
3. Retrieving Large Files via AJAX (Better Approach)
AJAX isn't ideal for downloading large binary files — instead, we'll use a direct controller action that returns a file stream, and trigger the download from the frontend:
Step 1: Add a Download Action to Your Controller
Create this action to fetch the file from the database and return it as a stream:
public ActionResult DownloadFile(int id) { using (FileDBEntities db = new FileDBEntities()) { tblFile file = db.tblFiles.FirstOrDefault(p => p.id == id); if (file == null) { return HttpNotFound("File not found"); } // Return the file stream with correct content type and filename return File(file.Data, file.ContentType, file.Name); } }
Step 2: Update Frontend Download Logic
Modify your .FileDownload click handler to trigger the download (instead of using AJAX):
$(document).on('click', '.FileDownload', function(e) { e.preventDefault(); // Stop the default link behavior var fileId = $(this).closest('tr').data('id'); var fileName = $(this).text(); // Option 1: Open in a new tab to trigger download window.open('/File/DownloadFile?id=' + fileId); // Option 2: Create a hidden <a> tag to trigger download (more reliable) // var downloadLink = document.createElement('a'); // downloadLink.href = '/File/DownloadFile?id=' + fileId; // downloadLink.download = fileName; // document.body.appendChild(downloadLink); // downloadLink.click(); // document.body.removeChild(downloadLink); });
Either option will work, but the hidden <a> tag method is more consistent across browsers.
内容的提问来源于stack exchange,提问作者Dimitri

