ASP.NET MVC Action Filters中有趣的Http Headers
你想要你的Asp.net mvc 应用程序在一段时间后自动重定向一个指定的URL,是的你能用javascript中window.location来实现,除了javascript外呢?看这个代码:
- [AutoRefresh(ControllerName = "Home", ActionName = "About", DurationInSeconds = 10)]
- public ActionResult Index1()
- [AutoRefresh(ActionName = "About", DurationInSeconds = 15)]
- public ActionResult Index2()
- [AutoRefresh(RouteName = "ByFavoriteRoute", DurationInSeconds = 30)]
- public ActionResult Index3()
- [AutoRefresh(DurationInSeconds = 45)]
- public ActionResult Index4()
[AutoRefresh(ControllerName = "Home", ActionName = "About", DurationInSeconds = 10)] public ActionResult Index1() [AutoRefresh(ActionName = "About", DurationInSeconds = 15)] public ActionResult Index2() [AutoRefresh(RouteName = "ByFavoriteRoute", DurationInSeconds = 30)] public ActionResult Index3() [AutoRefresh(DurationInSeconds = 45)] public ActionResult Index4()
如果浏览器在特定期间是闲置的,它将自动重定向到那个Action.如果你不指定任何action/controller/route,它将自动重定向当前URL.怎样?好的我只是使用/滥用一些http header,来看下面:
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
- [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
- public class AutoRefreshAttribute : ActionFilterAttribute
- {
- public const int DefaultDurationInSeconds = 300; // 5 Minutes
- public AutoRefreshAttribute()
- {
- DurationInSeconds = DefaultDurationInSeconds;
- }
- public int DurationInSeconds
- {
- get;
- set;
- }
- public string RouteName
- {
- get;
- set;
- }
- public string ControllerName
- {
- get;
- set;
- }
- public string ActionName
- {
- get;
- set;
- }
- public override void OnResultExecuted(ResultExecutedContext filterContext)
- {
- string url = BuildUrl(filterContext);
- string headerValue = string.Concat(DurationInSeconds, ";Url=", url);
- filterContext.HttpContext.Response.AppendHeader("Refresh", headerValue);
- base.OnResultExecuted(filterContext);
- }
- private string BuildUrl(ControllerContext filterContext)
- {
- UrlHelper urlHelper = new UrlHelper(filterContext.RequestContext);
- string url;
- if (!string.IsNullOrEmpty(RouteName))
- {
- url = urlHelper.RouteUrl(RouteName);
- }
- else if (!string.IsNullOrEmpty(ControllerName) && !string.IsNullOrEmpty(ActionName))
- {
- url = urlHelper.Action(ActionName, ControllerName);
- }
- else if (!string.IsNullOrEmpty(ActionName))
- {
- url = urlHelper.Action(ActionName);
- }
- else
- {
- url = filterContext.HttpContext.Request.RawUrl;
- }
- return url;
- }
- }
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)] public class AutoRefreshAttribute : ActionFilterAttribute { public const int DefaultDurationInSeconds = 300; // 5 Minutes public AutoRefreshAttribute() { DurationInSeconds = DefaultDurationInSeconds; } public int DurationInSeconds { get; set; } public string RouteName { get; set; } public string ControllerName { get; set; } public string ActionName { get; set; } public override void OnResultExecuted(ResultExecutedContext filterContext) { string url = BuildUrl(filterContext); string headerValue = string.Concat(DurationInSeconds, ";Url=", url); filterContext.HttpContext.Response.AppendHeader("Refresh", headerValue); base.OnResultExecuted(filterContext); } private string BuildUrl(ControllerContext filterContext) { UrlHelper urlHelper = new UrlHelper(filterContext.RequestContext); string url; if (!string.IsNullOrEmpty(RouteName)) { url = urlHelper.RouteUrl(RouteName); } else if (!string.IsNullOrEmpty(ControllerName) && !string.IsNullOrEmpty(ActionName)) { url = urlHelper.Action(ActionName, ControllerName); } else if (!string.IsNullOrEmpty(ActionName)) { url = urlHelper.Action(ActionName); } else { url = filterContext.HttpContext.Request.RawUrl; } return url; } }
不能想像适当使用这个action filter,可能你能在你你要显示一些在线统计之类页面任何iframe中使用它.好的,现在让我们试试滥用这个Refeash header,这时它是一个相当通的场景.
你要安全的使用(标记为已认证)action,当会话过期时自动重定向到登陆页面.现试试这个:
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
- [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
- public class AutoRedirecToLogin : ActionFilterAttribute
- {
- public override void OnResultExecuted(ResultExecutedContext filterContext)
- {
- string url = FormsAuthentication.LoginUrl;
- int durationInSeconds = ((filterContext.HttpContext.Session.Timeout * 60) + 10); // Extra 10 seconds
- string headerValue = string.Concat(durationInSeconds, ";Url=", url);
- filterContext.HttpContext.Response.AppendHeader("Refresh", headerValue);
- base.OnResultExecuted(filterContext);
- }
- }
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)] public class AutoRedirecToLogin : ActionFilterAttribute { public override void OnResultExecuted(ResultExecutedContext filterContext) { string url = FormsAuthentication.LoginUrl; int durationInSeconds = ((filterContext.HttpContext.Session.Timeout * 60) + 10); // Extra 10 seconds string headerValue = string.Concat(durationInSeconds, ";Url=", url); filterContext.HttpContext.Response.AppendHeader("Refresh", headerValue); base.OnResultExecuted(filterContext); } }
当会话过期时,不需要额外的用户点击它将自动重定向到登陆页面.
警告:如果你要你的URL被搜索引擎收录为索引,那以不要使用Refresh meta 头(验证过Google,其它的不确定).例如,你的页面A要自动重定向页面B,那么页面A只有这个头,在那种情况下页面A将不会被索引.
Roni Schuetz 刚通知他有一个聚集 mvc action filters的项目在CodePlex 上, 对于他的项目这两个应该是最佳候选.
Author: Petter Liu http://wintersun.cnblogs.com Source