动态创建的表单将 null 提交给控制器 (MVC)

Posted

技术标签:

【中文标题】动态创建的表单将 null 提交给控制器 (MVC)【英文标题】:Dynamically created forms submits null to controller (MVC) 【发布时间】:2017-07-26 19:24:05 【问题描述】:

在我看来,我在 for 中创建了多个表单,当我在提交时发送到控制器并且它为空时,问题就出现了。

这里是一个例子。

@model List<Project.ViewModels.ValidForm>
        @if (Model != null)
     
        for (int i = 0; i < Model.Count; i++)
        
            <div>
                @using (html.BeginForm("Method", "Controller", FormMethod.Post, new  id = "valForm" + @Model[i].Id ))
                
                    <div class="col-md-4">
                        <label>Data 1</label><br />
                        @Html.TextBoxFor(m => m[i].Data1, new  @class = "form-control" )
                    </div>
                    <div class="col-md-4">
                        <label>Data 2 options</label><br />
                        @Html.TextBoxFor(m => m[i].Data2.Option1, new  @class = "form-control" )
                    </div>
                    <div>
                        <button type="submit" class="btn btn-success">Save this form</button>
                    </div>

                
            </div>
        
    

还有视图模型。

public class ValidForm
    public int data1  get; set; 
    public Data2 data2 get;set;
 

public class Data2
 public int option1 get;set;
 public int option2 get;set;

和控制器。

[HttpPost]
public ActionResult validaciones(validform vm)
//do something.
    return view();

【问题讨论】:

您是否正在寻找带有提交按钮的单独表单?如果不是这样,您可以尝试将表单和提交按钮保持在循环之外并尝试发布它。在这种情况下,您必须将操作方法​​的参数更改为列表。 显示您期望的控制器和型号/VM。通常的罪魁祸首是当您发布的数据无法正确映射到您的预期对象时。 @RaviSankarRao 是的,我想用他的提交按钮分隔表单,实际上我只想提交列表中的一个对象。 @TravisActon 这是我正在尝试做的完整示例!,我可以得到对象,但他的所有变量都是空的 您一次只能提交一个表单,所以这没有任何意义,并且通过生成所有额外的 html 来降低性能并没有任何意义(更不用说用户我完成了一个或两个表单并按另一个上的提交按钮)。在带有链接的只读页面中显示集合,以重定向到编辑页面,或显示所选对象的对话框表单。 【参考方案1】:

您得到 null 的原因是您的模型是一个 ValidForm 数组,而不仅仅是一个。

将您的控制器更改为:

[HttpPost]
public ActionResult validaciones(ValidForm[] vms)
   ValidForm vm = ValidForm[0];
   //do something with vm.
    return view();

如果您一次只需要一个表单,您可以这样做:(我添加了 Name = "PropName",请注意 Name 中的大写 N)

那么你发布的动作应该是一个虚拟机

<div class="col-md-4">
  <label>Data 1</label><br />
  @Html.TextBoxFor(m => m[i].Data1, new  @class = "form-control", Name="Data1" )
</div>

对于 data2,名称需要是 Data2.option1,等等...

完整的工作示例:

家庭控制器:

    public class HomeController : Controller
    

        public class ValidForm
        
            public string Id  get; set; 
            public int data1  get; set; 
            public Data2 data2  get; set; 
        

        public class Data2
        
            public int option1  get; set; 
            public int option2  get; set; 
        


        public ActionResult Index()
        
            var model = new ValidForm[2]  new ValidForm  , new ValidForm data2 = new Data2 ;
            return PartialView(model);
        
        [HttpPost]
        public ActionResult Tester(ValidForm model)
        
            return View("Index", new ValidForm[1]  model );
        

查看:

@model MvcApplication1.Controllers.HomeController.ValidForm[]
@if (Model != null)
 
    for (int i = 0; i < Model.Count(); i++)
    
        <div>
            @using (Html.BeginForm("Tester", "Home", FormMethod.Post, new  id = "valForm" + @Model[i].Id ))
            
                <div class="col-md-4">
                    <label>Data 1</label><br />
                    @Html.TextBoxFor(m => m[i].data1, new  @class = "form-control", Name = "data1")
                </div>
                <div class="col-md-4">
                    <label>Data 2 options</label><br />
                    @Html.TextBoxFor(m => m[i].data2.option1, new  @class = "form-control", Name = "data2.option1")
                </div>
                <div>
                    <button type="submit" class="btn btn-success">Save this form</button>
                </div>

            
        </div>
    

还要注意输入框只能是数字,因为你有所有的整数。

【讨论】:

但是当我这样做时,我得到了我在视图上迭代的整个列表,我只想得到该列表的一个对象,这可能吗? @DanielUltramar 添加示例 我得到了对象但为空。当我赶上控制器时 public ActionResult validaciones(ValidForm vm) Name 属性应该相同,包括属性名称的大写字母,如果它们很复杂,您需要点,例如 Data2.Option1 @DanielUltramar 这只适用于第一种形式(默认情况下,集合索引器必须从零开始并且是连续的)

以上是关于动态创建的表单将 null 提交给控制器 (MVC)的主要内容,如果未能解决你的问题,请参考以下文章

带有模型数据的 MVC 5 路由

在 asp .NET MVC 中提交表单之前动态地将项目添加到列表中

ASP.NET MVC 表单提交多层子级实体集合数据到控制器中

带有 Jquery 模态形式的 asp.net MVC

Spring MVC 动态列表表单提交

Asp.net Mvc post表单提交多个实体模型