我的 Controller 中有一个基本的编辑方法,当编辑成功时,它会重定向回顶级列表(“索引”)。 MVC 脚手架后的标准行为。
我正在尝试更改此编辑方法以重定向回上一页(不是索引)。由于我的 Edit 方法没有使用默认的映射输入参数“id”,我首先尝试使用它来传递之前的 URL。
在我的编辑“get”方法中,我使用这一行来获取以前的 URL,它工作正常:
ViewBag.ReturnUrl = Request.UrlReferrer;
然后我使用我的表单标签将此返回 URL 发送到编辑“post”方法,如下所示:
@using (Html.BeginForm(new { id = ViewBag.ReturnUrl }))
现在这是轮子掉下来的地方。我无法从 id 参数中正确解析 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);
}
我现在使用表单中的隐藏字段将 returnUrl 参数从模型传递到 [HttpPost] 方法:
@using (Html.BeginForm())
{
<input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
...
在 [HttpPost] 方法中,我们从隐藏字段中提取参数并重定向到它....
//
// 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);
}
最佳答案
我假设(如果我错了请纠正我)如果编辑失败你想重新显示编辑页面并且要做到这一点你正在使用重定向。
与尝试重定向用户相比,再次返回 View 可能会更幸运,这样您也可以使用 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 Redirect(viewModel.PreviousUrl);
}
else
{
ModelState.AddModelError("There was an error");
return View(viewModel);
}
}
您的 View 的 BeginForm 方法也不需要使用此返回 URL,您应该能够逃脱:
@model ViewModel
@using (Html.BeginForm())
{
...
<input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" />
}
回到您的表单操作发布到错误的 URL,这是因为您将 URL 作为“id”参数传递,因此路由会自动使用返回路径格式化您的 URL。
这将不起作用,因为您的表单将发布到不知道如何保存编辑的 Controller 操作。您需要先发布到您的保存操作,然后在其中处理重定向。
关于C# ASP.NET MVC 返回上一页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9772947/