繁体   English   中英

如何在MVC中刷新页面

[英]How to refresh a page in MVC

我发现我的页面实际上是重新加载/刷新的,但是需要重新加载才能看到我刚刚添加的内容。 不过,我已经再次重新加载看到的数据, 添加其他数据,看看以前的数据..

我在下面添加了我的控制器代码:

(CreateCommentComment (显示评论)在Details (关于书的详细信息)内部

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>

详细信息(在内部具有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 })

和评论列出所有评论。

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请求的执行期间发生未处理的异常。 请查看堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。

异常详细信息:System.NullReferenceException:对象引用未设置为对象的实例。

源错误:

第9行:@ Html.Action(“ Comment”,新的{id = Model.Id})

要么

子操作不允许执行重定向操作。

如果我尝试RedirectToAction for CreateComment等。

我将欣赏一个代码示例,因为我发现仅凭单词很难理解新概念。

您的代码将返回CreateComment方法的视图。 看起来您已将此操作方法标记为“仅ChildActions 您不应该将ChildAction用于这样的用例。 应该使用ChildActions向视图呈现某些内容。 例如:应用程序中的菜单栏。

即使从CreateComment操作方法中删除了[ChildAction] ,当您将模型返回到窗体时,它仍将呈现由CreateComment视图生成的标记。 这意味着您将松散注释列表(调用“详细信息”视图时已加载)。

理想情况下,对于所有数据插入用例,都应遵循PRG模式。

PRG代表POST - REDIRECT - GET 这意味着,您提交表单,然后将数据成功保存到db后,您确实将重定向结果返回给客户端,并且客户端(浏览器)将对GET操作方法发出全新的http请求,您将在其中查询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);
}

不依赖客户端验证的另一个选项是创建一个平面视图模型,该模型具有现有注释列表和新注释表单的属性。 提交表单时,如果验证失败,请再次重新加载Comment属性,然后将视图模型返回到表单。

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;}
}

然后在您的“详细信息”操作中,加载“评论”并将其发送到视图

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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM