我在一個View上有兩種形式在一個Controller中執行兩個單獨的Action方法。MVC 4當我嘗試提交表單時,Model是空的
第一種形式(frmRefresh)負責獲取數據並將其顯示在窗體上,以便用戶可以選擇某些複選框。一旦提交,數據就會在ViewModel中正確返回並正確顯示在表單上。模板的11條記錄和保證人的3條記錄顯示爲表單上的複選框。
第二種形式(frmProcess)負責獲取表單上的數據(從上面的第一個帖子回來)。用戶在屏幕上進行選擇並根據Controller中的某些邏輯進行處理。我在模型中有List對象,並且不要因爲複雜的對象而使用FormCollection來處理數據。基本上,它們是複選框的集合。我真的需要使用應該在模型中提交的數據,因爲在Controller中處理該數據。
提交第二個表單時,我意識到,如果我將它們放在隱藏字段中(因爲它們處於單獨的表單中),那麼我將無法使用這個ddd,這很好。當我提交第二個表單(frmProcess)時,爲什麼模型視圖活頁夾沒有從表單中獲取數據,將其放入模型中並將其提交給我的GeneratePDF動作方法。?第一,我真的需要一些幫助來理解爲什麼會發生這種情況,第二,我真的需要一個解決方案,它將我的模型數據從表單傳遞到動作方法並對其進行處理。正如你可以在Controller中看到的那樣,在代碼的最後,我列舉了ViewModel中的模板來處理數據。
請大家幫忙,因爲我在工作時完全停留在這個位置,他們依賴於我。我只是不明白爲什麼模型聯編程序不會將表單上的值提交給操作方法進行處理。看起來我錯過了一些東西,允許數據在提交後回到模型中。
下面是我的相關代碼: ViedwModel
public partial class ViewModelTemplate_Guarantors
{
public int SelectedTemplateId { get; set; }
public IEnumerable<PDFTemplate> Templates { get; set; }
public int SelectedGuarantorId { get; set; }
public IEnumerable<tGuarantor> Guarantors { get; set; }
public string LoanId { get; set; }
public string SelectedDeptText { get; set; }
public string SelectedDeptValue { get; set; }
public string LoanType { get; set; }
public bool ShowTemps { get; set; }
public string Error { get; set; }
public string ErrorT { get; set; }
public string ErrorG { get; set; }
public bool ShowGeneratePDFBtn { get; set; }
}
查看
@model PDFConverterModel.ViewModels.ViewModelTemplate_Guarantors
@{
ViewBag.Title = "BHG :: PDF Generator";
}
<h2>@ViewBag.Message</h2>
<div>
<table style="width: 1000px">
<tr>
<td colspan="5">
<img alt="BHG Logo" src="~/Images/logo.gif" />
</td>
</tr>
@using (Html.BeginForm("Refresh", "Home", FormMethod.Post, new { id = "frmRefresh" })) { <tr>
<td>
@*@(Html.Kendo().NumericTextBox<int>()
.Name("txtLoanID")
.Placeholder("Enter numeric value")
)*@
@Html.LabelFor(model => model.LoanId)
@Html.TextBoxFor(model => model.LoanId)
@Html.ValidationMessageFor(model => model.LoanId)
</tr>
<tr>
<td>@Html.LabelFor(model => model.LoanType)
@Html.TextBox("SBA", "SBA")
@Html.ValidationMessageFor(model => model.LoanType)
@*@Html.TextBoxFor(model => model.LoanType)*@
</td>
<td>
<label for="ddlDept">Department:</label>
@(Html.Kendo().DropDownListFor(model => model.SelectedDeptText)
.Name("ddlDept")
.DataTextField("DepartmentName")
.DataValueField("DepartmentID")
.Events(e => e.Change("Refresh"))
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetDepartments", "Home");
});
})
)
@Html.ValidationMessageFor(model => model.SelectedDeptText)
</td>
</tr>
<tr>
<td colspan="3">
<input type="submit" id="btnRefresh" value='Refresh' />
</td>
</tr>
}
@using (Html.BeginForm("GeneratePDF", "Home", FormMethod.Post, new { id = "frmProcess" })) { if (Model.ShowGeneratePDFBtn == true)
{
if (Model.ErrorT != string.Empty)
{
<tr>
<td colspan="5">
<u><b>@Html.Label("Templates:")</b></u>
</td>
</tr>
<tr>
@foreach (var item in Model.Templates)
{
<td>
@Html.CheckBoxFor(model => item.IsChecked)
@Html.DisplayFor(model => item.TemplateName)
</td>
}
</tr>
}
else
{
Model.Error = Model.ErrorT;
}
if (Model.ErrorG != string.Empty)
{
<tr>
<td colspan="5">
<u><b>@Html.Label("Guarantors:")</b></u>
</td>
</tr>
<tr>
@foreach (var item in Model.Guarantors)
{
<td>
@Html.CheckBoxFor(model => item.isChecked)
@Html.DisplayFor(model => item.GuarantorFirstName) @Html.DisplayFor(model => item.GuarantorLastName)
</td>
}
</tr>
}
else
{
Model.Error = Model.ErrorG;
}
<tr>
<td>
<input type="submit" id="btnGeneratePDF" value='Generate PDF' />
</td>
</tr>
<tr>
<td colspan="5">
@Model.Error
</td>
</tr>
}
} </table>
</div>
<script type="text/javascript">
$('btnRefresh').on('click', '#btnRefresh', function() {
Refresh();
});
function Refresh() {
var LoanID = $("#LoanID").val();
if (LoanID != "") {
document.forms["frmTemps"].submit();
}
}
</script>
控制器
public ActionResult Index(ViewModelTemplate_Guarantors model)
{
ViewBag.Error = "";
model.ShowGeneratePDFBtn = false;
return View("Index", model);
}
// used for the first form "frmRefresh" [HttpPost] public ActionResult Refresh(ViewModelTemplate_Guarantors model) {
try
{
model.Error = string.Empty;
bool dbHasRows = db.ChkLoanFields(Convert.ToInt32(model.LoanId));
if (!dbHasRows)
{
model.ShowGeneratePDFBtn = false;
model.Error = "Details not available for this LoanId.";
return View("Index",model);
}
else
{
int TemplateCnt = 0;
int GuarantorCnt = 0;
//todo - modify 2nd & 3rd parms instead of hardcoding
ViewModelTemplate_Guarantors tg = db.SelectViewModelTemplate_Guarantors(Convert.ToInt32(model.LoanId), "All", "All", out TemplateCnt, out GuarantorCnt);
if (TemplateCnt > 0)
model.Templates = tg.Templates;
else
model.ErrorT = "Templates not available for this LoanType.";
if (GuarantorCnt > 0)
model.Guarantors = tg.Guarantors;
else
model.ErrorG = "Guarantors not available for this LoanId.";
model.ShowGeneratePDFBtn = true;
// right before the return here, the model is full of data. return View("Index", model); }
}
catch (Exception ex)
{
throw ex;
}
} [HttpPost] // when I check the data here (via submission from the "frmProcess" form, the model is completely empty, null, etc... WHY???? // i NEED the model data here to perform processing in this action method. public ActionResult GeneratePDF(ViewModelTemplate_Guarantors model) {
try
{
int FolderNo, GuarantorNum = 0;
string Folder, LoanFolder = String.Empty;
string FormId, FormName, GuarantorName = String.Empty;
int LoanId = Convert.ToInt32(model.LoanId);
LoanFolder = LoanId.ToString().PadLeft(8, '0');
//To calculate FolderId based on LoanId
if ((LoanId > 0) && (LoanId < 99000))
{
FolderNo = ((int)(LoanId/10000) * 10000);
}
else
{
FolderNo = ((int)(LoanId/1000) * 1000);
}
Folder = ((int)FolderNo).ToString();
Folder = Folder.PadLeft(8, '0');
//todo - 2nd parm SelectedValue of dept
List<sSRPTFundexDocCodes1_Test_Result> sSRPTFundexDocCodes1 = db.GetFormValues(Convert.ToInt32(model.LoanId), (model.SelectedDeptValue));
if (sSRPTFundexDocCodes1 != null)
{
foreach (PDFTemplate template in model.Templates) {
if (template.IsChecked == true) {
TEMPLATENAME沒有出現在模型後門柱。 這工作正常...值(複選框和相應的名稱顯示在窗體上
但是,發佈GeneratePDF按鈕時,我看到的所有模型是如果複選框被選中(這是偉大的)。在玩過以下很多語句之後(ValueFor,DisplayFor,LabelFor,EditorFor等),模板名稱返回的值是空白的。我需要與複選框相對應的模板名稱。
@ Html.ValueFor(型號=> Model.Templates [I] .TemplateName)
我怎樣才能做到這一點?謝謝你的時間提前......下面是我更新的代碼。查看的
ViewModel public partial class ViewModelTemplate_Guarantors
{
public ViewModelTemplate_Guarantors()
{
Templates = new List<PDFTemplate>();
Guarantors = new List<tGuarantor>();
}
public int SelectedTemplateId { get; set; }
public List<PDFTemplate> Templates { get; set; }
public int SelectedGuarantorId { get; set; }
public List<tGuarantor> Guarantors { get; set; }
public string LoanId { get; set; }
public string SelectedDeptText { get; set; }
public string SelectedDeptValue { get; set; }
public string LoanType { get; set; }
public string Error { get; set; }
public string ErrorT { get; set; }
public string ErrorG { get; set; }
public bool ShowGeneratePDFBtn { get; set; }
}
Pertinet部分:
if (Model.ShowGeneratePDFBtn == true)
{
if (Model.ErrorT == string.Empty)
{
<tr>
<td colspan="5">
<u><b>@Html.Label("Templates:")</b></u>
</td>
</tr>
<tr>
@for (int i = 0; i < Model.Templates.Count; i++)
{
<td>
@Html.CheckBoxFor(model => Model.Templates[i].IsChecked)
@Html.ValueFor(model => Model.Templates[i].TemplateName) </td>
}
</tr>
}
else
{
<tr>
<td>
<b>@Html.DisplayFor(model => Model.ErrorT)</b>
</td>
</tr>
}
if (Model.ErrorG == string.Empty)
{
<tr>
<td colspan="5">
<u><b>@Html.Label("Guarantors:")</b></u>
</td>
</tr>
<tr>
@for (int i = 0; i < Model.Guarantors.Count; i++)
{
<td>
@Html.CheckBoxFor(model => Model.Guarantors[i].isChecked)
@Html.ValueFor(model => Model.Guarantors[i].GuarantorFirstName) @Html.ValueFor(model => Model.Guarantors[i].GuarantorLastName) </td>
}
</tr>
}
else
{
<tr>
<td>
<b>@Html.DisplayFor(model => Model.ErrorG)</b>
</td>
</tr>
}
}
<tr>
<td colspan="3">
<input type="submit" name="submitbutton" id="btnRefresh" value='Refresh' />
</td>
@if (Model.ShowGeneratePDFBtn == true)
{
<td>
<input type="submit" name="submitbutton" id="btnGeneratePDF" value='Generate PDF' />
</td>
}
</tr>
<tr>
<td colspan="5">
@Model.Error
</td>
</tr>
控制器:
public ActionResult ProcessForm(string submitbutton, ViewModelTemplate_Guarantors model, FormCollection collection)
基本上,再次它的正常工作。當表單使用「生成PDF」按鈕發佈帖子時,我會得到每個複選框的選中值,而不是模型中模板的名稱。
我在這裏錯過了什麼?
我提交之前的表單基本上如下所示。這是複選框(Form4)的名稱,我一旦進入ActionResult,就會在我的模型中作爲TemplateID丟失。
public ActionResult ProcessForm(string submitbutton, ViewModelTemplate_Guarantors model, FormCollection collection)
複選框(選中)Form4
@for (int i = 0; i < Model.Templates.Count; i++)
{
<td>
@Html.CheckBoxFor(model => Model.Templates[i].IsChecked)
@Html.DisplayFor(model => Model.Templates[i].TemplateName)
</td>
}
正如我在最後一個問題中告訴你的,IEnumerables不能以這種方式綁定。爲了使模型聯編程序綁定它們,它們必須是可變集合(IEnumerable不能),例如List。 –