如何在MVC中刷新页面
本文关键字:刷新 MVC | 更新日期: 2023-09-27 18:09:38
我发现我的页面实际上是重新加载/刷新,但需要额外重新加载才能看到我刚刚添加的内容。但是,我必须再次重新加载以查看数据,或添加另一个数据以查看以前的数据。
我在下面添加了控制器代码:
(CreateComment和Comment(显示注释)在Details(Details about book) View )
CreateComment :
public ActionResult CreateComment(Guid id) {
return View(new CommentToBook { BookId = id });
}
[HttpPost]
public ActionResult CreateComment(CommentToBookVm model) {
if (ModelState.IsValid) {
var m = new CommentToBook { Comment = model.Comment, BookId = model.BookId };
m.UserId = new Guid(Session["UserID"].ToString());
m.CreatedDate = DateTime.Now;
db.CommentToBooks.Add(m);
db.SaveChanges();
}
return View(model);
}
查看createComment
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(s => s.BookId)
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Comment, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Comment, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Comment, "", 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>
Details(里面有Comment和CreateComment)
public ActionResult Details(Guid? id) {
Book book = db.Books.Find(id);
return View(book);
}
视图<h2>Details</h2>
@Html.Action("Rating", new { id = Model.Id })
<div>
<h4>Books</h4>
<hr/>
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Title)
</dt>
<dd>
@Html.DisplayFor(model => model.Title)
</dd>
@*and so on...*@
</dl>
</div>
@Html.Action("Comment", new { id = Model.Id })
@Html.Action("CreateComment", new { id = Model.Id })
和Comment来列出所有的注释。
public ActionResult Comment(Guid? id) {
var comment = db.CommentToBooks.Where(c => c.BookId == id);
return View(comment.ToList());
}
视图:
<table class="table">
<tr>
<th>
User
</th>
<th>
@Html.DisplayNameFor(model => model.Comment)
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.ActionLink(item.User.UserName, "VisitUser", new { id = item.UserId })
</td>
<td>
@Html.DisplayFor(modelItem => item.Comment)
</td>
</tr>
}
</table>
我想这是关于我在控制器中返回的东西,我尝试了一些不同的选择,但我最终遇到了错误:
Description:
当前事件执行过程中发生了未处理的异常web请求。有关的更多信息,请查看堆栈跟踪错误和它在代码中的起源。
Exception Details: System。NullReferenceException:对象引用不存在设置为对象的实例。
源错误:
第9行:@HtmlAction("Comment", new {id = Model。Id})
或
子操作不允许执行重定向操作。
如果我尝试用RedirectToAction
代替CreateComment
等
我将欣赏代码的例子,因为我发现很难理解新的概念,仅仅通过文字。
您的代码正在返回CreateComment
方法的视图。看起来您将此操作方法标记为仅ChildActions
。您不应该在这样的用例中使用ChildAction。应该使用ChildActions来向视图呈现某些内容。例如:应用程序中的菜单栏。
即使您从CreateComment动作方法中删除[ChildAction]
,当您将模型返回到表单时,它将呈现由CreateComment视图生成的标记。这意味着您将丢失注释列表(在调用Details视图时加载)。
理想情况下,对于所有数据插入用例,您应该遵循 p - r - g 模式。
PRG代表文章 - 重定向 - 得到。这意味着,您提交了一个表单,在成功地将数据保存到db后,您返回一个重定向结果给客户端,客户端(浏览器)将发出一个全新的http请求,请求GET操作方法,您将在其中查询db表并返回结果。
但是,由于您的表单是通过调用Html.Action
方法加载到主视图的,因此您将无法获得所需的结果(同一视图中的评论列表和验证消息)。让它工作的一件事是,启用不显眼的客户端验证。在这种情况下,表单实际上不会提交给服务器。相反,客户端验证将被调用,验证消息将在同一页面中显示给用户(不重新加载页面!)。
您可以通过在视图(或布局)中添加对这两个脚本的引用来启用它
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
重定向到GET操作,在成功保存发布的评论后显示所有评论。
[HttpPost]
public ActionResult CreateComment(CommentToBookVm model)
{
if (ModelState.IsValid)
{
//your existing code to save data to the table
return RedirectToAction("Details","Book", new { id=model.BookId} );
}
// Hoping that the below code might not execute as client side validation
// must have prevented the form submission if there was a validation error.
return View(model);
}
另一个不依赖于客户端验证的选项是创建一个平面视图模型,其中包含新评论表单的现有评论和属性列表。当您提交表单时,如果验证失败,则重新加载Comments属性并将视图模型返回给表单。
public class ListAndCreateVm
{
[Required]
public string NewComment { set;get;}
public Guid BookId { set;get;}
public List<CommentVm> Comments { set;get;}
}
public class CommentVm
{
public string Comment { set;get;}
public string Author { set;get;}
}
在Details操作中,加载Comments并将其发送给视图
public ActionResult Details(Guid id)
{
var vm = new ListAndCreateVm { BookId= id};
vm.Comments = GetComments(id);
return View(vm);
}
private List<CommentVm> GetComments(Guid bookId)
{
return db.CommentToBooks.Where(c => c.BookId == bookId)
.Select(x=> new CommentVm { Comment = x.Comment})
.ToList();
}
和在你的视图
@model ListAndCreateVm
@foreach(var c in Model.Comments)
{
<p>@c.Comment</p>
}
<h4>Create new comment</h4>
@using(Html.BeginForm())
{
@Html.ValidationSummary(false, "", new {@class = "text-danger"})
@Html.TextBoxFor(s=>s.NewComment)
@Html.HiddenFor(f=>f.BookId)
<input type="submit" />
}
现在,除了使用PRG模式外,请确保在模型验证失败时重新加载视图模型的Comments属性
[HttpPost]
public ActionResult Details(ListAndCreateVm model)
{
if(ModelState.IsValid)
{
// to do : Save
return RedirectToAction("Details,"Book",new { id=model.BookId});
}
//lets reload comments because Http is stateless :)
model.Comments = GetComments(model.BookId);
return View(model);
}