在用户运行某些操作(例如单击“返回...”链接或保存他们正在编辑的记录)后,我反复遇到的问题是处理重定向到上一页。
以前每当我需要知道要返回的页面时,我都会在当前视图中提供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,如果可能的话,我希望得到与之相关的答案,但欢迎任何想法。
答案 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)
使用拦截器或方面:
@Before
方面)并将请求的URL保存到会话中,每次都覆盖它如果您想使用它,这种设计可让您始终拥有最新的请求。 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)
Url.Encode(returnUrl)
对returnUrl进行编码,以包含在网址中。Url.Decode(returnUrl)
并使用实际重定向的值。