C#ASP.NET MVC返回上一页

Jas*_*chs 65 c# asp.net-mvc asp.net-mvc-4

我的控制器中有一个基本的Edit方法,当编辑成功时,它会重定向回顶级列表("Index").MVC脚手架后的标准行为.

我正在尝试更改此Edit方法以重定向回上一页(而不是索引).由于我的Edit方法没有使用默认的映射输入参数"id",我首先尝试使用它来传入上一个URL.

在我的编辑"获取"方法中,我使用此行来获取以前的URL并且它工作正常:

ViewBag.ReturnUrl = Request.UrlReferrer;
Run Code Online (Sandbox Code Playgroud)

然后,我使用我的表单标记将此返回URL发送到编辑"post"方法,如下所示:

@using (Html.BeginForm(new { id = ViewBag.ReturnUrl }))
Run Code Online (Sandbox Code Playgroud)

现在轮到这里了.我无法正确获取从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);
    }
Run Code Online (Sandbox Code Playgroud)

现在我使用表单中的隐藏字段将returnUrl参数从Model传递给[HttpPost]方法:

@using (Html.BeginForm())
{
    <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
    ...
Run Code Online (Sandbox Code Playgroud)

在[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);
    }
Run Code Online (Sandbox Code Playgroud)

Gar*_*and 54

我假设(请纠正我,如果我错了)你想重新显示编辑页面如果编辑失败并且这样做你正在使用重定向.

您可以通过再次返回视图而不是尝试重定向用户来获得更多运气,这样您就可以使用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);
   }
}
Run Code Online (Sandbox Code Playgroud)

您的视图的BeginForm方法也不需要使用此返回URL,您应该能够逃脱:

@model ViewModel

@using (Html.BeginForm())
{
    ...
    <input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" />
}
Run Code Online (Sandbox Code Playgroud)

回到您的表单操作过帐到错误的URL,这是因为您将URL作为'id'参数传递,因此路由会自动使用返回路径格式化您的URL.

这不起作用,因为您的表单将发布到不知道如何保存编辑的控制器操作.您需要先发布到保存操作,然后在其中处理重定向.


小智 5

我知道这已经很晚了,但也许这会对其他人有所帮助。

我使用“取消”按钮返回到引用网址。在视图中,尝试添加以下内容:

@{
  ViewBag.Title = "Page title";
  Layout = "~/Views/Shared/_Layout.cshtml";

  if (Request.UrlReferrer != null)
  {
    string returnURL = Request.UrlReferrer.ToString();
    ViewBag.ReturnURL = returnURL;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样设置按钮 href:

<a href="@ViewBag.ReturnURL" class="btn btn-danger">Cancel</a>
Run Code Online (Sandbox Code Playgroud)

除此之外,Jason Enochs 的更新效果非常好!