ASP.NET Core 5 MVC 使用带枚举的视图模型
ASP.NET Core 5 MVC Using View Models with enumeration
我有2个模型; TypeOne
和 Project_Screen
。我需要一个视图,使 2 tables 具有来自这两个 tables 的信息。我尝试使用本指南来制作一个视图模型,它有所帮助,但与我做的事情并不完全相同:https://dotnettutorials.net/lesson/view-model-asp-net-core-mvc/
这是我制作的视图模型:
public class MyProjectsViewModel
{
public Project_Screen Project_Screen { get; set; }
public TypeOne TypeOne { get; set; }
}
这是控制器:
public class ProfileController : Controller
{
private readonly Natural_ResourcesContext _context;
public ProfileController(Natural_ResourcesContext context)
{
_context = context;
}
// GET: Profile
public ActionResult Index()
{
Project_Screen project_Screen = (Project_Screen)(from s in _context.Project_Screen
where s.DSN_PM == User.Identity.Name
select s);
TypeOne typeOne = (TypeOne)(from x in _context.TypeOne
where x.Name == User.Identity.Name
select x);
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
return View(myProjectsViewModel);
}
}
可以看到,project_Screen
和typeOne
都是Manager = Name
.
的记录
然后在视图中我想显示如下内容:
@model EnvApp.ViewModels.MyProjectsViewModel
@{
ViewData["Title"] = "Projects";
}
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
<td>
@Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
<td>
@Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
我在 ````Model``` 上收到编译器错误 CS1579:
foreach statement cannot operate on variables of type 'MyProjectsViewModel' because 'MyProjectsViewModel' does not contain a public instance or extension definition for 'GetEnumorator'
我认为这是有道理的,因为我没有将 Project_Screen
或 TypeOne
表示为一个包含多条记录的对象,但我不太确定该怎么做。
我是在正确的轨道上还是我误解了这一点?我错过了什么?
编辑 1:
我完全按照 Md Farid Uddin Kiron 所说的进行操作,因此他的回答中的代码反映了我的视图模型和视图。但是我的控制器仍然有问题。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using EnvApp.ViewModels;
using EnvApp.Models.DB;
namespace EnvApp.Controllers
{
public class ProfileController : Controller
{
private readonly Natural_ResourcesContext _context;
public ProfileController(Natural_ResourcesContext context)
{
_context = context;
}
// GET: Profile
public ActionResult Index()
{
Project_Screen project_Screen = (Project_Screen)(from s in _context.Project_Screen
where s.DSN_PM == User.Identity.Name
select s);
TypeOne typeOne = (TypeOne)(from x in _context.TypeOne
where x.Name == User.Identity.Name
select x);
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
return View(myProjectsViewModel);
}
}
}
问题是 project_Screen
和 typeOne
不是列表或 IEnumerable 类型,这是有道理的,但我不是使它们可枚举的语法。
如果您需要查看,这是我的视图模型:
public class MyProjectsViewModel
{
public List<Project_Screen> Project_Screen { get; set; }
public List<TypeOne> TypeOne { get; set; }
}
这是视图:
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Project_Screen)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
<td>
@Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.TypeOne)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
<td>
@Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
同样,问题是 project_Screen
和 typeOne
不是控制器中的列表或 IEnumerable 类型。它们实际上是列表,除了控制器之外无处不在,但它们必须是。错误在行
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
在 project_Screen
和 typeOne
上读取
cannot implicitly convert type Envapp.Models.DB.Project_Screen to System.Collection.Generic.List<Envapp.Models.DB.Project_Screen>
这似乎正在发生,因为那里的代码试图指向 Project_Screen 的数据库模型 table,而不是 Project_Screen 模型中项目的 ViewModel 表示。我该如何解决这个问题?
编辑 2:
我不确定它是什么,但我的代码中的某些内容似乎真的让人们感到困惑。我发布了我所有的模型以供澄清:
Project_Screen.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
#nullable disable
namespace EnvApp.Models.DB
{
public partial class Project_Screen
{
[Key]
public long ID { get; set; }
public string State_Project_Number { get; set; }
public string? Federal_Project_Number { get; set; }
public string Project_Name { get; set; }
public string County { get; set; }
public DateTime? Memo_Date { get; set; }
public string From { get; set; }
public string? Authorization { get; set; }
public string DSN_PM { get; set; }
public string? History { get; set; }
public string History_PM { get; set; }
public bool Review_Exempt_H { get; set; }
public bool SHPO_Approval_H { get; set; }
public string? Archaeology { get; set; }
public string Archaeology_PM { get; set; }
public bool Review_Exempt_A { get; set; }
public bool SHPO_Approval_A { get; set; }
public bool ESA_Key { get; set; }
public bool Crayfish { get; set; }
public bool Crayfish_Habitat_Assessment { get; set; }
public bool NLEB_4D { get; set; }
public bool USFWS { get; set; }
public string USFWS_Type { get; set; }
public bool Mussel_Habitat { get; set; }
public bool Mussel_Stream { get; set; }
public string Within_Airport { get; set; }
public string? ToPo_Quad_Name { get; set; }
public bool Bat_Habitat { get; set; }
public string? Bars { get; set; }
public string Coordinates { get; set; }
public string? Natural_Resources_Notes { get; set; }
public string Adduser { get; set; }
public DateTime? Date_Added { get; set; }
public string Crayfish_Notes { get; set; }
public string Mussel_Notes { get; set; }
}
}
TypeOne.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace EnvApp.Models.DB
{
[Table("Type_One")]
public partial class TypeOne
{
[Key]
public long ID { get; set; }
[MaxLength(50)]
public string State_Project_Number { get; set; }
[MaxLength(50)]
public string Federal_Project_Number { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(50)]
public string Route_Number { get; set; }
public string County { get; set; }
[MaxLength(50)]
public string Work_Type { get; set; }
[MaxLength(100)]
public string Coordinates { get; set; }
public string Project_Description { get; set; }
public bool? Federal_Aid { get; set; }
public bool? Minimal_Project_Verification { get; set; }
[MaxLength(3)]
public string CE_Category { get; set; }
[MaxLength(10)]
public string Amms { get; set; }
public bool Activities_Agreement { get; set; }
public string Arch_RE { get; set; }
public string Hist_RE { get; set; }
public DateTime? Arch_RE_Date { get; set; }
public DateTime? Hist_RE_Date { get; set; }
public bool? Through_Lanes { get; set; }
public bool? Close_Road { get; set; }
public bool? ROW_Acquisition { get; set; }
public bool? Access_Control { get; set; }
public bool? Fifty_Year_Structure { get; set; }
public bool? Agency_Coordination { get; set; }
public bool? IPAC_Screening_Zone { get; set; }
public bool? Section_404_Permit { get; set; }
public bool? Ground_Disturbance { get; set; }
public bool? Waterway { get; set; }
public bool? Special_Use_Permit { get; set; }
public bool? Floodplain { get; set; }
public string Prepared_By { get; set; }
public string Approved_By { get; set; }
public string Adduser { get; set; }
public DateTime? Date_Added { get; set; }
}
}
Natural_ResourcesContext
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
#nullable disable
namespace EnvApp.Models.DB
{
public partial class Natural_ResourcesContext : DbContext
{
public Natural_ResourcesContext()
{
}
public Natural_ResourcesContext(DbContextOptions<Natural_ResourcesContext> options)
: base(options)
{
}
public virtual DbSet<NR_User> NR_Users { get; set; }
public virtual DbSet<Project_Screen> Project_Screen { get; set; }
public virtual DbSet<TypeOne> TypeOne { get; set; }
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
该错误是因为您在视图模型本身而不是您要枚举的属性上使用 foreach。
对于Project_Screen和TypeOne,将它们声明为可枚举类型(例如Array、List、IEnumerable等)。
public class MyProjectsViewModel
{
public IEnumerable<Project_Screen> Project_Screen { get; set; }
public IEnumerable<TypeOne> TypeOne { get; set; }
}
您将需要使用来自控制器的一组值来填充它们
var viewModel = new MyProjectsViewModel();
viewModel.Project_Screen = _context.Project_Screen.Where(x => SOME_CONDITION);
viewModel.TypeOne = _context.TypeOne.Where(x => SOME_CONDITION);
在视图中,您将枚举这些属性(而不是模型本身)。
@foreach (var item in Model.Project_Screen)
和
@foreach (var item in Model.TypeOne)
你已经足够接近了。从我们了解到的视图迭代中,您的 Project_Screen
和 Type_One
似乎应该是 class 的列表。如果是这样,那么你的 MyProjectsViewModel
应该是这样的:
View Model:
public class MyProjectsViewModel
{
public List<Project_Screen> ProjectScreen { get; set; }
public List<Type_One> TypeOne { get; set; }
}
Controller:
public ActionResult ViewModelEnumeration()
{
var proScreen = new List<Project_Screen>()
{
new Project_Screen(){ State_Project_Number = 1,Federal_Project_Number =1,Project_Name = "Project-1", County = "USA"},
new Project_Screen(){ State_Project_Number = 2,Federal_Project_Number =2,Project_Name = "Project-2", County = "CA"},
new Project_Screen(){ State_Project_Number = 3,Federal_Project_Number =3,Project_Name = "Project-3", County = "UK"},
};
var typeOne = new List<Type_One>()
{
new Type_One(){ State_Project_Number = 101,Federal_Project_Number =101,Project_Name = "Type-One-Project-1", County = "USA"},
new Type_One(){ State_Project_Number = 102,Federal_Project_Number =102,Project_Name = "Type-One-Project-2", County = "CA"},
new Type_One(){ State_Project_Number = 103,Federal_Project_Number =103,Project_Name = "Type-One-Project-3", County = "UK"},
};
//Bind to View Model
MyProjectsViewModel viewModel = new MyProjectsViewModel();
viewModel.ProjectScreen = proScreen;
viewModel.TypeOne = typeOne;
return View(viewModel);
}
Note: I am binding demo seeder property into the list. Feel free to change as per your requirement.Just getting you into the point.
View:
@model MVCApps.Models.MyProjectsViewModel
@{
ViewData["Title"] = "ViewModelEnumeration";
}
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.ProjectScreen)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.TypeOne)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
</tr>
}
</tbody>
</table>
Output:
Note: So according to your scenario you can use like this @foreach (var item in Model.Project_Screen)
. Additionally, be
conscious about your naming convention like Project_Screen Project_Screen
is confusing either practice like Project_Screen ProjectScreen
or ProjectScreen Project_Screen
.
希望以上步骤能相应地指导您。您可以在我们的 official document here
上进一步增强您的想法
更新:
As per your comment I am also adding the example in case of single
object means when you have other than List
or IEnumerable
View Model:
public class ProjectsScreenTypeOneViewModel
{
public Project_Screen ProjectScreen { get; set; }
public Type_One TypeOne { get; set; }
}
Controller:
public ActionResult ViewModelFromSingleObject()
{
//Binding Project_Screen Object
var _proScreen = new Project_Screen();
_proScreen.Project_Name = "Test Project-202";
_proScreen.State_Project_Number = 1111;
_proScreen.Federal_Project_Number = 11112021;
_proScreen.County = "USA";
//Binding Type_One Object
var _typeOne = new Type_One();
_typeOne.Project_Name = "Test Type One Project-101";
_typeOne.State_Project_Number = 1010;
_typeOne.Federal_Project_Number = 202121;
_typeOne.County = "UK";
//Binding to view model
var _viewModel = new ProjectsScreenTypeOneViewModel();
_viewModel.ProjectScreen = _proScreen;
_viewModel.TypeOne = _typeOne;
return View(_viewModel);
}
View:
@model MVCApps.Models.ProjectsScreenTypeOneViewModel
@{
ViewData["Title"] = "ViewModelFromSingleObject";
}
<h2>ViewModelFromSingleObject</h2>
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
@Html.DisplayFor(modelItem => Model.ProjectScreen.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => Model.ProjectScreen.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => Model.ProjectScreen.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => Model.ProjectScreen.County)
</td>
</tr>
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
@Html.DisplayFor(modelItem => Model.TypeOne.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => Model.TypeOne.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => Model.TypeOne.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => Model.TypeOne.County)
</td>
</tr>
</tbody>
</table>
Output:
Note:
Now as you can see I have added both single
and List
kind of example which will guided you accordingly. If you still
encounter any further issue feel free to share.
我有2个模型; TypeOne
和 Project_Screen
。我需要一个视图,使 2 tables 具有来自这两个 tables 的信息。我尝试使用本指南来制作一个视图模型,它有所帮助,但与我做的事情并不完全相同:https://dotnettutorials.net/lesson/view-model-asp-net-core-mvc/
这是我制作的视图模型:
public class MyProjectsViewModel
{
public Project_Screen Project_Screen { get; set; }
public TypeOne TypeOne { get; set; }
}
这是控制器:
public class ProfileController : Controller
{
private readonly Natural_ResourcesContext _context;
public ProfileController(Natural_ResourcesContext context)
{
_context = context;
}
// GET: Profile
public ActionResult Index()
{
Project_Screen project_Screen = (Project_Screen)(from s in _context.Project_Screen
where s.DSN_PM == User.Identity.Name
select s);
TypeOne typeOne = (TypeOne)(from x in _context.TypeOne
where x.Name == User.Identity.Name
select x);
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
return View(myProjectsViewModel);
}
}
可以看到,project_Screen
和typeOne
都是Manager = Name
.
然后在视图中我想显示如下内容:
@model EnvApp.ViewModels.MyProjectsViewModel
@{
ViewData["Title"] = "Projects";
}
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
<td>
@Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
<td>
@Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
我在 ````Model``` 上收到编译器错误 CS1579:
foreach statement cannot operate on variables of type 'MyProjectsViewModel' because 'MyProjectsViewModel' does not contain a public instance or extension definition for 'GetEnumorator'
我认为这是有道理的,因为我没有将 Project_Screen
或 TypeOne
表示为一个包含多条记录的对象,但我不太确定该怎么做。
我是在正确的轨道上还是我误解了这一点?我错过了什么?
编辑 1:
我完全按照 Md Farid Uddin Kiron 所说的进行操作,因此他的回答中的代码反映了我的视图模型和视图。但是我的控制器仍然有问题。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using EnvApp.ViewModels;
using EnvApp.Models.DB;
namespace EnvApp.Controllers
{
public class ProfileController : Controller
{
private readonly Natural_ResourcesContext _context;
public ProfileController(Natural_ResourcesContext context)
{
_context = context;
}
// GET: Profile
public ActionResult Index()
{
Project_Screen project_Screen = (Project_Screen)(from s in _context.Project_Screen
where s.DSN_PM == User.Identity.Name
select s);
TypeOne typeOne = (TypeOne)(from x in _context.TypeOne
where x.Name == User.Identity.Name
select x);
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
return View(myProjectsViewModel);
}
}
}
问题是 project_Screen
和 typeOne
不是列表或 IEnumerable 类型,这是有道理的,但我不是使它们可枚举的语法。
如果您需要查看,这是我的视图模型:
public class MyProjectsViewModel
{
public List<Project_Screen> Project_Screen { get; set; }
public List<TypeOne> TypeOne { get; set; }
}
这是视图:
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Project_Screen)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
<td>
@Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th>
Coordinates
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.TypeOne)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
<td>
@Html.DisplayFor(modelItem => item.Coordinates)
</td>
<td>
<a asp-action="Details" asp-route-id="@item.ID">Details</a>
</td>
</tr>
}
</tbody>
</table>
同样,问题是 project_Screen
和 typeOne
不是控制器中的列表或 IEnumerable 类型。它们实际上是列表,除了控制器之外无处不在,但它们必须是。错误在行
MyProjectsViewModel myProjectsViewModel = new MyProjectsViewModel()
{
Project_Screen = project_Screen,
TypeOne = typeOne
};
在 project_Screen
和 typeOne
上读取
cannot implicitly convert type Envapp.Models.DB.Project_Screen to System.Collection.Generic.List<Envapp.Models.DB.Project_Screen>
这似乎正在发生,因为那里的代码试图指向 Project_Screen 的数据库模型 table,而不是 Project_Screen 模型中项目的 ViewModel 表示。我该如何解决这个问题?
编辑 2:
我不确定它是什么,但我的代码中的某些内容似乎真的让人们感到困惑。我发布了我所有的模型以供澄清:
Project_Screen.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
#nullable disable
namespace EnvApp.Models.DB
{
public partial class Project_Screen
{
[Key]
public long ID { get; set; }
public string State_Project_Number { get; set; }
public string? Federal_Project_Number { get; set; }
public string Project_Name { get; set; }
public string County { get; set; }
public DateTime? Memo_Date { get; set; }
public string From { get; set; }
public string? Authorization { get; set; }
public string DSN_PM { get; set; }
public string? History { get; set; }
public string History_PM { get; set; }
public bool Review_Exempt_H { get; set; }
public bool SHPO_Approval_H { get; set; }
public string? Archaeology { get; set; }
public string Archaeology_PM { get; set; }
public bool Review_Exempt_A { get; set; }
public bool SHPO_Approval_A { get; set; }
public bool ESA_Key { get; set; }
public bool Crayfish { get; set; }
public bool Crayfish_Habitat_Assessment { get; set; }
public bool NLEB_4D { get; set; }
public bool USFWS { get; set; }
public string USFWS_Type { get; set; }
public bool Mussel_Habitat { get; set; }
public bool Mussel_Stream { get; set; }
public string Within_Airport { get; set; }
public string? ToPo_Quad_Name { get; set; }
public bool Bat_Habitat { get; set; }
public string? Bars { get; set; }
public string Coordinates { get; set; }
public string? Natural_Resources_Notes { get; set; }
public string Adduser { get; set; }
public DateTime? Date_Added { get; set; }
public string Crayfish_Notes { get; set; }
public string Mussel_Notes { get; set; }
}
}
TypeOne.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
#nullable disable
namespace EnvApp.Models.DB
{
[Table("Type_One")]
public partial class TypeOne
{
[Key]
public long ID { get; set; }
[MaxLength(50)]
public string State_Project_Number { get; set; }
[MaxLength(50)]
public string Federal_Project_Number { get; set; }
[MaxLength(50)]
public string Name { get; set; }
[MaxLength(50)]
public string Route_Number { get; set; }
public string County { get; set; }
[MaxLength(50)]
public string Work_Type { get; set; }
[MaxLength(100)]
public string Coordinates { get; set; }
public string Project_Description { get; set; }
public bool? Federal_Aid { get; set; }
public bool? Minimal_Project_Verification { get; set; }
[MaxLength(3)]
public string CE_Category { get; set; }
[MaxLength(10)]
public string Amms { get; set; }
public bool Activities_Agreement { get; set; }
public string Arch_RE { get; set; }
public string Hist_RE { get; set; }
public DateTime? Arch_RE_Date { get; set; }
public DateTime? Hist_RE_Date { get; set; }
public bool? Through_Lanes { get; set; }
public bool? Close_Road { get; set; }
public bool? ROW_Acquisition { get; set; }
public bool? Access_Control { get; set; }
public bool? Fifty_Year_Structure { get; set; }
public bool? Agency_Coordination { get; set; }
public bool? IPAC_Screening_Zone { get; set; }
public bool? Section_404_Permit { get; set; }
public bool? Ground_Disturbance { get; set; }
public bool? Waterway { get; set; }
public bool? Special_Use_Permit { get; set; }
public bool? Floodplain { get; set; }
public string Prepared_By { get; set; }
public string Approved_By { get; set; }
public string Adduser { get; set; }
public DateTime? Date_Added { get; set; }
}
}
Natural_ResourcesContext
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
#nullable disable
namespace EnvApp.Models.DB
{
public partial class Natural_ResourcesContext : DbContext
{
public Natural_ResourcesContext()
{
}
public Natural_ResourcesContext(DbContextOptions<Natural_ResourcesContext> options)
: base(options)
{
}
public virtual DbSet<NR_User> NR_Users { get; set; }
public virtual DbSet<Project_Screen> Project_Screen { get; set; }
public virtual DbSet<TypeOne> TypeOne { get; set; }
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
该错误是因为您在视图模型本身而不是您要枚举的属性上使用 foreach。
对于Project_Screen和TypeOne,将它们声明为可枚举类型(例如Array、List、IEnumerable等)。
public class MyProjectsViewModel
{
public IEnumerable<Project_Screen> Project_Screen { get; set; }
public IEnumerable<TypeOne> TypeOne { get; set; }
}
您将需要使用来自控制器的一组值来填充它们
var viewModel = new MyProjectsViewModel();
viewModel.Project_Screen = _context.Project_Screen.Where(x => SOME_CONDITION);
viewModel.TypeOne = _context.TypeOne.Where(x => SOME_CONDITION);
在视图中,您将枚举这些属性(而不是模型本身)。
@foreach (var item in Model.Project_Screen)
和
@foreach (var item in Model.TypeOne)
你已经足够接近了。从我们了解到的视图迭代中,您的 Project_Screen
和 Type_One
似乎应该是 class 的列表。如果是这样,那么你的 MyProjectsViewModel
应该是这样的:
View Model:
public class MyProjectsViewModel
{
public List<Project_Screen> ProjectScreen { get; set; }
public List<Type_One> TypeOne { get; set; }
}
Controller:
public ActionResult ViewModelEnumeration()
{
var proScreen = new List<Project_Screen>()
{
new Project_Screen(){ State_Project_Number = 1,Federal_Project_Number =1,Project_Name = "Project-1", County = "USA"},
new Project_Screen(){ State_Project_Number = 2,Federal_Project_Number =2,Project_Name = "Project-2", County = "CA"},
new Project_Screen(){ State_Project_Number = 3,Federal_Project_Number =3,Project_Name = "Project-3", County = "UK"},
};
var typeOne = new List<Type_One>()
{
new Type_One(){ State_Project_Number = 101,Federal_Project_Number =101,Project_Name = "Type-One-Project-1", County = "USA"},
new Type_One(){ State_Project_Number = 102,Federal_Project_Number =102,Project_Name = "Type-One-Project-2", County = "CA"},
new Type_One(){ State_Project_Number = 103,Federal_Project_Number =103,Project_Name = "Type-One-Project-3", County = "UK"},
};
//Bind to View Model
MyProjectsViewModel viewModel = new MyProjectsViewModel();
viewModel.ProjectScreen = proScreen;
viewModel.TypeOne = typeOne;
return View(viewModel);
}
Note: I am binding demo seeder property into the list. Feel free to change as per your requirement.Just getting you into the point.
View:
@model MVCApps.Models.MyProjectsViewModel
@{
ViewData["Title"] = "ViewModelEnumeration";
}
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.ProjectScreen)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
</tr>
}
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.TypeOne)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => item.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.County)
</td>
</tr>
}
</tbody>
</table>
Output:
Note: So according to your scenario you can use like this
@foreach (var item in Model.Project_Screen)
. Additionally, be conscious about your naming convention likeProject_Screen Project_Screen
is confusing either practice likeProject_Screen ProjectScreen
orProjectScreen Project_Screen
.
希望以上步骤能相应地指导您。您可以在我们的 official document here
上进一步增强您的想法更新:
As per your comment I am also adding the example in case of single object means when you have other than
List
orIEnumerable
View Model:
public class ProjectsScreenTypeOneViewModel
{
public Project_Screen ProjectScreen { get; set; }
public Type_One TypeOne { get; set; }
}
Controller:
public ActionResult ViewModelFromSingleObject()
{
//Binding Project_Screen Object
var _proScreen = new Project_Screen();
_proScreen.Project_Name = "Test Project-202";
_proScreen.State_Project_Number = 1111;
_proScreen.Federal_Project_Number = 11112021;
_proScreen.County = "USA";
//Binding Type_One Object
var _typeOne = new Type_One();
_typeOne.Project_Name = "Test Type One Project-101";
_typeOne.State_Project_Number = 1010;
_typeOne.Federal_Project_Number = 202121;
_typeOne.County = "UK";
//Binding to view model
var _viewModel = new ProjectsScreenTypeOneViewModel();
_viewModel.ProjectScreen = _proScreen;
_viewModel.TypeOne = _typeOne;
return View(_viewModel);
}
View:
@model MVCApps.Models.ProjectsScreenTypeOneViewModel
@{
ViewData["Title"] = "ViewModelFromSingleObject";
}
<h2>ViewModelFromSingleObject</h2>
<h1>My Projects</h1>
<hr />
<h4>Screening Forms</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
@Html.DisplayFor(modelItem => Model.ProjectScreen.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => Model.ProjectScreen.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => Model.ProjectScreen.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => Model.ProjectScreen.County)
</td>
</tr>
</tbody>
</table>
<br />
<hr />
<h4>Type One Projects</h4>
<table class="table">
<thead>
<tr>
<th>
State Project Number
</th>
<th>
Federal Project Number
</th>
<th>
Project Name
</th>
<th>
County
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
@Html.DisplayFor(modelItem => Model.TypeOne.State_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => Model.TypeOne.Federal_Project_Number)
</td>
<td>
@Html.DisplayFor(modelItem => Model.TypeOne.Project_Name)
</td>
<td>
@Html.DisplayFor(modelItem => Model.TypeOne.County)
</td>
</tr>
</tbody>
</table>
Output:
Note:
Now as you can see I have added bothsingle
andList
kind of example which will guided you accordingly. If you still encounter any further issue feel free to share.