2012-05-03 14 views
0

我試圖做一些看起來應該很容易的事情,但我是新來的MVC和基於約定的編程。如何將JavaScript數組發佈到MVC 3控制器操作(由於文件下載而沒有AJAX)?

我有一個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"); 
    } 
+0

這90%是正確的。我發佈了修正,使其工作100%。我應該把你的標記作爲答案還是我的?我對StackOverflow真的很陌生,正如你可以看到我的名聲,所以我很樂意在這個問題上遵從你的判斷和道德。 –

回答

1

你的回答是90%正確的,Kroehre。感謝您提供如此快速的迴應。唯一的問題是,應用程序無法找出要使用的控制器操作,因此頁面無法加載,我將其重定向到友好的錯誤頁面。儘管如此,解決方案非常簡單,我將把代碼放在下面。

查看(我離開了div S作爲我覺得他們玷污了的表達語義的代碼在那裏什麼也沒有顯示,但他們沒有語法的影響。只是個人喜好所以沒有失蹤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"); 
} 
0

陣列可以被髮送通過指定每個值的數組名稱和索引通過表單。我已經修改了代碼:

查看(更換你的隱藏輸入,集裝箱):

<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[],因爲類型必須能夠在實例化後添加元素,以便模型聯編程序在讀取發佈的值時正常工作。

相關問題