web-dev-qa-db-ja.com

MVC 4モデルのフォームの送信がコントローラーのpostメソッドでnullです

したがって、今の私の問題は、この次のフォームを送信すると、モデルをコントローラーに入れられないことです。 BillingCodes(BillingCodeObjectsのリスト)のアイテムをループして表示しようとしています。状況にあまり関係のないコードをいくつか削除して、短くて読みやすくしました。

これが私の見解のコードです...

@using (Html.BeginForm("SubmitTimesheet", "Timesheet", FormMethod.Post))
{


foreach (var item in Model.BillingCodes)
{

    <div class="button-padding">
        <a class="btn btn-large btn-danger btn-block billCodeBtn">
            <div class="btnText">@item.Name</div>
            <div class="btnTime">@item.TotalHours</div>

            <i class="icon-chevron-down billCodeIconUp billCodeIcon"></i>
            <i class="hidden icon-chevron-up billCodeIconDown billCodeIcon"></i>
        </a>

        <div class="content" >
            <div class="row timeEntry">
                <p></p>
                <div class="col-12 col-lg-2">
                    Enter Time: 
        <div class="row">
            <div class="col-12">
                @Html.DropDownListFor(model => item.EnterTimeHours, new SelectList(new[] {
                    new { Value = "0", Text = "0" },
                    new { Value = "1", Text = "1" },
                    new { Value = "2", Text = "2" },
                    new { Value = "3", Text = "3" },
                    new { Value = "4", Text = "4" },
                    new { Value = "5", Text = "5" },
                    new { Value = "6", Text = "6" },
                    new { Value = "7", Text = "7" },
                    new { Value = "8", Text = "8" },
                    new { Value = "9", Text = "9" },
                    new { Value = "10", Text = "10" },
                    new { Value = "11", Text = "11" },
                    new { Value = "12", Text = "12" },
                }, "Value", "Text")) <b>:</b> 
                @Html.DropDownListFor(model => item.EnterTimeMinutes, new SelectList(new[] {
                    new { Value = "0", Text = "00" },
                    new { Value = "15", Text = "15" },
                    new { Value = "30", Text = "30" },
                    new { Value = "45", Text = "45" },
                }, "Value", "Text"))

            </div>
        </div>
                </div>
                <div class="col-lg-2"></div>

                <div class="col-lg-1"></div>
                <div class="control-group col-12 col-lg-2">
                    <label class="checkbox">
                        Billable @Html.CheckBoxFor(model => item.Billable)
                    </label>
                </div>
                <div class="col-12 col-lg-2">
                    Enter Memo:
        <div class="row">
            <div class="col-12">
                @Html.TextAreaFor(model => item.Comment)
            </div>
        </div>

そして、これが私のコントローラーのコードです:

public class TimesheetController : Controller
{
    //
    // GET: /Timesheet/

    public ActionResult Index()
    {

        string getBillingCodeUrl ="";

      //SOME CODE REMOVED FOR LENGTH / READABILITY 

        foreach (var entryItem in timePeriod.TimeEntries[0].EntryCollection)
        {
            foreach (var billingItem in billingCodeList.BillingCodes)
            {
                if (entryItem.BillingCode == billingItem.Name)
                {
                    //update record in billingItem with data from entryItem
                    billingItem.Comment = entryItem.Comment;
                    billingItem.Billable = entryItem.Billable;
                    billingItem.TotalHours = entryItem.Hours;
                }
            }
        }

        return View(billingCodeList);
    }
    [HttpPost]
    public void SubmitTimesheet(BillingCodeList model)
    {

        string uri = "";

        foreach (var billingCode in model.BillingCodes)
        {
           //do stuff with each of these
        }
    }

}
}

そして最後に、これはモデルにある情報です:

    public class BillingCodeList
    {
        public List<BillingCodeObj> BillingCodes;
    }

    public class BillingCodeObj
    {
        public string Name { get; set; }
        public decimal TotalHours { get; set; }

        public decimal EnterTimeHours { get; set; }
        public decimal EnterTimeMinutes { get; set; }
        public bool Billable { get; set; }
        public string Comment { get; set; }

        public BillingCodeObj(string name, decimal hours)
        {
            this.Name = name;
            this.TotalHours = hours;
        }
        public BillingCodeObj()
        {

        }
    }

これは、フォームが返されたときのデバッグローカルの画像です。

地元のイメージ

9
Brandon Knight

ビューでforeachを実行しているので、入力要素には次のように値が投稿されているはずです:name="BillingCodes[0].EnterTimeHours"name="BillingCodes[0].EnterTimeMinutes"ネットワークタブでChromeデベロッパーツール(CTRL + SHIFT + C))のリクエストを検査するか、ソースを表示することができます。この場合、複数のBillingCodeObjオブジェクトを送信しています。それを受け取るコントローラーが必要です。

ソースコードを見てください。これは、舞台裏で何が起こっているかを理解するのに非常に役立ちます。

コントローラでこれを試してください:

[HttpPost]
public void SubmitTimesheet(IEnumerable<BillingCodeObj> billingCodes){
}

(デバッグ目的で)次のこともできます

public void SubmitTimesheet(FormCollection form){}

デバッグ時にどのように入力されるかフォームを検査します。

コメントと追加のコードが提供された後、ビューを次のように変更します。

@using (Html.BeginForm("SubmitTimesheet", "Timesheet", FormMethod.Post))
{
    @Html.EditorFor(m=>m.BillingCodes)
}

editorTemplates/BillingCodeObj.cshtmlに新しいcshtmlを作成します。

@model BillingCodeObj
<div class="button-padding">
    <a class="btn btn-large btn-danger btn-block billCodeBtn">
        <div class="btnText">@Model.Name</div>
        <div class="btnTime">@Model.TotalHours</div>

        <i class="icon-chevron-down billCodeIconUp billCodeIcon"></i>
        <i class="hidden icon-chevron-up billCodeIconDown billCodeIcon"></i>
    </a>

    <div class="content" >
        <div class="row timeEntry">
            <p></p>
            <div class="col-12 col-lg-2">
                Enter Time: 
    <div class="row">
        <div class="col-12">
            @Html.DropDownListFor(model => model.EnterTimeHours, new SelectList(new[] {
                new { Value = "0", Text = "0" },
                new { Value = "1", Text = "1" },
                new { Value = "2", Text = "2" },
                new { Value = "3", Text = "3" },
                new { Value = "4", Text = "4" },
                new { Value = "5", Text = "5" },
                new { Value = "6", Text = "6" },
                new { Value = "7", Text = "7" },
                new { Value = "8", Text = "8" },
                new { Value = "9", Text = "9" },
                new { Value = "10", Text = "10" },
                new { Value = "11", Text = "11" },
                new { Value = "12", Text = "12" },
            }, "Value", "Text")) <b>:</b> 
            @Html.DropDownListFor(model => model.EnterTimeMinutes, new SelectList(new[] {
                new { Value = "0", Text = "00" },
                new { Value = "15", Text = "15" },
                new { Value = "30", Text = "30" },
                new { Value = "45", Text = "45" },
            }, "Value", "Text"))

        </div>
    </div>
            </div>
            <div class="col-lg-2"></div>

            <div class="col-lg-1"></div>
            <div class="control-group col-12 col-lg-2">
                <label class="checkbox">
                    Billable @Html.CheckBoxFor(model => model.Billable)
                </label>
            </div>
            <div class="col-12 col-lg-2">
                Enter Memo:
    <div class="row">
        <div class="col-12">
            @Html.TextAreaFor(model => model.Comment)
        </div>
    </div>
7
Bart Calixto

ビューはBillingCodeListのタイプですが、送信しようとしていますList<BillingCodeObj>コントローラーでのアクション。

次のようにアクションを変更してください。

[HttpPost]
    public void SubmitTimesheet(BillingCodeList model)
    {

        string uri = "";

        foreach (var billingCode in model.BillingCodes)
        {
           //do stuff with each of these
        }
    }
0
Andriy Gubal

編集:モデルをビューに送る前に、BillingCodeListのリスト要素をnew List<BillingCode>()に初期化しているようではありません。それともあなたですか?

0
Rob G