2 つのフォーム投稿を含む 1 つのフォームを使用しています。最初のフォーム ("frmTemps") は、データを正常に取得し、フォームに表示します。データを表示するためにビューに戻ったときに、デバッグによってデータがモデル内にあることを保証できます。
データが戻ってくると、同じビューに別のボタンが表示されますが、最初のフォーム ("frmTemps") から返された選択されたデータを処理するための 2 番目のフォーム ("frmProcess") が表示されます。sme ビューで複数のフォームを使用できることはわかっています。それはすべて、MVC が提供する制御の一部です。
問題は、2 番目のフォーム (" frmProcess ")を投稿し、そのアクションの結果にすぐにブレークポイントを設定して、モデルの内容を確認するとすぐに、モデル内のすべての項目が null であることがわかります。ゼロ、または偽。モデル オブジェクトのデバッグを介して。
[HttpPost]
public ActionResult GeneratePDF(ViewModelTemplate_Guarantors model) {
フォーム 1 と同じモデルをフォーム 2 で使用しています。
フォームにデータを入力して送信し、アクション メソッドでモデル タイプに受け取ってもらうのが標準的な方法であることが理解されたと思います。
以下は、私のViewModelです。
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 = "frmTemps" }))
{
<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)
<td colspan="3">
<input type="submit" id="btnRefresh" value='Refresh' />
</td>
</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>
}
@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>
以下は、コントローラーの関連部分です。
[HttpPost]
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');
ボタン 1 からフォームを送信しましA
た。モデルが戻ってきて、私のView A
. View A
ここで、ボタン 2 を使用して、同じコントローラー内の別の Action メソッドに再度送信したいと考えています。
モデルを受信パラメーターとして同じコントローラーにフォームを再度送信すると、アクション メソッドに到達したときにモデルが空になります。最初のステップで上に戻ったときに、モデルにデータが含まれていることがわかりました。
MVC に比較的慣れていないので、ビューにデータが入力されていて、フォームをコントローラーに送信する場合、モデルにはデータが含まれているはずだという印象を受けました。モデルが永続的ではないことに気付きました。モデルをビューに、またはその逆に渡すと、それはなくなります。わかった。
私が知りたいのは、コントローラーに送信する前にモデルにデータを入力して、ビューをレンダリングするためにモデルにデータを入力してコントローラーにデータを送信する方法だけです。それはとても簡単です。私のモデルは強く型付けされたモデルではありません。これは、ビューとコントローラーの間でデータをやり取りする方法を理解するための主要な基礎であり、MVC がどのように機能するかを理解する上で非常に重要であると感じています。
コントローラーに再び到達したときにデータが空である場合、何が間違っていますか。何らかの処理を行ってビューを再度レンダリングするために、モデルにデータが含まれる場所を送信する前に、ビューからデータをモデル内に戻すにはどうすればよいですか。
前のポストバックからフォームに既に存在するデータがある場合、2 番目のボタンを使用して再度投稿すると、MVC がモデル バインダーを使用してフォーム データでモデルを作成し、投稿しないのはなぜですか。
ローン ID と ddl がデータに含まれないことはわかっていますが (2 番目の形式でラップされていないため)、その動作に非常に困惑しています。フォームにあるデータをモデルに戻すことを期待していました。なぜこれをしないのですか?