动态创建的表单将 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)的主要内容,如果未能解决你的问题,请参考以下文章
在 asp .NET MVC 中提交表单之前动态地将项目添加到列表中