在我的应用程序中,我将对象存储到会话中,该会话传递给Web服务以返回要在表中显示的数据。如果会话存在,则它不会要求用户输入新数据。但是,如果用户选择名为" New List"的链接,则会清除会话数据并提示用户输入新数据。
在我的代码中,我有一个像这样定义的锚:
<a href="@Url.Action("NewList", "Alert")"> New List</a>
将触发此控制器操作:
public ActionResult NewList()
{
Session["new_list"] = "y";
return RedirectToAction("List");
}
然后继续执行此操作:
public ActionResult List()
{
if ((string)Session["new_list"] == "y")
{
//clear session variables, load fresh data from API
}else{
//display blank table. Ask user to input data to retrieve a list
}
....
}
现在,我遇到的问题是当用户离开列表页面,然后使用浏览器的后退按钮导航回来时,它仍在调用newlist
。在浏览器的历史记录中,不是存储List
,而是存储导致会话变量清除的newlist
。我该怎么做才能阻止这种情况发生,或者在c#mvc中使用不同的机制可以帮助我达到预期的效果。
答案 0 :(得分:1)
这里的主要问题是NewList操作使用 GET 时应该是 POST 。
GET 请求永远不应该改变资源的状态,而只是返回资源的当前状态;而 POST 请求允许更改资源。
因为您允许使用GET请求调用NewList操作,所以用户的浏览器假设(非常正确地说)如果它在将来简单地重复请求,则不会发生任何不良/不希望的事情,例如,当用户使用后退按钮时。
如果发出POST请求,用户浏览器将永远不会重新发出请求,而用户不会确认他们确实要重新发出请求。
问题的解决方案是将其修改为标准 PRG 模式: POST / Redirect / GET ;也就是说,发送POST请求以执行状态更改,将用户浏览器重定向到另一个页面,然后获取结果页面。在这个方案中,按下后退按钮将有效地跳过&#34;跳过&#34;通过状态更改操作并转到用户所在的上一页。
要在MVC中完成此任务:
[HttpPost]
public ActionResult NewList()
{
//clear session variables, load fresh data from API
return RedirectToAction("List");
}
public ActionResult List()
{
// whatever needs to happen to display the state
}
这意味着您无法提供&#34;新列表&#34;直接作为页面中的超链接操作,因为这些将始终发出GET请求。您需要使用这样的最小形式:<form method="post" action="@Url.Action("NewList", "Alert")"><button type="submit">New List</button></form>
。您可以根据需要将按钮设置为看起来像普通超链接。
答案 1 :(得分:0)
存储NewList的原因是因为您正在重定向到“Alert / NewList”,并且其URL中的字符串用于命中“NewList”操作,因此每当您尝试返回按钮时,浏览器都会获得此“警报/ NewList“URL,因此它打击动作”NewList“。 但现在,我不知道为什么会议变得清晰。因为您正在“NewList”本身初始化会话。我仍然建议您使用本地存储来为会话分配值。