2012-04-10 84 views
6

我有一个在我的MVC应用程序中设置的会话变量。无论何时该会话过期并且用户尝试刷新它们所在的页面,该页面都将引发错误,因为会话不再设置。MVC等效于Page_Load

是否有任何地方可以检查加载视图之前是否设置了会话?也许把一些东西放在Global.asax文件中?

我可以在每个ActionResult的开头都做这样的事情。

public ActionResult ViewRecord() 
{ 
    if (MyClass.SessionName == null) 
    { 
     return View("Home"); 
    } 
    else 
    { 
     //do something with the session variable 
    } 
} 

有没有其他办法可以做到这一点? 在这种情况下最佳做法是什么?

+1

你需要一个自定义操作过滤器,一些更多的信息的http:// MSDN .microsoft.com/zh-cn/gg618482 – 2012-04-10 14:49:00

+0

此处的类似讨论:http://forums.asp.net/t/1287687.aspx – 2012-04-10 14:49:44

+0

除了@ ChrisDiver的评论,如果您需要将它应用于所有控制器/操作,你可以装饰一个基地控制器,从其中你所有的其他控制器继承。 – Chris 2012-04-10 15:03:10

回答

0

首先,你应该重定向到首页,而不是返回主页视图,否则你有主页显示的奇怪的情况,尽管Url在别的地方。

其次,会话永远不会为空,因为当旧会话过期或重置时会创建新会话。你会改为检查你的变量,如果THAT为空,那么你知道会话是新的。

第三,如果你的应用依赖于这个会话数据,那么我根本不会使用会话。你用这个来缓存数据吗?如果是这样,那么使用缓存可能是一个更好的选择(当缓存项目到期时,您的应用会得到通知)。

不幸的是,这可能是The XY Problem的一种情况。您有问题,并且您认为会话解决了您的问题,但是您遇到了与会话不同的问题,因此您正在问如何解决会话问题,而不是如何解决会话尝试解决的问题。

你试图用这个解决的实际问题是什么?

编辑:

根据您在下面的评论,你为什么不通过URL传递客户编号:

http://website/Controller/ViewRecord/3 

public ActionResult ViewRecord(int id) 
{ 
    // do whatever you need to do with the customer ID 
} 
+0

Web应用程序允许搜索客户。我们根据他们的ID号选择一个客户。我正在设置该ID号码有一个会话。这里是我做的:'\t \t公共静态字符串CIF \t \t { \t \t \t得到 \t \t \t { \t \t \t \t如果(HttpContext.Current.Session [ “到岸价格”] == NULL) \t \t \t \t \t return“”; 。 \t \t \t \t别的 \t \t \t \t \t返回HttpContext.Current.Session [ “CIF”]的ToString(); \t \t \t} \t \t \t集合{HttpContext.Current.Session [ “CIF”] =值; } \t \t} - 然后在View上,我调用MyClass.CIF来获取Session的值。 – Turp 2012-04-10 18:01:06

+0

@Turp - 您为什么需要将客户添加到会话中?为什么不在网址中传递客户号码?然后,该值不会存储在会话中,并且在您不再需要时会消失。 – 2012-04-10 18:04:12

+0

我们真的没有什么实际的原因,除了这是在我的原始版本的Web应用程序之前完成的。你的意思是否符合'/ Customer/Edit/1234'的意思?我们曾经讨论过,它看起来不如'/ CustomerProfile/Edit'好,另一件事就是我们不希望我们的用户用一个随机数替换当前的数字来拉另一个的客户。 BTY,这只是一个内部的Web应用程序。你站在哪里? – Turp 2012-04-10 18:15:43

3

如果它是在一个控制器,你可以这样做:

protected override void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
    base.OnActionExecuting(filterContext); 
    ... // do your magic 
} 

这将触发之前的任何动作执行。你不能从那里返回一个视图,虽然,你必须重定向到任何东西,返回作用的结果,如:

filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Shared" }, { "action", "Home" } }); 

但是,很明显,这应该重定向到不是受控制器的动作覆盖,否则你有一个循环重定向。 :)