I’m trying to do something that seems like it should be easy but I’m new to MVC and convention-based programming.
I have a jQuery datatable that is getting rows for PDF documents through AJAX. In the fnRowCallback, I added checkboxes so that the user can select multiple documents to be combined for a single download. As checkboxes are checked, the document ID is added to a JavaScript array of numbers and the filenames are added to another array so that, when combined, they can be used for bookmarks in the resulting PDF. Is there any way to send these two variables to the controller action? So far, all I’ve been able to do is JSON.stringify() one of the variables and send it to the controller using a hidden field in a form I put on the view and deserializing it in the controller but I’m goofing it up when I try to add the second variable. There has to be an easier way but I can’t even figure out the convoluted way and all articles I’ve read use AJAX. I can’t use AJAX, though, because you can’t send a binary file back in the response.
JavaScript:
var aiSelectedPDFs = new Array();
var aiSelectedDocumentIDs = new Array();
$('#imgDownload').click(function () {
$('#selectedPDFs').val(JSON.stringify(aiSelectedPDFs));
$('#selectedDocumentIDs').val(JSON.stringify(aiSelectedDocumentIDs));
$('#DownloadSelectedPdfs').submit();
});
View:
<img id="imgDownload" src="@(Url.RootUrl())Content/images/icons/pdf.gif"
alt="Download selected documents" title="Download selected documents" />
@using (Html.BeginForm("DownloadSelectedPdfs", "Controller", FormMethod.Post,
new { id = "DownloadSelectedPdfs" }))
{
<input type="hidden" id="selectedPdfs" name="jsonSelectedPdfs"/>
<input type="hidden" id="selectedDocumentIDs" name="jsonSelectedDocumentIDs"/>
}
Controller:
[HttpPost]
public ActionResult DownloadSelectedPdfs(string jsonSelectedDocumentIDs)
{
var selectedDocumentIDs = new JavaScriptSerializer().Deserialize<int[]>(
jsonSelectedDocumentIDs);
var invoices = new Dictionary<string, byte[]>();
foreach (int documentID in selectedDocumentIDs)
{
invoices.Add(documentID.ToString(),
_documentService.GetDocument(documentID));
}
return new FileContentResult(PdfMerger.MergeFiles(invoices),
"application/pdf");
}
Your answer is 90% correct, Kroehre. Thank you for such a quick response. The only issue is that the application cannot figure out what controller action to use so the page fails to load and I get redirected to my friendly error page. The solution to that was pretty simple, though, and I’ll put the code below.
View (I left out the
divs as I felt they sullied up the code with presentation semantics where nothing was to be displayed, though they had no syntactical impact. Just personal preference so not part of the missing 10%. 😉 ):Script (Created similar multiple hidden inputs but with naming such that they were the same object with properties):
Controller (added new class to handle the multiple, related javascript variables):