/// <summary> /// Implementation of the abstract base function 'Validate'. /// </summary> /// <param name="propertyMetaInfo"></param> /// <param name="parameterObject"></param> public override void Validate(PropertyMetaInfo propertyMetaInfo, ParameterBase parameterObject) { MethodBase? methodBase = MethodBase.GetCurrentMethod(); // // Make sure the 'ValidationAttribute' is assigned to the right // property type. (A string in this case) // #pragma warning disable CS8604 if (propertyMetaInfo.Type.ToLower().IndexOf("string") < 0) { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString(), $"The attribute '{methodBase?.DeclaringType}' is not allowed on properties of type: '{propertyMetaInfo.Type}'."); return; } // // The actual validation. // if (propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString()?.Length < this.MinLength) { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString(), $"{ValidationErrorMessage}"); return; } #pragma warning restore CS8604 // // The validation passed. // propertyMetaInfo.ValidationError = null; }
/// <summary> /// Implementation of the abstract base function 'Validate'. /// </summary> /// <param name="propertyMetaInfo"></param> /// <param name="parameterObject"></param> public override void Validate(PropertyMetaInfo propertyMetaInfo, ParameterBase parameterObject) { MethodBase? methodBase = MethodBase.GetCurrentMethod(); #pragma warning disable CS8600, CS8602, CS8604 var propertyValue = propertyMetaInfo.PropertyInfo.GetValue(parameterObject); if(propertyValue == null) { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString(), $"{ValidationErrorMessage}"); return; } else { switch(propertyMetaInfo.Type) { case "UInt16|Null": case "UInt16": case "Int16|Null": case "Int16": { if(Convert.ToInt16(this.MaxValue) >= ((Int16) propertyValue)) { propertyMetaInfo.ValidationError = null; return; } break; } case "UInt32|Null": case "UInt32": case "Int32|Null": case "Int32": { if(((Int32) this.MaxValue) >= ((Int32) propertyValue)) { propertyMetaInfo.ValidationError = null; return; } break; } case "UInt64|Null": case "UInt64": case "Int64|Null": case "Int64": { if(Convert.ToInt64(this.MaxValue) >= ((Int64) propertyValue)) { propertyMetaInfo.ValidationError = null; return; } break; } case "Single|Null": case "Single": { if(Convert.ToSingle(this.MaxValue) >= ((Single) propertyValue)) { propertyMetaInfo.ValidationError = null; return; } break; } case "Double|Null": case "Double": { if(((Double) this.MaxValue) >= ((Double) propertyValue)) { propertyMetaInfo.ValidationError = null; return; } break; } case "Decimal|Null": case "Decimal": { if(Convert.ToDecimal(this.MaxValue) >= ((Decimal) propertyValue)) { propertyMetaInfo.ValidationError = null; return; } break; } default: { // // The 'ValidationAttribute' is assigned to the wrong // property type. (Must be one of the number types above) // propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString(), $"The attribute '{methodBase?.DeclaringType}' is not allowed on properties of type: '{propertyMetaInfo.Type}'."); return; } } propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString(), $"{ValidationErrorMessage}"); } #pragma warning restore CS8600, CS8602, CS8604 }
/// <summary> /// Validates a single parameter property. /// </summary> /// <param name="propertyMetaInfo"></param> private void ValidateProperty(PropertyMetaInfo propertyMetaInfo) { // // The argument is mandatory // if (propertyMetaInfo.IsMandatory) { // // Parsing failed because the argument was missing. // if (propertyMetaInfo.ParseResult == ParseResultEnum.NOT_PARSED) { // // The argument has a default value attached. // if (propertyMetaInfo.DefaultValue != null) { // // Try using the default value. // try { propertyMetaInfo.PropertyInfo.SetValue(this, propertyMetaInfo.DefaultValue); } catch (System.Exception ex) { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, "", $"Setting the default value for the mandatory command line argument '{propertyMetaInfo.Name}' if invalid. The exceptions message is: '{ex.Message}'"); return; } } // // Not parsed and no default value. // Create a validation error for the missing mandatroy argument. // else { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, "", $"The mandatory command line argument '{propertyMetaInfo.Name}' is missing or the value is invalid."); return; } } // // Parsing failed because the command line argument value was invalid. // else if (propertyMetaInfo.ParseResult == ParseResultEnum.PARSE_FAILED) { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, "", $"The mandatory command line argument '{propertyMetaInfo.Name}' is missing or the value is invalid."); return; } } // // The argument is optional // else { // // Parsing the argument failed // if (propertyMetaInfo.ParseResult == ParseResultEnum.NOT_PARSED) { // // The argument has a default value attached. // if (propertyMetaInfo.DefaultValue != null) { // // Try using the default value. // try { propertyMetaInfo.PropertyInfo.SetValue(this, propertyMetaInfo.DefaultValue); } catch (System.Exception ex) { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, "", $"The default value for the command line argument '{propertyMetaInfo.Name}' is invalid. The exceptions message is: '{ex.Message}'"); return; } } } if (propertyMetaInfo.ParseResult == ParseResultEnum.PARSE_FAILED) { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, "", $"The value of command line argument '{propertyMetaInfo.Name}' is invalid."); return; } } // // Check the value against the value set. // if (propertyMetaInfo.ValueSet.Count > 0) { Type targetType = propertyMetaInfo.PropertyInfo.PropertyType; Type underlyingType; List<object> compareSet = new List<object>(); try { foreach (var item in propertyMetaInfo.ValueSet) { #pragma warning disable CS8600, CS8604 if (Nullable.GetUnderlyingType(targetType) != null) { if (item == null) { compareSet.Add(item); } else { underlyingType = Nullable.GetUnderlyingType(targetType); compareSet.Add(Convert.ChangeType(item, underlyingType)); } } else { compareSet.Add(Convert.ChangeType(item, targetType)); } #pragma warning restore CS8600, CS8604 } } catch { propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, "", $"The value set attached to '{propertyMetaInfo.Name}' is not compatible with the parameter property type."); return; } // // Compare string values in lower case. // #pragma warning disable CS8602 if (targetType.ToString().ToLower().IndexOf("string") > -1) { for (int index = 0; index < compareSet.Count; index++) { compareSet[index] = compareSet[index].ToString().ToLower(); } if (!compareSet.Contains((propertyMetaInfo.PropertyInfo.GetValue(this) as String).ToLower())) { #pragma warning restore CS8602 string errorString = $"The value of command line argument '{propertyMetaInfo.Name}' is not in the set of allowed values.\r\nAllowed values are:\r\n["; foreach (var item in compareSet) { errorString += item.ToString() + ", "; } errorString = errorString.TrimEnd(new char[] { ',', ' ' }); errorString += "]"; propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, "", errorString); return; } } // // Not a string value. // else { #pragma warning disable CS8604 if (!compareSet.Contains(propertyMetaInfo.PropertyInfo.GetValue(this))) { string errorString = $"The value of command line argument '{propertyMetaInfo.Name}' is not in the set of allowed values.\r\nAllowed values are:\r\n["; foreach (var item in compareSet) { errorString += item.ToString() + ", "; } errorString = errorString.TrimEnd(new char[] { ',', ' ' }); errorString += "]"; propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, "", errorString); return; } #pragma warning restore CS8604 } } // // Check all validaton attributes // foreach (ValidationAttributeBase? validationAttribute in propertyMetaInfo.ValidationAttributeList) { if (validationAttribute != null) { validationAttribute.Validate(propertyMetaInfo, this); if (propertyMetaInfo.ValidationError != null) { // // Stop execution on the first validation error. // return; } } } }
/// <summary> /// This function must be implemented by every subclass. /// <para> /// The function must set the 'propertyMetaInfo.ValidationError' property if the validation failed. /// </para> /// <para> /// If the validation succeeded, the 'propertyMetaInfo.ValidationError' should be set to 'null'. /// </para> /// <example> <para>An example string length validation attribute implementation:</para> /// <code> /// public class MaxStringLengthAttribute : ValidationAttributeBase /// { /// public int MaxLength /// { /// get; /// private set; /// } /// /// public MaxStringLengthAttribute(int maxLength, string validationErrorMessage) : base(validationErrorMessage) /// { /// this.MaxLength = maxLength; /// this.ValidationErrorMessage = validationErrorMessage; /// } /// /// // /// // Create an implementation of the abstact base function 'Validate' /// // /// public override void Validate(PropertyMetaInfo propertyMetaInfo, ParameterBase parameterObject) /// { /// MethodBase? methodBase = MethodBase.GetCurrentMethod(); /// // /// // Make sure the 'ValidationAttribute' is assigned to the right /// // property type. (A string in this case) /// // /// if(propertyMetaInfo.Type.ToLower().IndexOf("string") < 0) /// { /// propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString(), $"The attribute '{methodBase?.DeclaringType}' is not allowed on properties of type: '{propertyMetaInfo.Type}'."); /// return; /// } /// /// // /// // The actual validation. Set the 'ValidationError' if the validation fails. /// // /// if(propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString()?.Length > this.MaxLength) /// { /// propertyMetaInfo.ValidationError = new ValidationError(propertyMetaInfo, propertyMetaInfo.PropertyInfo.GetValue(parameterObject)?.ToString(), $"{ValidationErrorMessage}"); /// return; /// } /// /// // /// // The validation passed. Clear the 'ValidationError'. /// // /// propertyMetaInfo.ValidationError = null; /// } /// /// }// END class /// </code> /// </example> /// </summary> /// <param name="propertyMetaInfo"></param> /// <param name="parameterObject"></param> public abstract void Validate(PropertyMetaInfo propertyMetaInfo, ParameterBase parameterObject);
private static string CreateHelpLines(PropertyMetaInfo propertyMetaInfo, int screenWidth, int longestArgumentLength, int longestTypeLength, int longestDefaultLength) { List<String> descriptionLines; string description; description = propertyMetaInfo.Description ?? propertyMetaInfo.Name + "<" + propertyMetaInfo.Type.Replace("|Null", "") + ">"; descriptionLines = CreateWrappedLines(description, screenWidth - longestArgumentLength - longestTypeLength - longestDefaultLength - 14); for (int index = 0; index < descriptionLines.Count; index++) { string leadLine = string.Empty; string defaultValueStr = string.Empty; if (index == 0) { leadLine += VerticalLine; if (propertyMetaInfo.IsMandatory) { leadLine += "+"; } else { leadLine += "-"; } leadLine += VerticalLine + " "; leadLine += propertyMetaInfo.Name + new String(' ', longestArgumentLength - propertyMetaInfo.Name.Length) + " "; leadLine += VerticalLine + " "; leadLine += propertyMetaInfo.Type + new String(' ', longestTypeLength - propertyMetaInfo.Type.Length) + " "; leadLine += VerticalLine + " "; if (propertyMetaInfo.DefaultValue != null) { defaultValueStr = propertyMetaInfo.DefaultValue?.ToString() ?? ""; } else if (propertyMetaInfo.Type.IndexOf("|Null") > -1) { defaultValueStr = "Null"; } if((propertyMetaInfo.Type == "Char") && (propertyMetaInfo.DefaultValue != null) && ( ((Char) propertyMetaInfo.DefaultValue) == Char.MinValue)) { leadLine += "\\0" + new String(' ', longestDefaultLength - ("\\0".Length)) + " "; } else { leadLine += defaultValueStr + new String(' ', longestDefaultLength - (defaultValueStr.Length)) + " "; } leadLine += VerticalLine; } else { leadLine += VerticalLine + " " + VerticalLine + " "; leadLine += new String(' ', longestArgumentLength) + " "; leadLine += VerticalLine + " "; leadLine += new String(' ', longestTypeLength) + " "; leadLine += VerticalLine + " "; leadLine += new String(' ', longestDefaultLength) + " "; leadLine += VerticalLine; } descriptionLines[index] = leadLine + descriptionLines[index] + " " + VerticalLine + "\r\n"; } return String.Concat(descriptionLines); }
/// <summary> /// Constructor of the 'ValidationError' class. /// </summary> /// <param name="propertyMetaInfo"></param> /// <param name="value"></param> /// <param name="message"></param> public ValidationError(PropertyMetaInfo propertyMetaInfo, string value, string message) { this.PropertyMetaInfo = propertyMetaInfo; this.Value = value; this.Message = message; }