using System; using System.Web.Mvc; namespace MvcContrib.Filters { /// Troy DeMonbreun /// /// This is an action attribute that defines (via a predicate method) a required RouteData or Request /// parameter "precondition" for the action. On precondition failure, the specified Exception type will be thrown. /// More info here. /// /// /// /// [PredicatePreconditionFilter("id", PreconditionFilter.ParamType.RouteData, "IsGreaterThanZero", typeof(ArgumentOutOfRangeException))] /// OR /// [PredicatePreconditionFilter("id", PreconditionFilter.ParamType.Request, "IsGreaterThanZero", typeof(ArgumentOutOfRangeException))] /// /// public class PredicatePreconditionFilter : PreconditionFilter { protected string _predicateMethod; /// /// Attribute constructor /// /// Name of key to validate /// Type of key to validate /// Predicate<object> method that encapsulates validation logic /// Exception to throw on failed validation public PredicatePreconditionFilter(string paramName, ParamType paramType, string predicateMethod, Type exceptionToThrow) { _paramName = paramName; _paramType = paramType; _predicateMethod = predicateMethod; _exceptionToThrow = exceptionToThrow; _thrownExceptionMessage = Enum.GetName(typeof(ParamType), paramType) + " parameter '" + paramName + "' does not satisfy predicate method " + predicateMethod; } /// /// Signals failure if RouteData key does not exist, RouteData key value is null, /// or predicate evaluates to false /// protected override bool FailedValidation(ActionExecutingContext executingContext) { //convert predicate into callable form var predicate = (Predicate)Delegate.CreateDelegate(typeof(Predicate), executingContext.Controller, _predicateMethod); switch (_paramType) { case ParamType.RouteData: //default return !executingContext.RouteData.Values.ContainsKey(_paramName) || executingContext.RouteData.Values[_paramName] == null || !predicate(executingContext.RouteData.Values[_paramName]); case ParamType.Request: return executingContext.HttpContext.Request.Params[_paramName] == null || !predicate(executingContext.HttpContext.Request.Params[_paramName]); default: return false; } } } }