C#ASP.NETMVC如何返回到以前的页面?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (435)

在我的控制器中有一个基本的编辑方法,当编辑成功时,它会重定向回顶层列表(“索引”)。MVC脚手架后的标准行为。

我试图改变这个编辑方法重定向回到前一页(而不是索引)。由于我的Edit方法没有使用默认的映射输入参数“id”,所以我首先尝试使用它来传递前一个URL。

在我的Edit“get”方法中,我使用这一行来获取前一个URL,它工作正常:

ViewBag.ReturnUrl = Request.UrlReferrer;

然后,我通过使用我的表单标签将此返回URL发送到Edit“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);
    }
提问于
用户回答回答于

如果编辑失败,我假设(如果我错了,请纠正我)要重新显示编辑页面,并执行此操作以使用重定向。

可以通过再次返回视图而不是尝试重定向用户来获得更多运气,这样就可以使用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'参数,因此路由会自动使用返回路径格式化您的URL。

这是行不通的,因为表单将张贴到控制器操作中,不知道如何保存编辑。需要先发布到保存操作,然后处理其中的重定向。

扫码关注云+社区