代码改变世界

FUN WITH HTTP HEADERS IN ASP.NET MVC ACTION FILTERS(自定刷新)

2013-07-07 00:16  yezhi  阅读(301)  评论(0)    收藏  举报

http://weblogs.asp.net/rashid/archive/2009/04/29/fun-with-http-headers-in-asp-net-mvc-action-filters.aspx

FUN WITH HTTP HEADERS IN ASP.NET MVC ACTION FILTERS

Do you want your ASP.NET MVC application to auto redirect to a specific url after a certain interval, yes you can use javascript window.location, what about without javascript? Check this codes:

[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()

If the browsers is idle for the specified period, it will automatically redirect to that Action. if you do not specify any action/controller/route (Index4) it will auto refresh the current url. How? Well I am just using/abusing some http header, check it out:

[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;
    }
}

Can’t think any proper usage of this action filter, may be you can use it for any iframe kind of page where you want to show some live statistics. Okay now let’s try one more time to abuse this Refresh header, this time it is a very common scenario.

You want your secured (marked as Authorized) actions to automatically redirect to login page when the session expires. Now try this:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
public class AutoRedirectToLogin : 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);
    }
}

 

When the session expires it will automatically redirect to the login page without requiring the extra click from the user.