如何将 JavaScript 数组发布到 MVC 3 控制器操作(由于文件下载而没有 AJAX)
How do I post a JavaScript array to an MVC 3 controller action (no AJAX due to file download)?
我正在尝试做一些看起来应该很容易的事情,但我是MVC和基于约定的编程的新手。
我有一个jQuery数据表,它通过AJAX获取PDF文档的行。在fnRowCallback
中,我添加了复选框,以便用户可以选择要合并的多个文档以进行一次下载。选中复选框时,文档 ID 将添加到 JavaScript 数字数组中,文件名将添加到另一个数组中,以便在组合时,它们可以用于生成的 PDF 中的书签。有没有办法将这两个变量发送到控制器操作?到目前为止,我所能做的就是JSON.stringify()
其中一个变量,并使用我放在视图上的隐藏字段将其发送到控制器并在控制器中反序列化它,但是当我尝试添加第二个变量时,我把它搞砸了。必须有一种更简单的方法,但我什至无法弄清楚复杂的方法,我读过的所有文章都使用 AJAX。但是,我不能使用 AJAX,因为您无法在响应中发送回二进制文件。
JavaScript:
var aiSelectedPDFs = new Array();
var aiSelectedDocumentIDs = new Array();
$('#imgDownload').click(function () {
$('#selectedPDFs').val(JSON.stringify(aiSelectedPDFs));
$('#selectedDocumentIDs').val(JSON.stringify(aiSelectedDocumentIDs));
$('#DownloadSelectedPdfs').submit();
});
视图:
<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"/>
}
控制器:
[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");
}
你的答案是90%正确,Kroehre。感谢您如此快速的回复。唯一的问题是应用程序无法确定要使用什么控制器操作,因此页面无法加载,我被重定向到我的友好错误页面。不过,解决方案非常简单,我将把代码放在下面。
视图(我省略了div
,因为我觉得它们用表示语义玷污了代码,其中没有显示任何内容,尽管它们没有语法影响。只是个人喜好,所以不是缺少的10%的一部分。;-) ):
<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" })) { }
脚本(创建了类似的多个隐藏输入,但命名使它们是具有属性的同一对象(:
var aiSelectedPDFs = new Array();
var aiSelectedDocumentIDs = new Array();
$('#imgDownload').click(function () {
var form = $('#DownloadSelectedPdfs');
form.html('');
for (var i = 0; i < aiSelectedPDFs.length; i++) {
form.append('<input type="hidden" name="selectedPDFs[' + i + '].RefNumber"
value="' + aiSelectedPDFs[i] + '" />');
form.append('<input type="hidden" name="selectedPDFs[' + i + '].DocumentID"
value="' + aiSelectedDocumentIDs[i] + '" />');
}
form.submit();
});
控制器(添加了新类来处理多个相关的 JavaScript 变量(:
public class PDFViewModel
{
public int RefNumber { get; set; }
public int DocumentID { get; set; }
}
[HttpPost]
public ActionResult DownloadSelectedPdfs(List<PDFViewModel> selectedPDFs)
{
var pdfs = new Dictionary<string, byte[]>();
foreach (var selectedPDF in selectedPDFs)
{
var document = _documentService.GetDocument(selectedPDF.DocumentID);
var tabName = string.Format("pdf_{0}", selectedPDF.RefNumber);
pdfs.Add(tabName, document);
}
return new FileContentResult(PdfMerger.MergeFiles(pdfs), "application/pdf");
}
数组可以通过为每个值指定数组名称和索引来通过表单传输。我已经修改了你的代码:
视图(将隐藏的输入替换为容器(:
<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" }))
{
<div id="pdfs"></div>
<div id="docs"></div>
}
脚本(为数组中的项目添加/填充隐藏输入,而不是使用字符串化(:
var aiSelectedPDFs = new Array();
var aiSelectedDocumentIDs = new Array();
function createInputs(container, name, values){
$(container).html('');
for(var i = 0; i<values.length; i++){
$(container).append('<input type="hidden" name="' + name + '[' + i + ']" value="' + values[i] + '" />');
}
}
$('#imgDownload').click(function () {
createInputs('#pdfs', 'selectedPdfs', aiSelectedPDFs);
createInputs('#docs', 'selectedDocumentIDs', aiSelectedDocumentIDs);
$('#DownloadSelectedPdfs').submit();
});
控制器(更新输入参数以与发布的数组对齐,利用 MVC3 的内置模型绑定器(:
[HttpPost]
public ActionResult DownloadSelectedPdfs(List<int> selectedPdfs, List<int> selectedDocumentIDs)
{
var invoices = new Dictionary<string, byte[]>();
foreach (int documentID in selectedDocumentIDs)
{
invoices.Add(documentID.ToString(),
_documentService.GetInvoice(documentID));
}
return new FileContentResult(PdfMerger.MergeFiles(invoices),
"application/pdf");
}
*注意 - 我对参数使用了List<int>
而不是int[]
因为类型必须能够在实例化后添加元素,以便模型绑定器在读取已发布的值时正常运行。
- asp.net网站文件下载历史记录
- YUI向json文件发出ajax请求
- Firefox,如何提交表单触发文件下载,但停留在网页上
- 什么's使用脚本标记调用文件和ajax之间的区别
- 我如何从javascript文件中AJAX发布到MVC操作
- Interent Explorer中的数据URI文件下载
- Http 文件下载请求停止 JQuery ajax 调用
- AJAX 文件下载:进度事件,供下载
- 如何将 JavaScript 数组发布到 MVC 3 控制器操作(由于文件下载而没有 AJAX)
- 强制下载 Ajax 成功时的.mp3或.zip文件
- 从facebook下载ajax文件
- PHP文件下载与ajax问题
- Ajax响应是一个文件下载
- Spring Rest和jQuery Ajax文件下载
- 为什么我的AJAX文件下载,使用基于Blob的对象url,破坏文件
- Ajax -知道文件下载是否正确地从服务器发送
- 文件下载操作的Ajax
- 经过验证的AJAX文件下载
- 没有文件下载后,AJAX Post在余烬
- 在Chrome / Safari下载文件期间$ajax调用挂起,而不是在IE / Firefox中