【问题标题】:How do I redirect to the previous action in ASP.NET MVC?如何重定向到 ASP.NET MVC 中的上一个操作?
【发布时间】:2010-10-23 08:21:16
【问题描述】:

假设我有一些页面

  • some.web/articles/details/5
  • some.web/users/info/bob
  • some.web/foo/bar/7

可以调用通用的实用程序控制器,如

locale/change/esauthorization/login

如何让这些方法(changelogin)重定向到之前的操作(detailsinfobar),同时将之前的参数传递给它们(5、@ 987654332@,7)?

简而言之:如何在另一个控制器中执行操作后重定向到我刚刚访问的页面?

【问题讨论】:

    标签: asp.net-mvc routing redirect


    【解决方案1】:

    尝试:

    public ActionResult MyNextAction()
    {
        return Redirect(Request.UrlReferrer.ToString());
    }
    

    或者,谈到达林所说的,试试这个:

    public ActionResult MyFirstAction()
    {
        return RedirectToAction("MyNextAction",
            new { r = Request.Url.ToString() });
    }
    

    然后:

    public ActionResult MyNextAction()
    {
        return Redirect(Request.QueryString["r"]);
    }
    

    【讨论】:

    • 只是一个建议:你可以明确地使用“重定向”来对你的控制器进行单元测试。你最好改用“RedirectToAction”。
    • 我建议使用Request.Url.AbsolutePath.ToString(),因为AccountControllerLogOn 方法包含对以'/' 开头的URL 等的检查。
    • @gotnull Request.Url.AbsolutePath 将重定向到相同的操作。这不是所需的输出。我们必须回到倒数第二个动作。为此我们可以这样写: return Redirect(ControllerContext.HttpContext.Request.UrlReferrer.ToString());
    • @nathanridley:这不适用于 POST 请求。假设用户在GET Index 然后GET Edit。然后,引荐 URL 是 Index,但是当用户执行 POST Edit 时,引荐来源现在是来自前面 GET 请求的 Edit。如何确保 POST Edit 知道将用户引至 GET Edit 的 URL?
    • UrlReferrer 为 NULL 当我在某个页面并想查看时,我知道只需在地址栏中输入 URL 就会出错。为什么我在地址栏中输入 URL 时无法确定 UrlReferrer?
    【解决方案2】:

    如果您想从视图中的按钮重定向,您可以使用:

    @Html.ActionLink("Back to previous page", null, null, null, new { href = Request.UrlReferrer})
    

    【讨论】:

      【解决方案3】:

      如果您不关心单元测试,那么您可以简单地编写:

      return Redirect(ControllerContext.HttpContext.Request.UrlReferrer.ToString());
      

      【讨论】:

        【解决方案4】:

        关于如何做到这一点的建议:

        1. 返回 url 在表单的 POST 请求(以及任何失败的验证)中仍然存在
        2. 返回 url 由初始推荐 url 确定
        3. 不使用 TempData[] 或其他服务器端状态
        4. 处理对操作的直接导航(通过提供默认重定向)

        .

        public ActionResult Create(string returnUrl)
        {
            // If no return url supplied, use referrer url.
            // Protect against endless loop by checking for empty referrer.
            if (String.IsNullOrEmpty(returnUrl)
                && Request.UrlReferrer != null
                && Request.UrlReferrer.ToString().Length > 0)
            {
                return RedirectToAction("Create",
                    new { returnUrl = Request.UrlReferrer.ToString() });
            }
        
            // Do stuff...
            MyEntity entity = GetNewEntity();
        
            return View(entity);
        }
        
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(MyEntity entity, string returnUrl)
        {
            try
            {
                // TODO: add create logic here
        
                // If redirect supplied, then do it, otherwise use a default
                if (!String.IsNullOrEmpty(returnUrl))
                    return Redirect(returnUrl);
                else
                    return RedirectToAction("Index");
            }
            catch
            {
                return View();  // Reshow this view, with errors
            }
        }
        

        您可以像这样在视图中使用重定向:

        <% if (!String.IsNullOrEmpty(Request.QueryString["returnUrl"])) %>
        <% { %>
            <a href="<%= Request.QueryString["returnUrl"] %>">Return</a>
        <% } %>
        

        【讨论】:

          【解决方案5】:

          在 Mvc 中使用纯 html 在视图页面中和 java 脚本 onclick

          <input type="button" value="GO BACK" class="btn btn-primary" 
          onclick="location.href='@Request.UrlReferrer'" />
          

          这很好用。希望对某人有所帮助。

          @JuanPieterse 已经使用@Html.ActionLink 进行了回答,因此如果可能的话,有人可以使用@Url.Action 进行评论或回答

          【讨论】:

            【解决方案6】:

            我正在使用 .Net Core 2 MVC ,这个对我有用, 在控制器使用中 HttpContext.Request.Headers["Referer"];

            【讨论】:

              【解决方案7】:

              将 returnUrl 参数(url 编码)传递给 changelogin 操作,并在内部重定向到这个给定的 returnUrl。您的登录操作可能如下所示:

              public ActionResult Login(string returnUrl) 
              {
                  // Do something...
                  return Redirect(returnUrl);
              }
              

              【讨论】:

                【解决方案8】:

                您可以使用ViewBag.ReturnUrl 属性返回上一页。

                【讨论】:

                  【解决方案9】:

                  要在任何视图中动态构造 returnUrl,试试这个:

                  @{
                      var formCollection =
                          new FormCollection
                              {
                                  new FormCollection(Request.Form),
                                  new FormCollection(Request.QueryString)
                              };
                  
                      var parameters = new RouteValueDictionary();
                  
                      formCollection.AllKeys
                          .Select(k => new KeyValuePair<string, string>(k, formCollection[k])).ToList()
                          .ForEach(p => parameters.Add(p.Key, p.Value));
                  }
                  
                  <!-- Option #1 -->
                  @Html.ActionLink("Option #1", "Action", "Controller", parameters, null)
                  
                  <!-- Option #2 -->
                  <a href="/Controller/Action/@object.ID?returnUrl=@Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), parameters)">Option #2</a>
                  
                  <!-- Option #3 -->
                  <a href="@Url.Action("Action", "Controller", new { object.ID, returnUrl = Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), parameters) }, null)">Option #3</a>
                  

                  这也适用于布局页面、部分视图和 Html 助手

                  相关:MVC3 Dynamic Return URL(相同,但来自任何控制器/操作)

                  【讨论】:

                    【解决方案10】:

                    对于 ASP.NET Core 你可以使用 asp-route-* 属性:

                    <form asp-action="Login" asp-route-previous="@Model.ReturnUrl">
                    

                    其他详细示例: 想象一下,您有一个带有动作的车辆控制器

                    索引

                    详情

                    编辑

                    并且您可以从索引或详细信息中编辑任何车辆,因此如果您单击从索引编辑,您必须在编辑后返回索引 如果您从详细信息中单击编辑,则必须在编辑后返回到详细信息。

                    //In your viewmodel add the ReturnUrl Property
                    public class VehicleViewModel
                    {
                         ..............
                         ..............
                         public string ReturnUrl {get;set;}
                    }
                    
                    
                    
                    Details.cshtml
                    <a asp-action="Edit" asp-route-previous="Details" asp-route-id="@Model.CarId">Edit</a>
                    
                    Index.cshtml
                    <a asp-action="Edit" asp-route-previous="Index" asp-route-id="@item.CarId">Edit</a>
                    
                    Edit.cshtml
                    <form asp-action="Edit" asp-route-previous="@Model.ReturnUrl" class="form-horizontal">
                            <div class="box-footer">
                                <a asp-action="@Model.ReturnUrl" class="btn btn-default">Back to List</a>
                                <button type="submit" value="Save" class="btn btn-warning pull-right">Save</button>
                            </div>
                        </form>
                    

                    在您的控制器中:

                    // GET: Vehicle/Edit/5
                        public ActionResult Edit(int id,string previous)
                        {
                                var model = this.UnitOfWork.CarsRepository.GetAllByCarId(id).FirstOrDefault();
                                var viewModel = this.Mapper.Map<VehicleViewModel>(model);//if you using automapper
                        //or by this code if you are not use automapper
                        var viewModel = new VehicleViewModel();
                    
                        if (!string.IsNullOrWhiteSpace(previous)
                                    viewModel.ReturnUrl = previous;
                                else
                                    viewModel.ReturnUrl = "Index";
                                return View(viewModel);
                            }
                    
                    
                    
                    [HttpPost]
                        public IActionResult Edit(VehicleViewModel model, string previous)
                        {
                                if (!string.IsNullOrWhiteSpace(previous))
                                    model.ReturnUrl = previous;
                                else
                                    model.ReturnUrl = "Index";
                                ............. 
                                .............
                                return RedirectToAction(model.ReturnUrl);
                        }
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-06-22
                      • 1970-01-01
                      • 2014-12-31
                      • 2013-02-13
                      相关资源
                      最近更新 更多