/// <summary> /// Check for a numeric input and that it is both less than and greater than given values /// </summary> /// <param name="min">Minimum value the numeric value can take</param> /// <param name="max">Maximum value the numeric value can take</param> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> MinMaxNum(Decimal min, Decimal max, ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } var numeric = Numeric(opts)(val, data, host); if (numeric != null) { return numeric; } // Converted to dec must be possible since Numeric passed to get here var dec = Convert.ToDecimal(val); return dec < min || dec > max ? opts.Message : null; }); }
/// <summary> /// Check that the given value is a value that is available in a database - /// i.e. a join primary key. This will attempt to automatically use the table /// name and value column from the field's `Options` method (under the /// assumption that it will typically be used with a joined field), but the /// table and field can also be specified via the options. /// </summary> /// <param name="cfg">Validation options</param> /// <param name="column">Column name to use to check as a unique value. If not given the host field's database column name is used</param> /// <param name="table">Table to check that this value is uniquely valid on. If not given the host Editor's table name is used</param> /// <param name="db">Database connection. If not given the host Editor's database connection is used</param> /// <param name="valid">List of values that are valid in addition to the values found via the database</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> DbValues(ValidationOpts cfg = null, string column = null, string table = null, Database db = null, IEnumerable <object> valid = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } // If defined in local options if (valid != null && valid.Contains(val)) { return null; } if (db == null) { db = host.Db; } if (table == null) { table = host.Field.Options().Table(); } if (column == null) { column = host.Field.Options().Value(); } if (table == null || column == null) { throw new Exception("Table or column for database value check is not defined for field " + host.Field.Name()); } try { var count = db.Query("select") .Table(table) .Get(column) .Where(column, val) .Exec() .Count(); return count == 0 ? opts.Message : null; } catch (Exception) { return opts.Message; } }); }
/// <summary> /// Basic validation - this is used to perform the validation provided by the /// validation options only. If the validation options pass (e.g. `required`, /// `empty` and `optional`) then the validation will pass regardless of the /// actual value. /// </summary> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> Basic(ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); return common == false ? opts.Message : null; }); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Private methods */ private static Func <object, Dictionary <string, object>, ValidationHost, string> _Unique(ValidationOpts cfg = null, string column = null, string table = null, Database db = null, Type t = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } if (db == null) { db = host.Db; } if (table == null) { table = host.Editor.Table()[0]; } if (column == null) { column = host.Field.DbField(); } if (t != null) { val = Convert.ChangeType(val, t); } var query = db.Query("select") .Table(table) .Get(column) .Where(column, val); // If doing an edit then we need to also discount the current row, // since it is of course already validly unique if (host.Action == "edit") { var cond = host.Editor.PkeyToArray(host.Id, true); query.Where(cond, "!="); } var res = query.Exec(); return res.Count() == 0 ? null : opts.Message; }); }
/// <summary> /// Require a string with a certain minimum or maximum number of characters. /// </summary> /// <param name="min">Minimum length</param> /// <param name="max">Maximum length</param> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> MinMaxLen(int min, int max, ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } var str = Convert.ToString(val); return str.Length < min || str.Length > max ? opts.Message : null; }); }
/// <summary> /// Confirm that the value submitted is in a list of allowable values /// </summary> /// <param name="cfg">Validation options</param> /// <param name="valid">List of values that are valid</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> Values(ValidationOpts cfg = null, IEnumerable <object> valid = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } // If defined in local options return valid != null && valid.Contains(val) ? null : opts.Message; }); }
/// <summary> /// Validate as an URL address. /// </summary> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> Url(ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } var str = Convert.ToString(val); Uri addr; return Uri.TryCreate(str, UriKind.RelativeOrAbsolute, out addr) ? null : opts.Message; }); }
/// <summary> /// Validate as an IP address. /// </summary> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> Ip(ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } var str = Convert.ToString(val); System.Net.IPAddress addr; return System.Net.IPAddress.TryParse(str, out addr) ? null : opts.Message; }); }
/// <summary> /// Check if string could contain an XSS attack string /// </summary> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> Xss(ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } if (!(val is string)) { return null; } return host.Field.XssSafety((string)val) == (string)val ? null : opts.Message; }); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Number validation methods */ /// <summary> /// Check that any input is numeric. /// </summary> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> Numeric(ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } try { Convert.ToDecimal(val); return null; } catch (Exception) { } return opts.Message; }); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Date validation methods */ /// <summary> /// Check that a valid date input is given /// </summary> /// <param name="format">Format that the date / time should be given in</param> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> DateFormat(string format, ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } try { var str = Convert.ToString(val); DateTime.ParseExact(str, format, System.Globalization.CultureInfo.InvariantCulture); return null; // If no exceptions - then valid } catch (Exception) { } return opts.Message; }); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * String validation methods */ /// <summary> /// Validate an input as an e-mail address. /// </summary> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> Email(ValidationOpts cfg = null) { ValidationOpts opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } try { var str = Convert.ToString(val); new System.Net.Mail.MailAddress(str); return null; // If no exceptions - then valid } catch (Exception) { } return opts.Message; }); }
/// <summary> /// Ensure that the submitted string does not contain HTML tags /// </summary> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> NoTags(ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } if (!(val is string)) { return null; } var tagRegex = new Regex(@"<[^>]+>"); return tagRegex.IsMatch((string)val) ? opts.Message : null; }); }
/// <summary> /// Check for a numeric input and that it is less than a given value. /// </summary> /// <param name="max">Maximum value the numeric value can take</param> /// <param name="culture">Numeric conversion culture</param> /// <param name="cfg">Validation options</param> /// <returns>Validation delegate</returns> public static Func <object, Dictionary <string, object>, ValidationHost, string> MaxNum(decimal max, string culture = "en-US", ValidationOpts cfg = null) { var opts = ValidationOpts.Select(cfg); return(delegate(object val, Dictionary <string, object> data, ValidationHost host) { var common = _Common(val, opts); if (common != null) { return common == false ? opts.Message : null; } var numeric = Numeric(culture, opts)(val, data, host); if (numeric != null) { return numeric; } // Converted to dec must be possible since Numeric passed to get here return Convert.ToDecimal(val, new CultureInfo(culture)) > max ? opts.Message : null; }); }