C#ASP.NET MVC返回上一页
在我的控制器中有一个基本的Edit方法,当编辑成功时,它redirect回顶层列表(“Index”)。 MVC脚手架之后的标准行为。
我试图改变这个编辑方法redirect回到上一页(而不是索引)。 由于我的编辑方法没有使用默认的映射input参数“id”,我第一次尝试使用它来传递前一个URL。
在我的Edit“get”方法中,我使用这一行来获取前一个URL,它工作正常:
ViewBag.ReturnUrl = Request.UrlReferrer;
然后,我通过使用我的表单标签,如下所示发送此返回的URL到编辑“后”方法:
@using (Html.BeginForm(new { id = ViewBag.ReturnUrl }))
现在轮子掉下来了。 我无法正确地得到从id参数parsing的URL。
*** 更新:已解决 ** *
使用Garry的示例作为指导,我将参数从“id”更改为“returnUrl”,并使用隐藏字段来传递我的参数(而不是表单标签)。 获得的经验:只有使用“id”参数才能使用它,并保持简单。 它现在有效。 这里是我更新的代码与笔记:
首先,我像第一次那样使用Request.UrlReferrer获取前一个URL。
// // GET: /Question/Edit/5 public ActionResult Edit(int id) { Question question = db.Questions.Find(id); ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId); ViewBag.Answers = db.Questions .AsEnumerable() .Select(d => new SelectListItem { Text = d.Text, Value = d.QuestionId.ToString(), Selected = question.QuestionId == d.QuestionId }); // Grab the previous URL and add it to the Model using ViewData or ViewBag ViewBag.returnUrl = Request.UrlReferrer; ViewBag.ExamId = db.Domains.Find(question.DomainId).ExamId; ViewBag.IndexByQuestion = string.Format("IndexByQuestion/{0}", question.QuestionId); return View(question); }
现在我使用以下forms的隐藏域将模型中的returnUrlparameter passing给[HttpPost]方法:
@using (Html.BeginForm()) { <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" /> ...
在[HttpPost]方法中,我们从隐藏字段中拉取参数,并redirect到….
// // POST: /Question/Edit/5 [HttpPost] public ActionResult Edit(Question question, string returnUrl) // Add parameter { int ExamId = db.Domains.Find(question.DomainId).ExamId; if (ModelState.IsValid) { db.Entry(question).State = EntityState.Modified; db.SaveChanges(); //return RedirectToAction("Index"); return Redirect(returnUrl); } ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId); return View(question); }
我假设(请纠正我,如果我错了),如果编辑失败,你想重新显示编辑页面,并做到这一点,你正在使用redirect。
你可能有更多的运气,只是再次返回视图,而不是试图redirect用户,这样你就可以使用ModelState来输出任何错误。
编辑:
根据反馈进行更新。 您可以将之前的URL放在viewModel中,将其添加到隐藏字段中,然后在保存编辑的操作中再次使用它。
例如:
public ActionResult Index() { return View(); } [HttpGet] // This isn't required public ActionResult Edit(int id) { // load object and return in view ViewModel viewModel = Load(id); // get the previous url and store it with view model viewModel.PreviousUrl = System.Web.HttpContext.Current.Request.UrlReferrer; return View(viewModel); } [HttpPost] public ActionResult Edit(ViewModel viewModel) { // Attempt to save the posted object if it works, return index if not return the Edit view again bool success = Save(viewModel); if (success) { return RedirectToAction(viewModel.PreviousUrl); } else { ModelState.AddModelError("There was an error"); return View(viewModel); } }
你的视图的BeginForm方法不需要使用这个返回的URL,你应该能够逃避:
@model ViewModel @using (Html.BeginForm()) { ... <input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" /> }
回到表单动作发布到一个不正确的URL,这是因为你传递一个URL作为'id'参数,所以路由会自动使用返回path格式化你的URL。
这将无法正常工作,因为您的表单将张贴到不知道如何保存编辑的控制器操作。 您需要先发布到您的保存操作,然后处理其中的redirect。