web-dev-qa-db-fra.com

La soumission du formulaire dans le modèle MVC 4 est nulle dans la méthode de publication du contrôleur

Mon problème actuel est que je ne peux pas insérer mon modèle dans mon contrôleur lorsque je soumets ce formulaire. J'essaie d'avoir les éléments de BillingCodes (qui est une liste de BillingCodeObjects) en boucle et en affichage. J'y ai enlevé du code qui ne correspond pas vraiment à la situation pour le rendre plus court et plus facile à lire.

Voici le code pour ma vue ...

@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>

Et voici un code pour mon contrôleur:

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
        }
    }

}
}

et enfin, voici l'info qui se trouve dans le modèle:

    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()
        {

        }
    }

voici une image des sections locales de débogage lorsque le formulaire est renvoyé.

image des habitants

8
Brandon Knight

Vous faites un foreach sur les vues. Par conséquent, les éléments d'entrée doivent avoir les valeurs suivantes: name="BillingCodes[0].EnterTimeHours", name="BillingCodes[0].EnterTimeMinutes" vous pouvez consulter la demande dans l'onglet Réseau des outils de développement Chrome (CTRL + MAJ + C ) ou juste en regardant la source. Si tel est le cas, vous soumettez plusieurs objets BillingCodeObj. Vous devez avoir un contrôleur qui reçoit cela.

Jetez un coup d'œil au code source, car cela peut vous aider grandement à comprendre ce qui se passe dans les coulisses.

Essayez ceci sur votre contrôleur:

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

Vous pouvez aussi (à des fins de débogage) faire 

public void SubmitTimesheet(FormCollection form){}

et inspectez le formulaire comment est rempli lors du débogage.

après les commentaires et plus de code fourni changez votre vue pour:

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

créez un nouveau cshtml dans EditorTemplates/BillingCodeObj.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>
6
Bart Calixto

Votre vue est du type BillingCodeList, mais vous essayez d’envoyer List<BillingCodeObj> à votre action dans le contrôleur.

Essayez de changer les actions comme suit:

[HttpPost]
    public void SubmitTimesheet(BillingCodeList model)
    {

        string uri = "";

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

edit: Il ne semble pas que vous initialisiez l'élément de liste de votre BillingCodeList à une new List<BillingCode>() avant d'envoyer le modèle à la vue. Ou es-tu?

0
Rob G