如何在另一个视图中显示一个视图
How do I display a View inside another View
我正在通过制作像 Twitter 这样的网站来练习 ASP 和 MVC,但我在使用 PartialView 时遇到了问题。
我的用户主页控制器在这里,它是从我的登录页面控制器调用的。
public class UserController : Controller
{
private readonly Twitter _twitter = null;
private readonly TwitterCloneDBContext _context;
public UserController(TwitterCloneDBContext context)
{
_twitter = new Twitter(context);
_context = context;
}
public ActionResult Index()
{
List<Tweet> tweets = _twitter.TweetList();
ViewBag.Tweets = tweets.Count;
ViewBag.Followers = 2;
ViewBag.Following = 3;
return View();
}
public PartialViewResult TweetList()
{
List<Tweet> tweetList = _twitter.TweetList();
return PartialView("TweetList",tweetList);
}
}
这是它的视图。
@{
ViewData["Title"] = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using Microsoft.AspNetCore.Http;
@model IEnumerable<Tweet>
@if (Context.Session.GetString("FullName") != null)
{
<div class="text-center">
<h1 class="display-4">Welcome, @Context.Session.GetString("FullName")!</h1>
</div>
<hr />
<div class="row">
<div class="col-sm-2">
<div class="text-left">
<h4>Follow</h4>
<form asp-action="Search">
<div class="input-group mb-3">
<input type="text" name="searchName" class="form-control" placeholder="Search User" />
<div class="input-group-append">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</div>
</form>
<span class="text-danger">@ViewBag.SearchFail</span>
</div>
<div>
<h6>@ViewBag.Tweets Tweets</h6>
<br />
<h6>@ViewBag.Followers Followers</h6>
<br />
<h6>@ViewBag.Following Following</h6>
</div>
</div>
<div class=border></div>
<div class="col-4">
<h4>Tweet your thoughts!</h4>
<form asp-action="Tweet">
<textarea rows="5" cols="100" name="message" class="form-control"> </textarea>
<br />
<input type="submit" value="Tweet" class="btn btn-primary" />
</form>
<span class=" text-danger">@ViewBag.ErrMessage</span>
<div>
@Html.PartialAsync("TwitterList",Model)
</div>
</div>
</div>
}
else
{
<h2>You are not Authorized!</h2>
<script type="text/javascript">
window.setTimeout(function () {
window.location.href = '/Home/UserLogin';
}, 1000);
</script>
}
Partial Line 应该调用 TwitterList 视图,它工作正常并按预期显示列表。
@model IEnumerable<TwitterClone.Models.Tweet>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.User_ID)
</th>
<th>
@Html.DisplayNameFor(model => model.Message)
</th>
<th>
@Html.DisplayNameFor(model => model.Created)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.User_ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Message)
</td>
<td>
@Html.DisplayFor(modelItem => item.Created)
</td>
</tr>
}
</tbody>
</table>
但是当我使用@Html.PartialAsync() 调用它时它失败了
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=TwitterClone.Views
StackTrace:
at AspNetCore.Views_User_TweetList.<ExecuteAsync>d__0.MoveNext() in C:\Users\Cloud\source\repos\TwitterClone\TwitterClone\Views\User\TweetList.cshtml:line 19
并在主页上给我这个
参见下面的推文按钮,这是我的局部视图,如果我以任何其他方式执行局部视图,我会在两个地方都得到 NullReferenceException。这是我已经完成的,但我无法弄清楚。
编辑:
我的 ViewBags 在另一个与此处无关的 Actions 中。他们基本上会打印一条错误消息。
NullExceptions 消失了,当我自己打开 Table 视图时,我的模型不是空的。但是通过 Partial 调用时它是空的。我怀疑是因为链中没有调用某些东西。
如果我将索引操作更改为这样,
public ActionResult Index()
{
List<Tweet> tweets = _twitter.TweetList();
ViewBag.Tweets = tweets.Count;
ViewBag.Followers = 2;
ViewBag.Following = 3;
return View("Index",tweets);
}
我收到这个错误。
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List`1[TwitterClone.Models.Tweet]', but this ViewDataDictionary instance requires a model item of type 'TwitterClone.Models.Person'.
我不知道 ViewDataDictionary 将 Person 设置到哪里。我能想到的唯一连接到 UserController 的地方是我的 HomeController。
编辑
这是一个愚蠢的错误,我在布局文件中遗漏了@model Person。对不起。
编辑
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly TwitterCloneDBContext _context;
public HomeController(ILogger<HomeController> logger, TwitterCloneDBContext context)
{
_logger = logger;
_context = context;
}
//GET: Home/UserLogin
public ActionResult UserLogin()
{
return View();
}
//POST: Home/UserLogin
[Microsoft.AspNetCore.Mvc.HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UserLogin(Person userLogin)
{
var login = _context.Person.Where(a => a.UserID.Equals(userLogin.UserID)
&& a.Password.Equals(userLogin.Password)).FirstOrDefault();
if (login != null)
{
Person session = _context.Person.SingleOrDefault(u => u.UserID == userLogin.UserID);
session.Active = 1;
HttpContext.Session.SetString("FullName", login.FullName);
HttpContext.Session.SetString("UserID", login.UserID);
_context.SaveChanges();
return RedirectToAction("Index", "User");
}
else
{
ViewBag.ErrMsg = "Invalid Credentials";
return View();
}
}
}
及其视图
@model Person
@{
ViewData["Title"] = "UserLogin";
Layout = "~/Views/Shared/LoginLayout.cshtml";
}
<h1>Welcome!</h1>
<h4>Enter Credentials</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="UserLogin">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserID" class="control-label">User ID</label>
<input asp-for="UserID" class="form-control" />
<span asp-validation-for="UserID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label">Password</label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Login" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
New User? <a asp-action="Signup">Signup</a>
</div>
什么是
<span class="text-danger">@ViewBag.SearchFail</span>
我在你的操作中看不到 ViewBag.SearchFail 或 ViewBag.ErrMessage。
你有一个大错误。将重定向从索引视图移至操作,否则在创建页面后它将始终 运行。
public ActionResult Index()
{
if (Context.Session.GetString("FullName") != null)
{
List<Tweet> tweets = _twitter.TweetList();
.....
return View("Index", tweets);
}
RedirectToAction("Login", "Users")
}
由于两者使用的是同一型号,请尝试更换
@Html.PartialAsync("TwitterList",Model)
和
<partial name="TwitterList" />
并修复两个视图的模型
@model List<TwitterClone.Models.Tweet>
同时修复局部视图
@if(@Model!=null && Model.Count >0)
{
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model[0].User_ID)
</th>
<th>
@Html.DisplayNameFor(model => model[0].Message)
</th>
......
}
我正在通过制作像 Twitter 这样的网站来练习 ASP 和 MVC,但我在使用 PartialView 时遇到了问题。
我的用户主页控制器在这里,它是从我的登录页面控制器调用的。
public class UserController : Controller
{
private readonly Twitter _twitter = null;
private readonly TwitterCloneDBContext _context;
public UserController(TwitterCloneDBContext context)
{
_twitter = new Twitter(context);
_context = context;
}
public ActionResult Index()
{
List<Tweet> tweets = _twitter.TweetList();
ViewBag.Tweets = tweets.Count;
ViewBag.Followers = 2;
ViewBag.Following = 3;
return View();
}
public PartialViewResult TweetList()
{
List<Tweet> tweetList = _twitter.TweetList();
return PartialView("TweetList",tweetList);
}
}
这是它的视图。
@{
ViewData["Title"] = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using Microsoft.AspNetCore.Http;
@model IEnumerable<Tweet>
@if (Context.Session.GetString("FullName") != null)
{
<div class="text-center">
<h1 class="display-4">Welcome, @Context.Session.GetString("FullName")!</h1>
</div>
<hr />
<div class="row">
<div class="col-sm-2">
<div class="text-left">
<h4>Follow</h4>
<form asp-action="Search">
<div class="input-group mb-3">
<input type="text" name="searchName" class="form-control" placeholder="Search User" />
<div class="input-group-append">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</div>
</form>
<span class="text-danger">@ViewBag.SearchFail</span>
</div>
<div>
<h6>@ViewBag.Tweets Tweets</h6>
<br />
<h6>@ViewBag.Followers Followers</h6>
<br />
<h6>@ViewBag.Following Following</h6>
</div>
</div>
<div class=border></div>
<div class="col-4">
<h4>Tweet your thoughts!</h4>
<form asp-action="Tweet">
<textarea rows="5" cols="100" name="message" class="form-control"> </textarea>
<br />
<input type="submit" value="Tweet" class="btn btn-primary" />
</form>
<span class=" text-danger">@ViewBag.ErrMessage</span>
<div>
@Html.PartialAsync("TwitterList",Model)
</div>
</div>
</div>
}
else
{
<h2>You are not Authorized!</h2>
<script type="text/javascript">
window.setTimeout(function () {
window.location.href = '/Home/UserLogin';
}, 1000);
</script>
}
Partial Line 应该调用 TwitterList 视图,它工作正常并按预期显示列表。
@model IEnumerable<TwitterClone.Models.Tweet>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.User_ID)
</th>
<th>
@Html.DisplayNameFor(model => model.Message)
</th>
<th>
@Html.DisplayNameFor(model => model.Created)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.User_ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Message)
</td>
<td>
@Html.DisplayFor(modelItem => item.Created)
</td>
</tr>
}
</tbody>
</table>
但是当我使用@Html.PartialAsync() 调用它时它失败了
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=TwitterClone.Views
StackTrace:
at AspNetCore.Views_User_TweetList.<ExecuteAsync>d__0.MoveNext() in C:\Users\Cloud\source\repos\TwitterClone\TwitterClone\Views\User\TweetList.cshtml:line 19
并在主页上给我这个
参见下面的推文按钮,这是我的局部视图,如果我以任何其他方式执行局部视图,我会在两个地方都得到 NullReferenceException。这是我已经完成的,但我无法弄清楚。
编辑:
我的 ViewBags 在另一个与此处无关的 Actions 中。他们基本上会打印一条错误消息。
NullExceptions 消失了,当我自己打开 Table 视图时,我的模型不是空的。但是通过 Partial 调用时它是空的。我怀疑是因为链中没有调用某些东西。
如果我将索引操作更改为这样,
public ActionResult Index()
{
List<Tweet> tweets = _twitter.TweetList();
ViewBag.Tweets = tweets.Count;
ViewBag.Followers = 2;
ViewBag.Following = 3;
return View("Index",tweets);
}
我收到这个错误。
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List`1[TwitterClone.Models.Tweet]', but this ViewDataDictionary instance requires a model item of type 'TwitterClone.Models.Person'.
我不知道 ViewDataDictionary 将 Person 设置到哪里。我能想到的唯一连接到 UserController 的地方是我的 HomeController。
编辑
这是一个愚蠢的错误,我在布局文件中遗漏了@model Person。对不起。
编辑
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly TwitterCloneDBContext _context;
public HomeController(ILogger<HomeController> logger, TwitterCloneDBContext context)
{
_logger = logger;
_context = context;
}
//GET: Home/UserLogin
public ActionResult UserLogin()
{
return View();
}
//POST: Home/UserLogin
[Microsoft.AspNetCore.Mvc.HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UserLogin(Person userLogin)
{
var login = _context.Person.Where(a => a.UserID.Equals(userLogin.UserID)
&& a.Password.Equals(userLogin.Password)).FirstOrDefault();
if (login != null)
{
Person session = _context.Person.SingleOrDefault(u => u.UserID == userLogin.UserID);
session.Active = 1;
HttpContext.Session.SetString("FullName", login.FullName);
HttpContext.Session.SetString("UserID", login.UserID);
_context.SaveChanges();
return RedirectToAction("Index", "User");
}
else
{
ViewBag.ErrMsg = "Invalid Credentials";
return View();
}
}
}
及其视图
@model Person
@{
ViewData["Title"] = "UserLogin";
Layout = "~/Views/Shared/LoginLayout.cshtml";
}
<h1>Welcome!</h1>
<h4>Enter Credentials</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="UserLogin">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserID" class="control-label">User ID</label>
<input asp-for="UserID" class="form-control" />
<span asp-validation-for="UserID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label">Password</label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Login" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
New User? <a asp-action="Signup">Signup</a>
</div>
什么是
<span class="text-danger">@ViewBag.SearchFail</span>
我在你的操作中看不到 ViewBag.SearchFail 或 ViewBag.ErrMessage。
你有一个大错误。将重定向从索引视图移至操作,否则在创建页面后它将始终 运行。
public ActionResult Index()
{
if (Context.Session.GetString("FullName") != null)
{
List<Tweet> tweets = _twitter.TweetList();
.....
return View("Index", tweets);
}
RedirectToAction("Login", "Users")
}
由于两者使用的是同一型号,请尝试更换
@Html.PartialAsync("TwitterList",Model)
和
<partial name="TwitterList" />
并修复两个视图的模型
@model List<TwitterClone.Models.Tweet>
同时修复局部视图
@if(@Model!=null && Model.Count >0)
{
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model[0].User_ID)
</th>
<th>
@Html.DisplayNameFor(model => model[0].Message)
</th>
......
}