0

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)&nbsp;@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 番目の形式でラップされていないため)、その動作に非常に困惑しています。フォームにあるデータをモデルに戻すことを期待していました。なぜこれをしないのですか?

4

2 に答える 2

3

フォームはモデルを共有していますが、GeneratePDF アクションに送信される値は、"frmProcess" フォームに含まれている値のみです。"frmTemps" (例: LoanId) の値を GeneratePDF アクションに再送信する必要がある場合は、隠しフィールドとして "frmProcess" フォームに含める必要があります。

@Html.HiddenFor(m => m.LoanId)

したがって、データフローは次のとおりです。

  • 「frmTemps」に値を入力します
  • 「frmTemps」から「Refresh」アクションへのデータの投稿
  • 更新されたモデルでビューを返す
  • 更新されたモデルの値は、「frmProcess」の非表示フィールドとして入力されます
  • 「frmProcess」から「GeneratePDF」アクションへのすべてのデータの投稿
于 2012-10-06T19:40:43.977 に答える
2

心に留めておくべきことがいくつかあります。

まず、フォームは送信されたフォーム要素内にある値のみを投稿します。ページに複数のフォームがある場合、他のフォームからのデータは送信されません。「アクティブな」フォームからのデータのみ。

データをラウンド トリップする場合、つまり、データを投稿してからフォームを返す場合、2 番目のフォームが投稿されたときに元のデータが含まれている場合 (同じビューであっても)、そのデータを保持する要素が必要です。新しい形で再掲します。隠しフィールドは、この目的でよく使用されます。

最後に、通常は、複数のフォームを 1 つのページにまとめるよりも、個別のビューを使用する方が適切です。これは可能で、状況によっては (ページに検索ボックスがある場合など) 意味がありますが、一般的には混乱を招きます。

于 2012-10-06T19:54:13.993 に答える