一种处理MVC环境中的返回URL的智能方法

时间:2011-09-12 01:57:57

标签: asp.net-mvc returnurl

在用户运行某些操作(例如单击“返回...”链接或保存他们正在编辑的记录)后,我反复遇到的问题是处理重定向到上一页。

以前每当我需要知道要返回的页面时,我都会在当前视图中提供returnURL参数。

http://blah.com/account/edit/1?returnURL="account/index"

这不是处理这种情况的非常简洁的方法,因为有时返回URL包含搜索字符串等参数,这些参数必须包含在URL中。

http://blah.com/account/edit/1?returnURL="account/index?search="searchTerm""

此外,如果用户在返回包含returnURL的网页之前可以转发其他网页,则会产生问题,因为您必须将returnURL传递给所有访问过的网页。

简单地调用浏览器的Back功能也不够,因为您可能希望页面刷新,例如显示您刚刚在上一页保存的编辑内容。

所以我的问题是,有没有人找到一种聪明的方法来处理这种情况,特别是在MVC环境中?

注意:我正在使用ASP .NET MVC,如果可能的话,我希望得到与之相关的答案,但欢迎任何想法。

10 个答案:

答案 0 :(得分:12)

设置cookie或使用会话变量有什么问题?如果您不控制调用您的页面,那么您唯一的理由是,在这种情况下,您唯一的选项是查询字符串,帖子值或引荐来源。

答案 1 :(得分:3)

我想我可以在问题中添加我的答案,看看其他人是否认为这是一个好主意。

我只是使用TempViewData将其传递给控制器​​:

@{
   TempData["returnURL"] = Request.Url.AbsoluteUri;
}

然后以与此类似的方式访问它(在我的真实版本中,我检查密钥是否在TempData中并且returnURL是真实的网址):

return Redirect(TempData["returnURL"].ToString());

如果它需要继续第一页更改(即搜索页面 - >编辑页面 - >编辑部分页面)我再次添加

TempData["returnURL"] = TempData["returnURL"];

答案 2 :(得分:2)

查看我的博文:Using cookies to control return page after login on asp.net mvc 3

就像@Mystere Man提到的那样,你可以使用cookie或会话。我刚才遇到类似的情况时,我回去了。

答案 3 :(得分:1)

尝试注册网址为/{controller}/{action}/{id}/returnurl/{*url}的新路由,然后在接受 url 作为参数的操作中使用RedirectToAction

答案 4 :(得分:1)

Request.UrlReferrer.AbsoluteUri

虽然我仍然认为你不应该创建自己的“后退”按钮。

答案 5 :(得分:1)

使用拦截器或方面:

  1. 以某种方式拦截每个请求(例如,@Before方面)并将请求的URL保存到会话中,每次都覆盖它
  2. 在您的视图层中,根据需要访问该Session对象,在您的情况下为反向链接访问。
  3. 如果您想使用它,这种设计可让您始终拥有最新的请求。 Here's an example在.NET中编写方面/拦截器。另外,PostSharp是一个.NET方面项目。

答案 6 :(得分:1)

目前,我找不到一种快速而肮脏的方法......所以我正在使用一种实用的方法。

在概念层面上,页面的“可追溯性”应由您当前所在的页面决定。如果Controller中捕获的参数通过ViewModel传递给它,View可以推断出这种情况(在大多数情况下)。

示例:

访问Foo后,我将Bar查看某些内容,后退按钮应返回Foo

控制器

public ActionResult Foo(string fooId) // using a string for your Id, good idea; Encryption, even better.
{
    FooModel model = new FooModel() { fooId = fooId }; // property is passed to the Model - important.
    model.Fill();
    return View("FooView", model);
}

public ActionResult Bar(string fooId, string barId)
{
    BarModel model = new BarModel() { fooId = fooId; barId = barId };
    model.Fill()
    return View("BarView", model)
}

的ViewModels

public class FooModel
{
    public string fooId { get; set; }

    public void Fill()
    {
        // Get info from Repository.
    }
}

public class BarModel
{
    public string fooId { get; set; }
    public string barId { get; set; }

    public void Fill()
    {
        // Get info from Repository.
    }
}

查看(部分) // No pun intended... or maybe it was. :)

您的BarView现在可以从其模型中解读它需要返回的位置(使用fooId)。

在BarView上(使用MVC2语法):

<a href="<%= string.Format("/Foo?fooId={0}", Model.fooId) %>">Back</a>

您也可以使用Html.ActionLink。

<强>可替换地:

您可以从BaseViewModel继承您的ViewModel,它可以具有受保护的属性returnURL。必要时设置它。

示例:

在您的ViewModel上:

public class BarModel : BaseViewModel
{
    public string fooId { get; set; }
    public string barId { get; set; }

    public void Fill()
    {
        returnURL = string.Format("/Foo?fooId={0}", fooId)
        // Get info from Repository.
    }
}

观看视频:

<a href="<%=returnURL %>">Back</a>

答案 7 :(得分:1)

通过显示部分操作可以更好地处理这一点,而不会离开页面并使用JQuery来创建对话框/向导工作流程吗?

然后您只需对对话框中的“完成”按钮作出反应即可刷新原始视图。

答案 8 :(得分:1)

关于“保存他们正在编辑的记录”的问题部分,我认为重定向后获取(PGR)模式适用于您。

如果你不熟悉它,这可能是一个阅读它的好地方。

答案 9 :(得分:-1)

  1. 使用Url.Encode(returnUrl)对returnUrl进行编码,以包含在网址中。
  2. 准备好重定向时,请使用Url.Decode(returnUrl)并使用实际重定向的值。