MVC控制器传递多个Model到视图,使用ViewData, ViewBag, 部分视图, TempData, ViewModel, Tuple_mvc 多个model-CSDN博客 function getStudentTable() {
$('#studentsTable').empty();
$('#studentsTable').append("<table id='tblStudents'><tr><th>编号</th><th>姓名</th></tr></table>");
var students = @Html.Raw(Json.Encode(ViewData["Students"]));
for (var i = 0; i < students.length; i++) {
var courses = students[i].Courses;
for (var j = 0; j < courses.length; j++) {
if (courses[j].Name == selectedCourseName) {
$('#tblStudents').append("<tr><td>"+courses[j].Id+"</td><td>"+courses[j].Name+"</td></tr>");
}
}
}
}
</script>
</head>
<body>
<div>
<table>
<tr>
<td><h3>选择课程</h3></td>
<td>
<select id="sel">
<option>--选择课程--</option>
@foreach (var course in ViewData["Courses"] as List<Course>)
{
<option>@course.Name</option>
}
</select>
</td>
</tr>
</table>
</div>
<div id="teachers">
<h4>老师课程表</h4>
<div id="teachersTable"></div>
</div>
<div id="students">
<h4>学生上课表</h4>
<div id="studentsTable"></div>
</div>
</body>
</html>
@Html.Raw(Json.Encode(ViewData["Students"]))是把Model转换成json字符串,需要用到System.Web.Helpers,把此类库引用到项目,并且必须设置"复制到本地属性"为true,否则报错。
使用ViewBag传递多个Model
□ HomeController
public ActionResult ViewBagDemo()
{
ViewBag.Courses = _repository.GetCourses();
ViewBag.Students = _repository.GetStudents();
ViewBag.Teachers = _repository.GetTeachers();
return View();
}
□ Home/ViewBagDemo.cshtml
下拉框遍历课程改成:
@foreach (var course in ViewBag.Courses)
getTeacherTable()方法中改成:
var teachers = @Html.Raw(Json.Encode(ViewBag.Teachers));
getStudentTable()方法中改成:
var students = @Html.Raw(Json.Encode(ViewBag.Students));
使用部分视图传递多个Model
□ HomeController
public ActionResult PartialViewDemo()
{
List<Course> courses = _repository.GetCourses();
return View(courses);
}
public ActionResult StudentsToPVDemo(string courseName)
{
IEnumerable<Course> courses = _repository.GetCourses();
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Student> students = _repository.GetStudents();
var studentsInCourse = students.Where(s => s.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("StudentPV", studentsInCourse);
}
public ActionResult TeachersToPVDemo(string courseName)
{
IEnumerable<Course> courses = _repository.GetCourses();
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Teacher> teachers = _repository.GetTeachers();
var teachersForCourse = teachers.Where(t => t.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("TeacherPV", teachersForCourse);
}
□ Home/PartialViewDemo.cshmtl
@model IEnumerable<MvcApplication1.Models.Course>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>PatialViewDemo</title>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(function () {
//隐藏
$('#students').hide();
$('#teachers').hide();
//点击课程下拉框
$('#sel').change(function() {
selectedCourseName = $('#sel').val().trim();
if (selectedCourseName == "--选择课程--") {
$('#students').hide();
$('#teachers').hide();
} else {
getTeacherTable();
getStudentTable();
$('#students').show();
$('#teachers').show();
}
});
});
var selectedCourseName;
//创建老师课程表
function getTeacherTable() {
$.ajax({
url: "@Url.Action("TeachersToPVDemo","Home")",
type: 'Get',
data: { courseName: selectedCourseName },
success: function(data) {
$('#teachersTable').empty().append(data);
},
error: function() {
alert("sth wrong");
}
});
}
//创建学生上课表
function getStudentTable() {
$.ajax({
url: "@Url.Action("StudentsToPVDemo","Home")",
type: 'Get',
data: { courseName: selectedCourseName },
success: function (data) {
$('#studentsTable').empty().append(data);
},
error: function () {
alert("sth wrong");
}
});
}
</script>
</head>
<body>
<div>
<table>
<tr>
<td><h3>选择课程</h3></td>
<td>
<select id="sel">
<option>--选择课程--</option>
@foreach (var course in Model)
{
<option>@course.Name</option>
}
</select>
</td>
</tr>
</table>
</div>
<div id="teachers">
<h4>老师课程表</h4>
<div id="teachersTable"></div>
</div>
<div id="students">
<h4>学生上课表</h4>
<div id="studentsTable"></div>
</div>
</body>
</html>
□ TeacherPV.cshtml与StudentPV.cshtml
@model IEnumerable<MvcApplication1.Models.Teacher>
<table id="tblTeacherDetail">
<tr>
<th>编号</th>
<th>名称</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@item.Id</td>
<td>@item.Name</td>
</tr>
}
</table>
使用TempData传递多个Model
□ HomeController
public ActionResult TempDataDemo()
{
//第一次从数据库读取数据放到TempData中,以后的请求从TempData中获取数据
TempData["Courses"] = _repository.GetCourses();
//让TempData保存数据,直到下一次请求
TempData.Keep("Courses");
return View();
}
public ActionResult TeachersTempData(string courseName)
{
var courses = TempData["Courses"] as IEnumerable<Course>;
//由于TempData["Courses"]还要被下一次请求,继续TempData保存数据
TempData.Keep("Courses");
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Teacher> teachers = _repository.GetTeachers();
var teachersForCourse = teachers.Where(t => t.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("TeacherPV", teachersForCourse);
}
public ActionResult StudentsTempData(string courseName)
{
var courses = TempData["Courses"] as IEnumerable<Course>;
//由于TempData["Courses"]还要被下一次请求,继续TempData保存数据
TempData.Keep("Courses");
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Student> students = _repository.GetStudents();
var studentsForCourse = students.Where(s => s.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("StudentPV", studentsForCourse);
}
□ Home/TempDataDemo.cshtml
下拉框遍历课程:
@foreach (var course in Model)
ajax请求老师课程表:
@Url.Action("TeachersTempData","Home")
ajax请求学生上课表:
@Url.Action("StudentsTempData","Home")
使用ViewModel传递多个Model
□ View Model
public class SchoolVm
{
public List<Course> Courses { get; set; }
public List<Student> Students { get; set; }
public List<Teacher> Teachers { get; set; }
}
□ HomeController
public ActionResult ViewModelDemoVM()
{
SchoolVm vm = new SchoolVm();
vm.Courses = _repository.GetCourses();
vm.Teachers = _repository.GetTeachers();
vm.Students = _repository.GetStudents();
return View(vm);
}
□ Home/ViewModelDemoVM.cshtml
@model MvcApplication1.Models.SchoolVm
下拉框遍历课程:
@foreach (var course in Model.Courses)
ajax请求老师课程表和学生上课表:
@Html.Raw(Json.Encode(Model.Teachers))
@Html.Raw(Json.Encode(Model.Students))
使用Tuple传递多个Model
□ HomeController
public ActionResult TupleDemo()
{
var allModels = new Tuple<List<Course>, List<Teacher>, List<Student>>(_repository.GetCourses(),
_repository.GetTeachers(), _repository.GetStudents()) {};
return View(allModels);
}
□ Home/TupleDemo.cshtml
@model Tuple <List <MvcApplication1.Models.Course>, List <MvcApplication1.Models.Teacher>, List <MvcApplication1.Models.Student>>
下拉框遍历课程:
@foreach (var course in Model.Item1)
ajax请求老师课程表和学生上课表:
@Html.Raw(Json.Encode(Model.Item2))
@Html.Raw(Json.Encode(Model.Item3))
function getStudentTable() {
$('#studentsTable').empty();
$('#studentsTable').append("<table id='tblStudents'><tr><th>编号</th><th>姓名</th></tr></table>");
var students = @Html.Raw(Json.Encode(ViewData["Students"]));
for (var i = 0; i < students.length; i++) {
var courses = students[i].Courses;
for (var j = 0; j < courses.length; j++) {
if (courses[j].Name == selectedCourseName) {
$('#tblStudents').append("<tr><td>"+courses[j].Id+"</td><td>"+courses[j].Name+"</td></tr>");
}
}
}
}
</script>
</head>
<body>
<div>
<table>
<tr>
<td><h3>选择课程</h3></td>
<td>
<select id="sel">
<option>--选择课程--</option>
@foreach (var course in ViewData["Courses"] as List<Course>)
{
<option>@course.Name</option>
}
</select>
</td>
</tr>
</table>
</div>
<div id="teachers">
<h4>老师课程表</h4>
<div id="teachersTable"></div>
</div>
<div id="students">
<h4>学生上课表</h4>
<div id="studentsTable"></div>
</div>
</body>
</html>
@Html.Raw(Json.Encode(ViewData["Students"]))是把Model转换成json字符串,需要用到System.Web.Helpers,把此类库引用到项目,并且必须设置"复制到本地属性"为true,否则报错。
使用ViewBag传递多个Model
□ HomeController
public ActionResult ViewBagDemo()
{
ViewBag.Courses = _repository.GetCourses();
ViewBag.Students = _repository.GetStudents();
ViewBag.Teachers = _repository.GetTeachers();
return View();
}
□ Home/ViewBagDemo.cshtml
下拉框遍历课程改成:
@foreach (var course in ViewBag.Courses)
getTeacherTable()方法中改成:
var teachers = @Html.Raw(Json.Encode(ViewBag.Teachers));
getStudentTable()方法中改成:
var students = @Html.Raw(Json.Encode(ViewBag.Students));
使用部分视图传递多个Model
□ HomeController
public ActionResult PartialViewDemo()
{
List<Course> courses = _repository.GetCourses();
return View(courses);
}
public ActionResult StudentsToPVDemo(string courseName)
{
IEnumerable<Course> courses = _repository.GetCourses();
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Student> students = _repository.GetStudents();
var studentsInCourse = students.Where(s => s.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("StudentPV", studentsInCourse);
}
public ActionResult TeachersToPVDemo(string courseName)
{
IEnumerable<Course> courses = _repository.GetCourses();
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Teacher> teachers = _repository.GetTeachers();
var teachersForCourse = teachers.Where(t => t.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("TeacherPV", teachersForCourse);
}
□ Home/PartialViewDemo.cshmtl
@model IEnumerable<MvcApplication1.Models.Course>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>PatialViewDemo</title>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(function () {
//隐藏
$('#students').hide();
$('#teachers').hide();
//点击课程下拉框
$('#sel').change(function() {
selectedCourseName = $('#sel').val().trim();
if (selectedCourseName == "--选择课程--") {
$('#students').hide();
$('#teachers').hide();
} else {
getTeacherTable();
getStudentTable();
$('#students').show();
$('#teachers').show();
}
});
});
var selectedCourseName;
//创建老师课程表
function getTeacherTable() {
$.ajax({
url: "@Url.Action("TeachersToPVDemo","Home")",
type: 'Get',
data: { courseName: selectedCourseName },
success: function(data) {
$('#teachersTable').empty().append(data);
},
error: function() {
alert("sth wrong");
}
});
}
//创建学生上课表
function getStudentTable() {
$.ajax({
url: "@Url.Action("StudentsToPVDemo","Home")",
type: 'Get',
data: { courseName: selectedCourseName },
success: function (data) {
$('#studentsTable').empty().append(data);
},
error: function () {
alert("sth wrong");
}
});
}
</script>
</head>
<body>
<div>
<table>
<tr>
<td><h3>选择课程</h3></td>
<td>
<select id="sel">
<option>--选择课程--</option>
@foreach (var course in Model)
{
<option>@course.Name</option>
}
</select>
</td>
</tr>
</table>
</div>
<div id="teachers">
<h4>老师课程表</h4>
<div id="teachersTable"></div>
</div>
<div id="students">
<h4>学生上课表</h4>
<div id="studentsTable"></div>
</div>
</body>
</html>
□ TeacherPV.cshtml与StudentPV.cshtml
@model IEnumerable<MvcApplication1.Models.Teacher>
<table id="tblTeacherDetail">
<tr>
<th>编号</th>
<th>名称</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@item.Id</td>
<td>@item.Name</td>
</tr>
}
</table>
使用TempData传递多个Model
□ HomeController
public ActionResult TempDataDemo()
{
//第一次从数据库读取数据放到TempData中,以后的请求从TempData中获取数据
TempData["Courses"] = _repository.GetCourses();
//让TempData保存数据,直到下一次请求
TempData.Keep("Courses");
return View();
}
public ActionResult TeachersTempData(string courseName)
{
var courses = TempData["Courses"] as IEnumerable<Course>;
//由于TempData["Courses"]还要被下一次请求,继续TempData保存数据
TempData.Keep("Courses");
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Teacher> teachers = _repository.GetTeachers();
var teachersForCourse = teachers.Where(t => t.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("TeacherPV", teachersForCourse);
}
public ActionResult StudentsTempData(string courseName)
{
var courses = TempData["Courses"] as IEnumerable<Course>;
//由于TempData["Courses"]还要被下一次请求,继续TempData保存数据
TempData.Keep("Courses");
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Student> students = _repository.GetStudents();
var studentsForCourse = students.Where(s => s.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("StudentPV", studentsForCourse);
}
□ Home/TempDataDemo.cshtml
下拉框遍历课程:
@foreach (var course in Model)
ajax请求老师课程表:
@Url.Action("TeachersTempData","Home")
ajax请求学生上课表:
@Url.Action("StudentsTempData","Home")
使用ViewModel传递多个Model
□ View Model
public class SchoolVm
{
public List<Course> Courses { get; set; }
public List<Student> Students { get; set; }
public List<Teacher> Teachers { get; set; }
}
□ HomeController
public ActionResult ViewModelDemoVM()
{
SchoolVm vm = new SchoolVm();
vm.Courses = _repository.GetCourses();
vm.Teachers = _repository.GetTeachers();
vm.Students = _repository.GetStudents();
return View(vm);
}
□ Home/ViewModelDemoVM.cshtml
@model MvcApplication1.Models.SchoolVm
下拉框遍历课程:
@foreach (var course in Model.Courses)
ajax请求老师课程表和学生上课表:
@Html.Raw(Json.Encode(Model.Teachers))
@Html.Raw(Json.Encode(Model.Students))
使用Tuple传递多个Model
□ HomeController
public ActionResult TupleDemo()
{
var allModels = new Tuple<List<Course>, List<Teacher>, List<Student>>(_repository.GetCourses(),
_repository.GetTeachers(), _repository.GetStudents()) {};
return View(allModels);
}
□ Home/TupleDemo.cshtml
@model Tuple <List <MvcApplication1.Models.Course>, List <MvcApplication1.Models.Teacher>, List <MvcApplication1.Models.Student>>
下拉框遍历课程:
@foreach (var course in Model.Item1)
ajax请求老师课程表和学生上课表:
@Html.Raw(Json.Encode(Model.Item2))
@Html.Raw(Json.Encode(Model.Item3))
MVC控制器传递多个Model到视图,使用ViewData, ViewBag, 部分视图, TempData, ViewModel, Tuple
MVC控制器传递多个Model到视图,使用ViewData, ViewBag, 部分视图, TempData, ViewModel, Tuple
如果能将 模型和表格 绑定到一块,类似 ASP.NET WebForms 中的用户控件(UserControl),然后在主视图中引入这些绑定好的块岂不是很好?
其实ASP.NET MVC中有类似的解决方法,只不过不叫用户控件,而称为分部视图(PartialView),下面我们就用分部视图来实现上述功能。
1. 模型类(Student)上面已经介绍过了
2. 控制器,返回包含两个对象元组对象
public IActionResult Index() { var students = StudentHelper.GetSimpleStudentList(); var model = new Tuple<IEnumerable<Student>, IEnumerable<Student>>(students.Where(m => m.AtSchool), students.Where(m => !m.AtSchool)); return View(model); }
3. 主视图
@{ var F = Html.F(); } @using FineUICore.Examples.Areas.DataModel.Models; @model Tuple<IEnumerable<Student>, IEnumerable<Student>> @section body { @(Html.Partial("PartialGrid", Model.Item1, new ViewDataDictionary(ViewData) { { "__Title", "表格一(在校生)" } })) <br /> @(Html.Partial("PartialGrid", Model.Item2, new ViewDataDictionary(ViewData) { { "__Title", "表格一(毕业生)" } })) }
注意一下几点:
3.1 模型类型是:Tuple<IEnumerable<Student>, IEnumerable<Student>>
3.2 在视图中可以通过 Model.Item1 获取元组中的第一个对象,相应的 Model.Item2 获取第二个对象,从而省去了自定义类的麻烦
3.3 使用 Html.Partial 来渲染一个分部视图,传入三个参数:
----1. 分部视图的名称,会先在主视图所在目录中检索,如果找不到会转到 Shared 目录检索
----2. 传入分部视图的模型
----3. 额外的ViewData对象,如果需要引入多个分部视图,可以在为每个分部视图自定义显示数据
---------------------------------------------------------------------------------------------------------------------------------
方法二
public class CombinedViewModel
{
public ModelA ModelA { get; set; }
public ModelB ModelB { get; set; }
}
然后,在控制器中创建 CombinedViewModel 的实例,并将数据填充到它的两个模型属性中,最后将其传递给视图:
public ActionResult Index()
{
var modelA = new ModelA();
var modelB = new ModelB();
// 假设这里填充了数据
var viewModel = new CombinedViewModel
{
ModelA = modelA,
ModelB = modelB
};
return View(viewModel);
}
最后,在视图中,你可以使用 Model 来访问 CombinedViewModel 的属性:
@model CombinedViewModel
<!-- 使用 Model.ModelA 和 Model.ModelB 来显示和绑定数据 -->
这样,你就可以在同一个视图中绑定和显示多个模型的数据了。
------------------------------------------------------------------------------------
文心一言给出的 ASP.NET MVC 视图中绑定多个模型 答案 :
在ASP.NET MVC中,视图通常与一个单独的模型绑定。然而,有时你可能需要在视图中处理多个模型的数据。有几种方法可以实现这一点:
### 方法一:使用ViewModel
最常见和推荐的方法是创建一个包含多个模型属性的ViewModel类。然后在视图中绑定这个ViewModel。
1. **创建ViewModel类**
```csharp
public class MyViewModel
{
public ModelA ModelA { get; set; }
public ModelB ModelB { get; set; }
}
```
2. **在控制器中准备数据**
```csharp
public class MyController : Controller
{
public ActionResult MyAction()
{
var modelA = new ModelA { /* 初始化ModelA的属性 */ };
var modelB = new ModelB { /* 初始化ModelB的属性 */ };
var viewModel = new MyViewModel { ModelA = modelA, ModelB = modelB };
return View(viewModel);
}
}
```
3. **在视图中使用ViewModel**
```html
@model MyNamespace.Models.MyViewModel
<div>
<h2>Model A Data</h2>
<p>@Model.ModelA.SomeProperty</p>
<!-- 其他ModelA的属性 -->
</div>
<div>
<h2>Model B Data</h2>
<p>@Model.ModelB.SomeOtherProperty</p>
<!-- 其他ModelB的属性 -->
</div>
```
### 方法二:使用Tuple(不推荐)
虽然可以使用`Tuple`来传递多个模型,但这通常不是最佳实践,因为它降低了代码的可读性和可维护性。
1. **在控制器中准备数据**
```csharp
public ActionResult MyAction()
{
var modelA = new ModelA { /* 初始化ModelA的属性 */ };
var modelB = new ModelB { /* 初始化ModelB的属性 */ };
var tuple = Tuple.Create(modelA, modelB);
return View(tuple);
}
```
2. **在视图中使用Tuple**
```html
@model Tuple<MyNamespace.Models.ModelA, MyNamespace.Models.ModelB>
<div>
<h2>Model A Data</h2>
<p>@Model.Item1.SomeProperty</p>
<!-- 其他ModelA的属性 -->
</div>
<div>
<h2>Model B Data</h2>
<p>@Model.Item2.SomeOtherProperty</p>
<!-- 其他ModelB的属性 -->
</div>
```
### 方法三:使用ViewData或ViewBag(不推荐)
你也可以使用`ViewData`或`ViewBag`来传递多个模型,但这通常也不如ViewModel方法清晰和类型安全。
1. **在控制器中准备数据**
```csharp
public ActionResult MyAction()
{
var modelA = new ModelA { /* 初始化ModelA的属性 */ };
var modelB = new ModelB { /* 初始化ModelB的属性 */ };
ViewData["ModelA"] = modelA;
ViewData["ModelB"] = modelB;
return View();
}
```
2. **在视图中使用ViewData**
```html
<div>
<h2>Model A Data</h2>
<p>@ViewData["ModelA"].SomeProperty</p>
<!-- 其他ModelA的属性 -->
</div>
<div>
<h2>Model B Data</h2>
<p>@ViewData["ModelB"].SomeOtherProperty</p>
<!-- 其他ModelB的属性 -->
</div>
```
### 总结
推荐使用ViewModel方法,因为它提供了类型安全、可读性和可维护性。其他方法虽然也可以实现功能,但在大多数情况下不如ViewModel方法好。
------------------------------------------------------------------------------------------------------