我正在尝试在一个视图中创建一个具有Parent-Child模型(多个模型)的Web应用程序(ASP.NET Core + MVC + Entity Framework)。
以下是输入(输入No.1)。 这是" Views / Blogs / index.cshtml"
以下也是输入(输入No.2)。 这是" Views / Tags / index.cshtml"
以下是我期待的输出(输出No.1)。
我写了以下内容"观看/博客/ cshtml"。
@model IEnumerable<urlapp12.Models.UrlTag>
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Blog.Userid)
</th>
<th>
@Html.DisplayNameFor(model => model.Blog.Url)
</th>
<th>
@Html.DisplayNameFor(model => model.Blog.LastUpdatedAt_UtcDt)
</th>
<th>
@Html.DisplayNameFor(model => model.Blog.LastUpdatedAt_LocalDt)
</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Blog.Userid)
</td>
<td>
<a href="@Html.DisplayFor(modelItem => item.Blog.Url)">@Html.DisplayFor(modelItem => item.Blog.Title)</a>
</td>
<td>
@Html.DisplayFor(modelItem => item.Blog.LastUpdatedAt_UtcDt)
</td>
<td>
@Html.DisplayFor(modelItem => item.Blog.LastUpdatedAt_LocalDt)
</td>
<td>
@foreach (var childItem in item.Tag)
{
@Html.DisplayFor(modelItem => childItem.tagItem)
}
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.Blog.BlogId">Edit</a> |
<a asp-action="Details" asp-route-id="@item.Blog.BlogId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.Blog.BlogId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
并执行,我收到以下错误。 (输出No.2。真正的意外输出)
An unhandled exception occurred while processing the request.
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List`1[urlapp12.Models.Blog]', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable`1[urlapp12.Models.UrlTag]'.
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary.EnsureCompatible(object value)
Models / Blog.cs如下。
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace urlapp12.Models
{
public partial class Blog
{
public Blog()
{
Post = new HashSet<Post>();
}
[Key]
public int BlogId { get; set; }
public string Userid { get; set; }
public string Url { get; set; }
public string Title { get; set; }
public string CreatedBy { get; set; }
[System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
public DateTime CreatedAt_UtcDt { get; set; }
[System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
public DateTime CreatedAt_LocalDt { get; set; }
public string LastUpdatedBy { get; set; }
[System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
public DateTime LastUpdatedAt_UtcDt { get; set; }
[System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
public DateTime LastUpdatedAt_LocalDt { get; set; }
public ICollection<Tag> Tag { get; set; }
public ICollection<Post> Post { get; set; }
/*
public List<Tag> Tag { get; set; }
public List<Post> Post { get; set; }
*/
}
}
Models / Tag.cs如下。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace urlapp12.Models
{
public class Tag
{
public int Id { get; set; }
public int DispOrderNbr { get; set; }
public string tagItem { get; set; }
public int BlogId { get; set; }
public string CreatedBy { get; set; }
[System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
public DateTime CreatedAt_UtcDt { get; set; }
[System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
public DateTime CreatedAt_LocalDt { get; set; }
public string LastUpdatedBy { get; set; }
[System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
public DateTime LastUpdatedAt_UtcDt { get; set; }
[System.ComponentModel.DataAnnotations.Schema.Column(TypeName = "datetime2")]
public DateTime LastUpdatedAt_LocalDt { get; set; }
[System.ComponentModel.DataAnnotations.Schema.ForeignKey("BlogId")]
public Blog blog { get; set; }
}
}
Model / UlrTag.cs如下。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace urlapp12.Models
{
public class UrlTag
{
public Blog Blog { get; set; }
public IEnumerable<Tag> Tag { get; set; }
}
}
是否有人对此亲子模型有所帮助? 提前谢谢。
Blogs.Controller.cs如下。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using urlapp12.Models;
namespace urlapp12.Controllers
{
public class BlogsController : Controller
{
private readonly Blogging02Context _context;
// Stores UserManager
private readonly UserManager<ApplicationUser> _manager;
private UserManager<ApplicationUser> _userManager;
public BlogsController(Blogging02Context context, UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
_context = context;
}
// GET: Blogs
public async Task<IActionResult> Index()
{
return View(await _context.Blog.ToListAsync());
}
// GET: Blogs/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var blog = await _context.Blog
.SingleOrDefaultAsync(m => m.BlogId == id);
if (blog == null)
{
return NotFound();
}
return View(blog);
}
// GET: Blogs/Create
public IActionResult Create()
{
return View();
}
// POST: Blogs/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost] [ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("BlogId,Userid,Url,Title")] Blog blog)
{
if (ModelState.IsValid)
{
/*
string strCurrentUserId;
strCurrentUserId = User.Identity.GetUserId(this IIdentity identity);
var currentUserName = User.Identity.Name ;
var user = await UserManager<ApplicationUser>.FindByIdAsync(User.Identity.GetUserId());
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDbContext()));
var UserManager = new UserManager(IUserstore<ApplicationUser>);
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
var user = await GetCurrentUserAsync();
var userId = user?.Id;
string mail = user?.Email;
var userid = GetCurrentUserClaims().userid;
var userClaims = new UserClaims();
var claims = _httpContextAccessor.HttpContext.User.Claims.ToList();
var userid2 = await IGenericRepository < User > userRepository.GetByIdAsync(_currentUserGuid);
UserManager<ApplicationUser> _userManager;
SignInManager<ApplicationUser> _signInManager = new SignInManager<ApplicationUser>();
var info = await _signInManager.GetExternalLoginInfoAsync();
*/
// Stores UserManager
// private readonly UserManager<ApplicationUser> _manager;
// var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
// var result = await _userManager.CreateAsync(user, model.Password);
var user = await _userManager.GetUserAsync(HttpContext.User);
var currentLoginUserid = user.Id;
blog.Userid = user.Id;
int maxIdInDb = 0;
int BlogRecCnt = _context.Blog.Count();
if (_context.Blog.Count() == 0)
{
maxIdInDb = 0;
}
else
{
maxIdInDb = _context.Blog.Max(p => p.BlogId);
}
int NextId = maxIdInDb + 1;
blog.BlogId = NextId;
blog.CreatedAt_LocalDt = DateTime.Now;
blog.CreatedAt_UtcDt = DateTime.UtcNow;
blog.CreatedBy = user.Id;
blog.LastUpdatedAt_LocalDt = DateTime.Now;
blog.LastUpdatedAt_UtcDt = DateTime.UtcNow;
blog.LastUpdatedBy = user.Id;
_context.Add(blog);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(blog);
}
// GET: Blogs/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var blog = await _context.Blog.SingleOrDefaultAsync(m => m.BlogId == id);
if (blog == null)
{
return NotFound();
}
var user = await _userManager.GetUserAsync(HttpContext.User);
var currentLoginUserid = user.Id;
blog.Userid = user.Id;
blog.LastUpdatedAt_LocalDt = DateTime.Now;
blog.LastUpdatedAt_UtcDt = DateTime.UtcNow;
blog.LastUpdatedBy = user.Id;
return View(blog);
}
// POST: Blogs/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("BlogId,Userid,Url,Title")] Blog blog)
{
if (id != blog.BlogId)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(blog);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!BlogExists(blog.BlogId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(blog);
}
// GET: Blogs/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var blog = await _context.Blog
.SingleOrDefaultAsync(m => m.BlogId == id);
if (blog == null)
{
return NotFound();
}
return View(blog);
}
// POST: Blogs/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var blog = await _context.Blog.SingleOrDefaultAsync(m => m.BlogId == id);
_context.Blog.Remove(blog);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool BlogExists(int id)
{
return _context.Blog.Any(e => e.BlogId == id);
}
}
}
TagsController.cs如下。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using urlapp12.Models;
namespace urlapp12.Controllers
{
public class TagsController : Controller
{
private readonly Blogging02Context _context;
public TagsController(Blogging02Context context)
{
_context = context;
}
//int id, [Bind("BlogId,Userid,Url,Title")] Blog blog
// GET: Tags
// public async Task<IActionResult> Index()
public async Task<IActionResult> Index(int id, [Bind("BlogId,Userid,Url,Title")] Blog blog)
{
/*
return View(await _context.Tag.ToListAsync());
*/
var blogging02Context = _context.Tag.Include(t => t.blog);
return View(await blogging02Context.ToListAsync());
// return View (await _context.Tag.ToListAsync());
}
// GET: Tags/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var tag = await _context.Tag
.Include(t => t.blog)
.SingleOrDefaultAsync(m => m.Id == id);
if (tag == null)
{
return NotFound();
}
return View(tag);
}
// GET: Tags/Create
public IActionResult Create()
{
ViewData["BlogId"] = new SelectList(_context.Blog, "BlogId", "Title");
return View();
}
// POST: Tags/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,DispOrderNbr,tagItem,BlogId")] Tag tag)
{
if (ModelState.IsValid)
{
_context.Add(tag);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["BlogId"] = new SelectList(_context.Blog, "BlogId", "Title", tag.BlogId);
return View(tag);
}
// GET: Tags/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var tag = await _context.Tag.SingleOrDefaultAsync(m => m.Id == id);
if (tag == null)
{
return NotFound();
}
ViewData["BlogId"] = new SelectList(_context.Blog, "BlogId", "Title", tag.BlogId);
return View(tag);
}
// POST: Tags/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,DispOrderNbr,tagItem,BlogId")] Tag tag)
{
if (id != tag.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(tag);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TagExists(tag.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
ViewData["BlogId"] = new SelectList(_context.Blog, "BlogId", "Title", tag.BlogId);
return View(tag);
}
// GET: Tags/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var tag = await _context.Tag
.Include(t => t.blog)
.SingleOrDefaultAsync(m => m.Id == id);
if (tag == null)
{
return NotFound();
}
return View(tag);
}
// POST: Tags/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int? id)
{
var tag = await _context.Tag.SingleOrDefaultAsync(m => m.Id == id);
_context.Tag.Remove(tag);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool TagExists(int id)
{
return _context.Tag.Any(e => e.Id == id);
}
}
}
我尝试过Gimly的想法。
public async Task<IActionResult> Index()
{
return View(await _context.Blog.Include(b => b.Tags).ToListAsync());
}
然后Visual Studio告诉我&#34;&#39; Blog&#39;不包括&#39;标签&#39;定义&#34;错误。 所以我将标签更改为标签,我的Visual Studio称它是O.K。
public async Task<IActionResult> Index()
{
return View(await _context.Blog.Include(b => b.Tag).ToListAsync());
}
我运行调试模式的代码,Web应用程序返回以下错误。
处理请求时发生未处理的异常。
InvalidOperationException:传递给ViewDataDictionary的模型项的类型为&#39; System.Collections.Generic.List 1[urlapp12.Models.Blog]', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable
1 [urlapp12.Models.UrlTag]&#39;。
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary.EnsureCompatible(对象值)
非常感谢。
我更改了代码&#34; /Views/Blogs/Index.cshml"如下所示,我可以成功执行它。
@model IEnumerable<urlapp12.Models.Blog>
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Userid)
</th>
<th>
@Html.DisplayNameFor(model => model.Url)
</th>
<th>
@Html.DisplayNameFor(model => model.LastUpdatedAt_UtcDt)
</th>
<th>
@Html.DisplayNameFor(model => model.LastUpdatedAt_LocalDt)
</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Userid)
</td>
<td>
<a href="@Html.DisplayFor(modelItem => item.Url)">@Html.DisplayFor(modelItem => item.Title)</a>
</td>
<td>
@Html.DisplayFor(modelItem => item.LastUpdatedAt_UtcDt)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastUpdatedAt_LocalDt)
</td>
<td>
@foreach (var childItem in item.Tag)
{
@Html.DisplayFor(itemItem => childItem.tagItem)
}
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.BlogId">Edit</a> |
<a asp-action="Details" asp-route-id="@item.BlogId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.BlogId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
答案 0 :(得分:0)
首先,关于你得到的异常,错误信息是非常明确的,并且@junkangli在其评论中解释说,你没有将正确的对象返回给View。 View需要IEnumerable<UrlTag>
,并且您发送IEnumerable<Blog>
。
现在,关于问题的核心,您需要在查询中加载标记列表以获取博客列表,因此,在控制器的Index
操作中,您应该执行以下操作:
public async Task<IActionResult> Index()
{
return View(await _context.Blog.Include(b => b.Tags).ToListAsync());
}
然后,在您的视图中,您应该能够访问您的代码并创建一个while循环来显示所有代码。