Jasinski Technical Wiki


Home Page
All Pages

Quick Search
Advanced Search »

Contributor Links

Create a new Page
File Management
Your Profile

Other Wiki Sections



ActionValidator Class - ASP.NET

Modified on Mon, Nov 09, 2009, 4:02 PM by Administrator Categorized as ASP·NET Web Forms, Class Library
This page is a Draft. Its content is not complete and might contain errors.

Adapted from this article on The Code Project's website.


I have a class named ActionValidator which maintains a count of specific actions like First Visit, Revisit, Asynchronous postbacks, Add New widget, Add New Page etc. It checks whether the count for such specific action for a specific IP exceeds the threshold value or not. The enumeration contains the type of actions to check for and their threshold value for a specific duration: 10 mins.

A static method named IsValid does the check. It returns true if the request limit is not passed, false if the request needs to be denied. Once you get false, you can call Request.End(). The cache key is built with a combination of action type and client IP address. First it checks if there's any entry for the action and the client IP in cache or not. If not, start the count and remember the count for the IP in cache for the specific duration. The absolute expiration on cache item ensures that after the duration the cache item will be cleared and the count will restart. When there's already an entry in the cache, get the last hit count, and check if the limit is exceeded or not. If not exceeded, increase the counter. There is no need to store the updated value in the cache again by doing: Cache[url]=hit; because the hit object is by reference and changing it means it gets changed in the cache as well. In fact, if you do put it again in the cache, the cache expiration counter will restart and fail the logic of restarting count after specific duration.

Of course you can put in some Cisco firewall and prevent DOS attack. You will get a guarantee from your hosting provider that their entire network is immune to DOS and DDOS (Distributed DOS) attacks. What they guarantee is network level attack like TCP SYN attacks or malformed packet floods etc. There is no way they can analyze the packet and find out a particular IP is trying to load the site too many times without supporting cookie or trying to add too many widgets. These are called application level DOS attack which hardware cannot prevent. It must be implemented in your own code.

Source Code

HitInfo Class




public class HitInfo
    private int _hits;

    public HitInfo() {}

    public int Hits
        get { return _hits; }
        set { _hits = value; }

ActionValidator Class




public static class ActionValidator
    private const int DURATION = 10; // 10 min period
    public enum ActionTypeEnum
        FirstVisit = 100, // The most expensive one, choose the value wisely. 
        ReVisit = 1000,  // Welcome to revisit as many times as user likes
        Postback = 5000,    // Not must of a problem for us
        AddNewWidget = 100, 
        AddNewPage = 100,

    public static bool IsValid( ActionTypeEnum actionType )
       HttpContext context = HttpContext.Current;
       if( context.Request.Browser.Crawler ) return false;
       string key = actionType.ToString() + context.Request.UserHostAddress;
       var hit = (HitInfo)(context.Cache[key] ?? new HitInfo());
       if( hit.Hits > (int)actionType ) return false;
       else hit.Hits ++;
       if( hit.Hits == 1 )
          context.Cache.Add(key, hit, null, DateTime.Now.AddMinutes(DURATION), 
             System.Web.Caching.CacheItemPriority.Normal, null);
       return true;


Usage in an ASPX page or Master page.



protected override void OnInit(EventArgs e)

    else if (IsFirstVisit())
    else if(!ActionValidator.IsValid(ActionValidator.ActionTypeEnum.ReVisit)) 
private bool IsFirstVisit()
    if (Session["IsFirstVisit"] == null)
        Session["IsFirstVisit"] = false;
        return true;
        return false;

ScrewTurn Wiki version Some of the icons created by FamFamFam. Except where noted, all contents Copyright © 1999-2024, Patrick Jasinski.