2016-03-24 6 views
1

Ich habe eine Ansicht, die ein ViewModel auf der Seite anzeigt. Ich möchte dem Benutzer erlauben, eine Taste zu drücken, um eine CSV-Datei zu erstellen, die dann an sie per E-Mail gesendet wird. Ich habe den POSt funktioniert, aber das ViewModel, das zurückgeschickt wird, ist immer leer, obwohl die Seite deutlich viele Zeilen zeigt.Zurück ein ViewBag ViewModel zurück zu Controller in BeginForm Post-Methode in der Ansicht

Dies ist ein Teil der Ansicht in Frage:

<table style="width:99%" cellpadding="3" class="ContentTable" border="1" align="center"> 

    @using (Html.BeginForm("SubmitExcel", "AllRecognition", new { AllRecognitions = ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel }, FormMethod.Post, new { id = "submitExcel" })) 
    { 
     <tr> 
      <td style="padding:3px;"> 
       <input type="submit" name="BtnSubmitExcel" id="BtnSubmitExcel" value="Export to Excel" /> 
      </td> 
     </tr> 
    } 

    <tr style="background-color:#5D7B9D;color:white;"> 
     <th style="width:4%;padding:3px;font-size:12px;">Date</th> 
     <th style="width:8%;padding:3px;font-size:12px;">Employee</th> 
     <th style="width:8%;padding:3px;font-size:12px;">Recognized By</th> 
     <th style="width:6%;padding:3px;font-size:12px;">5-Star Standard</th> 
     <th style="width:70%;padding:3px;font-size:12px;">Description</th> 
     <th style="width:4%;padding:3px;font-size:12px;">Points</th> 
    </tr> 

    @{ 

     if (ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel != null) 
     { 
      foreach (Recognition.ViewModels.AllRecognitionViewModel item in ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel) 
      { 
       @:<tr> 
        @:<td style="width:4%;padding:3px;font-size:12px;">@item.Date</td> 
        @:<td style="width:8%;padding:3px;font-size:12px;">@item.Employee</td> 
        @:<td style="width:8%;padding:3px;font-size:12px;">@item.RecognizedBy</td> 
        @:<td style="width:6%;padding:3px;font-size:12px;">@item.FiveStarStandard</td> 
        @:<td style="width:70%;padding:3px;font-size:12px;">@item.Description</td> 
        @:<td style="width:4%;padding:3px;font-size:12px;">@item.Points</td> 
       @:</tr> 
       } 



     } 
    } 

</table> 

Dies ist die Seite-Controller die POST-Methode empfängt:

public ActionResult SubmitExcel(List<ViewModels.AllRecognitionViewModel> AllRecognitions) 
    { 
     ViewBag.NoSearch = "block"; 
     ViewBag.SupervisorSearch = "none"; 
     ViewBag.DepartmentSearch = "none"; 
     ViewBag.EmployeeSearch = "none"; 

     DataTable dtAllRecognitions = Base.SQLHelper.ConvertListToDataTable(AllRecognitions.ToList()); 
     DataSet dsAllRecognitions = new DataSet(); 
     dsAllRecognitions.Tables.Add(dtAllRecognitions); 
     FHSBase.FHS.DataHelper.SendMeExcelFile(dsAllRecognitions, "Recognitions", CurrentUser); 

     ViewModels.AllRecognitionBigViewModel AllRecognitionBigViewModel = new ViewModels.AllRecognitionBigViewModel(); 
     AllRecognitionBigViewModel.AllRecognitionViewModel = null; 
     Models.DateRange DateRange = new Models.DateRange(); 
     DateRange.fromDate = DateTime.Today.Date; 
     DateRange.toDate = DateTime.Today.Date; 
     AllRecognitionBigViewModel.DateRange = DateRange; 
     ViewBag.AllRecognitionBigViewModel = AllRecognitionBigViewModel; 

     List<SelectListItem> empList = new List<SelectListItem>(); 
     string VPath = "Index"; 
     return View(VPath, empList); 

    } 

Die "AllRecognitions" Ansicht Modell ist leer in der Action aber ISN in der Ansicht selbst leer. Wie kann ich das aktuelle Ansichtsmodell mit den aktuellen Werten in der Ansicht zurück zum ActionResult (SubmitExcel) abrufen?

+0

Sie möchten TempData für Ihre AllRecognitions. Es wird für Sie da sein, wenn Sie POST. Sie können den ViewBag weiterhin für das Rendern verwenden, wenn Sie möchten, aber dann ist es verloren, wenn Sie es nicht mit Formulareingabeelementen verknüpfen. TempData überlebt die Rundreise in Erinnerung und ist nicht abhängig von der Form. –

Antwort

0

Funktioniert das für Sie? Es ist ein anderer Ansatz. Da Sie in Ihrer Ansicht nichts manipulieren und nur nach Excel exportieren möchten, sollten Sie Ihre Ergebnisse nicht in ViewDaten, sondern in TempData speichern und dann beim POST abrufen. TempData ist gut in Erinnerung für diese eine Reise zurück.

Also, in Ihren ersten Controller machen, tun:

TempData["AllRecognition"] = ThisIsMyAllRecognitionViewModelData; 

Dann, wenn sie übertreffen einreichen, dass die Daten immer noch in Temp.

public ActionResult SubmitExcel() 
    { 
var MyDataMadeIt = TempData["AllRecognition"]; 
// do some stuff 
} 
+1

Das hat funktioniert und war sehr einfach zu implementieren! Vielen Dank! – pldiguanaman

0

Ihr Formular ist leer. Daher werden keine Daten auf dem Server veröffentlicht.

Wenn Sie ein Formular absenden, sendet es nicht die gesamte Seite an den Server. (Wie würde der Server überhaupt wissen, was mit dem HTML zu tun ist, um die gewünschten Werte zu erhalten?) Er sendet Schlüssel/Wert-Paare aus Formularelementen. Und Sie haben nur ein Formularelement:

Also nur dieser eine Schlüssel/Wert wird an den Server gesendet.

Das erste, was Sie tun müssen, ist Ihr Formular um die Daten zu wickeln, die Sie auf dem Server veröffentlichen möchten. Also im Grunde um Ihren gesamten Tisch herum.

Als nächstes müssen Sie tatsächliche Formularelemente ausgeben. Der Text auf der Seite ist nicht verwertbare Daten, es ist nur Seiteninhalt. Da das Modell ein List<ViewModels.AllRecognitionViewModel> ist, sollten Sie es mit einer einfachen Modifikation Ihrer Schleife tun können. Anstatt also diese:

foreach (Recognition.ViewModels.AllRecognitionViewModel item in ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel) 

Sie würden dies wollen:

for (var i = 0; i < ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel.Count(); i++) 

Die Formelemente hidden sein können, so dass Sie nicht die aktuelle UX auf Ihrer Seite ändern. Vielleicht etwas wie folgt aus:

@Html.HiddenFor(x => x[i].Date) 

oder vielleicht:

@Html.HiddenFor(x => x.AllRecognitionViewModel[i].Date) 

Ich bin hier ein bisschen eigentlich zu raten, da ich das Modell anstelle des ViewBag zu verwenden für diese viel mehr daran gewöhnt bin . (Was Sie vielleicht stattdessen verwenden möchten, wird es wahrscheinlich einfacher machen.) Sie müssen möglicherweise ein Debugging durchführen, um genau festzustellen, was im serverseitigen Code hier vor sich geht.

Letztlich, was Sie suchen in Ihrem clientseitige Code zu sehen sind Elemente ähnlich wie diese:

<input type="hidden" name="AllRecognitionViewModel.Date[0]" value="..." /> 

Also, wenn die oben genannten @Html.EditorFor Vorschläge nicht funktionieren, können Sie immer tun es manuell.In der Schleife könnte es etwa so aussehen:

<input type="hidden" name="AllRecognitionViewModel.Date[@i]" value="@ViewBag.AllRecognitionBigViewModel.AllRecognitionViewModel[i].Date" /> 

Der Schlüssel, was zu beachten ist das name Attribut. Durch Senden dieser "Arrays" aus Schlüssel/Wert-Paaren an den Server sollte der Modellbinder in der Lage sein, die List<ViewModels.AllRecognitionViewModel> zu konstruieren.

+0

Ich habe entschieden, den BeginForm Post um die gesamte Tabelle zu wickeln, aber immer noch ein leeres Viewmodel im Controller. Ich probierte beide versteckten Methoden, die Sie angezeigt haben, aber ich bekomme eine Fehlermeldung über kann nicht mit einer IEnumerable Liste verwendet werden, die ein anderes Modell ist, das weiter oben in der Ansicht verwendet wird. Es kommt mir nur komisch vor, dass ich das ViewBag Viewmodel nicht an den Controller weitergeben kann. – pldiguanaman

+0

@pldiguanaman: Sie * können Daten an den Controller zurückgeben. Sie müssen nur diese Daten in Formularelementen haben. Ich habe einen weiteren möglichen Vorschlag am Ende der Antwort hinzugefügt. Wenn die '@ Html.HiddenFor'-Ansätze nicht funktionieren, können Sie die Formularelemente immer einfach manuell erstellen. – David

Verwandte Themen