using System; using System.Web.Mvc; using System.Text.RegularExpressions; namespace MvcContrib.Filters { /// Troy DeMonbreun /// /// This is an action attribute that defines (via a regular expression) a required RouteData or Request /// parameter "precondition" for the action. On precondition failure, the specified Exception type will be thrown. /// More info here. /// /// /// /// [RegExPreconditionFilter("id", PreconditionFilter.ParamType.RouteData, "^[1-9][0-9]*$", typeof(ArgumentOutOfRangeException))] /// OR /// [RegExPreconditionFilter("id", PreconditionFilter.ParamType.Request, "^[1-9][0-9]*$", typeof(ArgumentOutOfRangeException))] /// /// public class RegExPreconditionFilter : PreconditionFilter { protected string _regExPattern; /// /// Attribute constructor /// /// Name of key to validate /// Type of key to validate /// Regular expression to be matched /// Exception to throw on failed validation public RegExPreconditionFilter(string paramName, ParamType paramType, string regExPattern, Type exceptionToThrow) { _paramName = paramName; _paramType = paramType; _regExPattern = regExPattern; _exceptionToThrow = exceptionToThrow; _thrownExceptionMessage = Enum.GetName(typeof(ParamType), paramType) + " parameter '" + paramName + "' does not match regex " + regExPattern; } /// /// Signals failure if RouteData key does not exist, RouteData key value is null or empty string, /// or regular expression does not match RouteData key value /// protected override bool FailedValidation(ActionExecutingContext executingContext) { switch (_paramType) { case ParamType.RouteData: return !executingContext.RouteData.Values.ContainsKey(_paramName) || executingContext.RouteData.Values[_paramName] == null || !Regex.IsMatch(executingContext.RouteData.Values[_paramName].ToString(), _regExPattern); case ParamType.Request: return executingContext.HttpContext.Request.Params[_paramName] == null || !Regex.IsMatch(executingContext.HttpContext.Request.Params[_paramName], _regExPattern); default: return false; } } } }