C# 在 MVC 4 模型中提交表单在控制器 post 方法中为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18235846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:36:37  来源:igfitidea点击:

Submitting Form in MVC 4 model is null in controller post method

c#asp.net-mvcformsasp.net-mvc-4razor

提问by Brandon Knight

So my problem right now is that I cant get my model into my controller when I submit this following form. I am trying to have the items from the BillingCodes (which is a list of BillingCodeObjects) loop through and display. I have removed some code from these that isn't really relevant to the situation to make it shorter and easier to read.

所以我现在的问题是,当我提交以下表单时,我无法将模型放入我的控制器中。我试图让 BillingCodes(这是 BillingCodeObjects 列表)中的项目循环并显示。我已经从这些中删除了一些与情况无关的代码,以使其更短且更易于阅读。

Here is the code for my view...

这是我的观点的代码......

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

And here is some code for my controller:

这是我的控制器的一些代码:

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

}
}

and lastly, here is the info that is in the model:

最后,这是模型中的信息:

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

        }
    }

here is a picture of the debug locals when the form is returned..

这是返回表单时调试本地人的图片..

image of locals

当地人的形象

采纳答案by Bart Calixto

You are doing a foreach on the views, so the input elements should have the values posted somewhere like to this : name="BillingCodes[0].EnterTimeHours", name="BillingCodes[0].EnterTimeMinutes"you can inspect in the network tab the request on Chrome Developer Tools (CTRL+SHIFT+C) or just viewing the source. If this is the case, you are submitting multiple BillingCodeObj objects. You must have a controller that receive that.

您正在对视图执行 foreach,因此输入元素应该将值张贴在类似这样的地方 : name="BillingCodes[0].EnterTimeHours"name="BillingCodes[0].EnterTimeMinutes"您可以在网络选项卡中检查 Chrome 开发人员工具 (CTRL+SHIFT+C) 上的请求或仅查看源代码。如果是这种情况,您将提交多个 BillingCodeObj 对象。你必须有一个接收它的控制器。

Take a look at the source code as this can greatly help you understand what's going on behind the scenes.

查看源代码,因为这可以极大地帮助您了解幕后发生的事情。

Try this on your controller:

在您的控制器上试试这个:

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

You can also (for debugging purposes) do

您也可以(出于调试目的)执行

public void SubmitTimesheet(FormCollection form){}

and inspect the form how is populated on debug.

并检查表单如何在调试时填充。

after comments and more code provided change your view to :

在提供评论和更多代码后,将您的视图更改为:

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

create a new cshtml in EditorTemplates/BillingCodeObj.cshtml :

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

回答by Andriy Gubal

Your View is type of BillingCodeList, but you are trying to send List<BillingCodeObj>to you action in controller.

您的 View 是 类型BillingCodeList,但您正试图List<BillingCodeObj>在控制器中向您发送操作。

Try to change action as follows:

尝试改变动作如下:

[HttpPost]
    public void SubmitTimesheet(BillingCodeList model)
    {

        string uri = "";

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

回答by Rob G

edit: It doesn't seem that you're initializing your BillingCodeList's list element to a new List<BillingCode>()before you send the model off to the view. Or are you?

编辑:new List<BillingCode>()在将模型发送到视图之前,您似乎没有将 BillingCodeList 的列表元素初始化为 a 。还是你?