[英]ASP.NET MVC 5 : Binding all the partial views to the main controller
我正在使用ASP.NET MVC 5开发Web应用程序。我有多个局部视图及其对应的模型,但是只有一个与主视图相对应的控制器,该控制器使用以下代码显示每个局部视图。
@{Html.RenderPartial("PartialViewName");}
我的问题是,如何将表单数据从所有局部视图(包括主视图)传递到主控制器?
最初,当我仅添加1个局部视图时,将其模型作为参数添加到主控制器的public ActionResult Index(MainModelName model1, PartialModelName pmodel1)
。 并且工作正常,我可以从主控制器的局部视图访问数据。
但是,当我添加第二个局部视图并用附加的局部模型参数更新public ActionResult Index(...)
时,它没有帮助,因为数据没有从局部视图传递到主控制器。 虽然我没有任何错误。
我的主模型类将部分模型的对象引用作为其数据成员。 从我的阅读中,我需要有一个模型列表作为主控制器中方法的参数,但是我的模型不是子类型。
处理这种情况的惯用方式是什么?
谢谢!
EDIT1:这是示例应用程序的代码,在MainController.cs中访问mainModel.PartialModel2.Pm2
时出现空引用错误,而我可以正确访问mainModel.PartialModel1.Pm1
。
MainModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class MainModel
{
private int mm1;
private PartialModel1 partialModel1;
private PartialModel2 partialModel2;
public int Mm1 { get => mm1; set => mm1 = value; }
public PartialModel1 PartialModel1 { get => partialModel1; set => partialModel1 = value; }
public PartialModel2 PartialModel2 { get => partialModel2; set => partialModel2 = value; }
}
}
PartialModel1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class PartialModel1
{
private int pm1;
public PartialModel1()
{
}
public int Pm1 { get => pm1; set => pm1 = value; }
}
}
PartialModel2.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class PartialModel2
{
private int pm2;
public PartialModel2()
{
}
public int Pm2 { get => pm2; set => pm2 = value; }
}
}
Index.cshtml
@model TestApp.Models.MainModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MainModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Mm1, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Mm1, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Mm1, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@{ Html.RenderPartial("Partial1", Model); }
@{ Html.RenderPartial("Partial2", Model); }
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
@*<div>
@Html.ActionLink("Back to List", "Index")
</div>*@
</body>
</html>
Partial1.cshtml
@model TestApp.Models.MainModel
@using (Html.BeginForm("MainModel"))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>PartialModel1</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.PartialModel1.Pm1, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PartialModel1.Pm1, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PartialModel1.Pm1, "", new { @class = "text-danger" })
</div>
</div>
@*<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>*@
</div>
}
@*<div>
@Html.ActionLink("Back to List", "Index")
</div>*@
Partial2.cshtml
@model TestApp.Models.MainModel
@using (Html.BeginForm("MainModel"))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>PartialModel2</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.PartialModel2.Pm2, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PartialModel2.Pm2, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PartialModel2.Pm2, "", new { @class = "text-danger" })
</div>
</div>
@*<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>*@
</div>
}
@*<div>
@Html.ActionLink("Back to List", "Index")
</div>*@
MainController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestApp.Models;
namespace TestApp.Controllers
{
public class MainController : Controller
{
// GET: Main
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(MainModel mainModel)
{
//Access mainModel.PartialModel1.Pm1
//Access mainModel.PartialModel2.Pm2
string msg = mainModel.PartialModel1.Pm1 + " " + mainModel.PartialModel2.Pm2;
ViewBag.message = msg;
return View("Success");
}
}
}
编辑2:如果我只保留它@{ Html.RenderPartial("Partial2"); }
@{ Html.RenderPartial("Partial2"); }
,我得到这个错误- The model item passed into the dictionary is of type 'TestApp.Models.Main', but this dictionary requires a model item of type 'TestApp.Models.Partial2'.
MainController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestApp.Models;
namespace TestApp.Controllers
{
public class MainController : Controller
{
// GET: Main
[HttpGet]
public ActionResult Index()
{
return View(new Main() { Partial1 = new Partial1(), Partial2 = new Partial2() });
}
[HttpPost]
public ActionResult Index(Main mainModel)
{
//Access mainModel.PartialModel1.Pm1
//Access mainModel.PartialModel2.Pm2
string msg = mainModel.Partial1.Pm1 + " " + mainModel.Partial2.Pm2;
ViewBag.message = msg;
return View("Success");
}
}
}
Main.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class Main
{
public int Mm1 { get; set; }
public Partial1 Partial1 { get; set; }
public Partial2 Partial2 { get; set; }
}
}
Partial1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class Partial1
{
public Partial1()
{
}
public int Pm1 { get; set; }
}
}
Partial2.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestApp.Models
{
public class Partial2
{
public Partial2()
{
}
public int Pm2 { get; set; }
}
}
Index.cshtml
@model TestApp.Models.Main
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>MainModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Mm1, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Mm1, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Mm1, "", new { @class = "text-danger" })
</div>
</div>
@{ Html.RenderPartial("Partial2"); }
@{ Html.RenderPartial("Partial1"); }
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
@*<div>
@Html.ActionLink("Back to List", "Index")
</div>*@
</body>
</html>
Partial1.cshtml
@model TestApp.Models.Partial1
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>PartialModel1</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Pm1, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Pm1, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Pm1, "", new { @class = "text-danger" })
</div>
</div>
</div>
@*<div>
@Html.ActionLink("Back to List", "Index")
</div>*@
Partial2.cshtml
@model TestApp.Models.Partial2
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>PartialModel2</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Pm2, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Pm2, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Pm2, "", new { @class = "text-danger" })
</div>
</div>
</div>
@*<div>
@Html.ActionLink("Back to List", "Index")
</div>*@
您可以更改代码:
public ActionResult Index(MainModelName model1, PartialModelName pmodel1)
至
public ActionResult Index(NewMainModelName newModel)
在类NewMainModelName中,您可以像这样醒来:
public class NewMainModelName
{
public MainModelName model1 { get; set; }
public PartialModelName pmodel1{ get; set; }
}
这里有一堆东西你应该改变。 对于初学者,您不需要使用正在使用的getter形式。
代替
private int pm1;
public int Pm1 { get => pm1; set => pm1 = value; }
您只需要具备以下功能:
public int Pm1 { get; set; }
您不需要私有后备变量。
如果要实际提供执行某些操作的方法,则只需要填充get和set方法即可。
其次,您需要实例化PartialModel的。 在这种情况下,这无关紧要,因为您不引用任何实际数据,仅引用元数据..但是,一旦添加实数据,它可能会引起问题。
[HttpGet]
public ActionResult Index()
{
return View(new MainModel() { PartialModel1 = new PartialModel1(), PartialModel2 = new PartialModel2 });
}
接下来,我不确定您要如何完成此任务,但可能不是您认为的那样:
@using (Html.BeginForm("MainModel"))
您在这里拥有的是嵌套表单,而这不是合法的HTML。
相反,您应该从部分表格中删除表单,即使这是合法的,然后表单也只会提交该表单中的数据。 这是您的主要问题。
另外,删除部分中的提交按钮。 只需在Index.cshtml中有一个总体表单并提交按钮即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.