You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,491 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="basecomparevalidator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Web.UI.WebControls {
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Web;
|
||||
using System.Web.UI.HtmlControls;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text;
|
||||
using System.Web.Util;
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para> Serves as the abstract base
|
||||
/// class for validators that do typed comparisons.</para>
|
||||
/// </devdoc>
|
||||
public abstract class BaseCompareValidator : BaseValidator {
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Gets or sets the data type that specifies how the values
|
||||
/// being compared should be interpreted.</para>
|
||||
/// </devdoc>
|
||||
[
|
||||
WebCategory("Behavior"),
|
||||
Themeable(false),
|
||||
DefaultValue(ValidationDataType.String),
|
||||
WebSysDescription(SR.RangeValidator_Type)
|
||||
]
|
||||
public ValidationDataType Type {
|
||||
get {
|
||||
object o = ViewState["Type"];
|
||||
return((o == null) ? ValidationDataType.String : (ValidationDataType)o);
|
||||
}
|
||||
set {
|
||||
if (value < ValidationDataType.String || value > ValidationDataType.Currency) {
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
}
|
||||
ViewState["Type"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// Whether we should do culture invariant conversion against the
|
||||
/// string value properties on the control
|
||||
/// </devdoc>
|
||||
[
|
||||
WebCategory("Behavior"),
|
||||
Themeable(false),
|
||||
DefaultValue(false),
|
||||
WebSysDescription(SR.BaseCompareValidator_CultureInvariantValues)
|
||||
]
|
||||
public bool CultureInvariantValues {
|
||||
get {
|
||||
object o = ViewState["CultureInvariantValues"];
|
||||
return((o == null) ? false : (bool)o);
|
||||
}
|
||||
set {
|
||||
ViewState["CultureInvariantValues"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <internalonly/>
|
||||
/// <devdoc>
|
||||
/// AddAttributesToRender method
|
||||
/// </devdoc>
|
||||
protected override void AddAttributesToRender(HtmlTextWriter writer) {
|
||||
base.AddAttributesToRender(writer);
|
||||
if (RenderUplevel) {
|
||||
ValidationDataType type = Type;
|
||||
if (type != ValidationDataType.String) {
|
||||
string id = ClientID;
|
||||
HtmlTextWriter expandoAttributeWriter = (EnableLegacyRendering || IsUnobtrusive) ? writer : null;
|
||||
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "type", PropertyConverter.EnumToString(typeof(ValidationDataType), type), false);
|
||||
|
||||
NumberFormatInfo info = NumberFormatInfo.CurrentInfo;
|
||||
if (type == ValidationDataType.Double) {
|
||||
string decimalChar = info.NumberDecimalSeparator;
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "decimalchar", decimalChar);
|
||||
}
|
||||
else if (type == ValidationDataType.Currency) {
|
||||
string decimalChar = info.CurrencyDecimalSeparator;
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "decimalchar", decimalChar);
|
||||
|
||||
string groupChar = info.CurrencyGroupSeparator;
|
||||
// Map non-break space onto regular space for parsing
|
||||
if (groupChar[0] == 160)
|
||||
groupChar = " ";
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "groupchar", groupChar);
|
||||
|
||||
int digits = info.CurrencyDecimalDigits;
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "digits", digits.ToString(NumberFormatInfo.InvariantInfo), false);
|
||||
|
||||
// VSWhidbey 83165
|
||||
int groupSize = GetCurrencyGroupSize(info);
|
||||
if (groupSize > 0) {
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "groupsize", groupSize.ToString(NumberFormatInfo.InvariantInfo), false);
|
||||
}
|
||||
}
|
||||
else if (type == ValidationDataType.Date) {
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "dateorder", GetDateElementOrder(), false);
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "cutoffyear", CutoffYear.ToString(NumberFormatInfo.InvariantInfo), false);
|
||||
|
||||
// VSWhidbey 504553: The changes of this bug make client-side script not
|
||||
// using the century attribute anymore, but still generating it for
|
||||
// backward compatibility with Everett pages.
|
||||
int currentYear = DateTime.Today.Year;
|
||||
int century = currentYear - (currentYear % 100);
|
||||
AddExpandoAttribute(expandoAttributeWriter, id, "century", century.ToString(NumberFormatInfo.InvariantInfo), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// Check if the text can be converted to the type
|
||||
/// </devdoc>
|
||||
public static bool CanConvert(string text, ValidationDataType type) {
|
||||
return CanConvert(text, type, false);
|
||||
}
|
||||
|
||||
|
||||
public static bool CanConvert(string text, ValidationDataType type, bool cultureInvariant) {
|
||||
object value = null;
|
||||
return Convert(text, type, cultureInvariant, out value);
|
||||
}
|
||||
|
||||
|
||||
/// <internalonly/>
|
||||
/// <devdoc>
|
||||
/// Return the order of date elements for the current culture
|
||||
/// </devdoc>
|
||||
protected static string GetDateElementOrder() {
|
||||
DateTimeFormatInfo info = DateTimeFormatInfo.CurrentInfo;
|
||||
string shortPattern = info.ShortDatePattern;
|
||||
if (shortPattern.IndexOf('y') < shortPattern.IndexOf('M')) {
|
||||
return "ymd";
|
||||
}
|
||||
else if (shortPattern.IndexOf('M') < shortPattern.IndexOf('d')) {
|
||||
return "mdy";
|
||||
}
|
||||
else {
|
||||
return "dmy";
|
||||
}
|
||||
}
|
||||
|
||||
// VSWhidbey 83165
|
||||
private static int GetCurrencyGroupSize(NumberFormatInfo info) {
|
||||
int [] groupSizes = info.CurrencyGroupSizes;
|
||||
if (groupSizes != null && groupSizes.Length == 1) {
|
||||
return groupSizes[0];
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
protected static int CutoffYear {
|
||||
get {
|
||||
return DateTimeFormatInfo.CurrentInfo.Calendar.TwoDigitYearMax;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
protected static int GetFullYear(int shortYear) {
|
||||
Debug.Assert(shortYear >= 0 && shortYear < 100);
|
||||
return DateTimeFormatInfo.CurrentInfo.Calendar.ToFourDigitYear(shortYear);
|
||||
}
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// Try to convert the test into the validation data type
|
||||
/// </devdoc>
|
||||
protected static bool Convert(string text, ValidationDataType type, out object value) {
|
||||
return Convert(text, type, false, out value);
|
||||
}
|
||||
|
||||
|
||||
protected static bool Convert(string text, ValidationDataType type, bool cultureInvariant, out object value) {
|
||||
|
||||
value = null;
|
||||
try {
|
||||
switch (type) {
|
||||
case ValidationDataType.String:
|
||||
value = text;
|
||||
break;
|
||||
|
||||
case ValidationDataType.Integer:
|
||||
value = Int32.Parse(text, CultureInfo.InvariantCulture);
|
||||
break;
|
||||
|
||||
case ValidationDataType.Double: {
|
||||
string cleanInput;
|
||||
if (cultureInvariant) {
|
||||
cleanInput = ConvertDouble(text, CultureInfo.InvariantCulture.NumberFormat);
|
||||
}
|
||||
else {
|
||||
cleanInput = ConvertDouble(text, NumberFormatInfo.CurrentInfo);
|
||||
}
|
||||
|
||||
if (cleanInput != null) {
|
||||
value = Double.Parse(cleanInput, CultureInfo.InvariantCulture);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ValidationDataType.Date: {
|
||||
if (cultureInvariant) {
|
||||
value = ConvertDate(text, "ymd");
|
||||
}
|
||||
else {
|
||||
// if the calendar is not gregorian, we should not enable client-side, so just parse it directly:
|
||||
if (!(DateTimeFormatInfo.CurrentInfo.Calendar.GetType() == typeof(GregorianCalendar))) {
|
||||
value = DateTime.Parse(text, CultureInfo.CurrentCulture);
|
||||
break;
|
||||
}
|
||||
|
||||
string dateElementOrder = GetDateElementOrder();
|
||||
value = ConvertDate(text, dateElementOrder);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ValidationDataType.Currency: {
|
||||
string cleanInput;
|
||||
if (cultureInvariant) {
|
||||
cleanInput = ConvertCurrency(text, CultureInfo.InvariantCulture.NumberFormat);
|
||||
}
|
||||
else {
|
||||
cleanInput = ConvertCurrency(text, NumberFormatInfo.CurrentInfo);
|
||||
}
|
||||
|
||||
if (cleanInput != null) {
|
||||
value = Decimal.Parse(cleanInput, CultureInfo.InvariantCulture);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
value = null;
|
||||
}
|
||||
return (value != null);
|
||||
}
|
||||
|
||||
private static string ConvertCurrency(string text, NumberFormatInfo info) {
|
||||
string decimalChar = info.CurrencyDecimalSeparator;
|
||||
string groupChar = info.CurrencyGroupSeparator;
|
||||
|
||||
// VSWhidbey 83165
|
||||
string beginGroupSize, subsequentGroupSize;
|
||||
int groupSize = GetCurrencyGroupSize(info);
|
||||
if (groupSize > 0) {
|
||||
string groupSizeText = groupSize.ToString(NumberFormatInfo.InvariantInfo);
|
||||
beginGroupSize = "{1," + groupSizeText + "}";
|
||||
subsequentGroupSize = "{" + groupSizeText + "}";
|
||||
}
|
||||
else {
|
||||
beginGroupSize = subsequentGroupSize = "+";
|
||||
}
|
||||
|
||||
// Map non-break space onto regular space for parsing
|
||||
if (groupChar[0] == 160)
|
||||
groupChar = " ";
|
||||
int digits = info.CurrencyDecimalDigits;
|
||||
bool hasDigits = (digits > 0);
|
||||
string currencyExpression =
|
||||
"^\\s*([-\\+])?((\\d" + beginGroupSize + "(\\" + groupChar + "\\d" + subsequentGroupSize + ")+)|\\d*)"
|
||||
+ (hasDigits ? "\\" + decimalChar + "?(\\d{0," + digits.ToString(NumberFormatInfo.InvariantInfo) + "})" : string.Empty)
|
||||
+ "\\s*$";
|
||||
|
||||
Match m = Regex.Match(text, currencyExpression);
|
||||
if (!m.Success) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make sure there are some valid digits
|
||||
if (m.Groups[2].Length == 0 && hasDigits && m.Groups[5].Length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return m.Groups[1].Value
|
||||
+ m.Groups[2].Value.Replace(groupChar, string.Empty)
|
||||
+ ((hasDigits && m.Groups[5].Length > 0) ? "." + m.Groups[5].Value : string.Empty);
|
||||
}
|
||||
|
||||
private static string ConvertDouble(string text, NumberFormatInfo info) {
|
||||
// VSWhidbey 83156: If text is empty, it would be default to 0 for
|
||||
// backward compatibility reason.
|
||||
if (text.Length == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
string decimalChar = info.NumberDecimalSeparator;
|
||||
string doubleExpression = "^\\s*([-\\+])?(\\d*)\\" + decimalChar + "?(\\d*)\\s*$";
|
||||
|
||||
Match m = Regex.Match(text, doubleExpression);
|
||||
if (!m.Success) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Make sure there are some valid digits
|
||||
if (m.Groups[2].Length == 0 && m.Groups[3].Length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return m.Groups[1].Value
|
||||
+ (m.Groups[2].Length > 0 ? m.Groups[2].Value : "0")
|
||||
+ ((m.Groups[3].Length > 0) ? "." + m.Groups[3].Value: string.Empty);
|
||||
}
|
||||
|
||||
// ****************************************************************************************************************
|
||||
// ** **
|
||||
// ** NOTE: When updating the regular expressions in this method, you must also update the regular expressions **
|
||||
// ** in WebUIValidation.js::ValidatorConvert(). The server and client regular expressions must match. **
|
||||
// ** **
|
||||
// ****************************************************************************************************************
|
||||
private static object ConvertDate(string text, string dateElementOrder) {
|
||||
// always allow the YMD format, if they specify 4 digits
|
||||
string dateYearFirstExpression = "^\\s*((\\d{4})|(\\d{2}))([-/]|\\. ?)(\\d{1,2})\\4(\\d{1,2})\\.?\\s*$";
|
||||
Match m = Regex.Match(text, dateYearFirstExpression);
|
||||
int day, month, year;
|
||||
if (m.Success && (m.Groups[2].Success || dateElementOrder == "ymd")) {
|
||||
day = Int32.Parse(m.Groups[6].Value, CultureInfo.InvariantCulture);
|
||||
month = Int32.Parse(m.Groups[5].Value, CultureInfo.InvariantCulture);
|
||||
if (m.Groups[2].Success) {
|
||||
year = Int32.Parse(m.Groups[2].Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else {
|
||||
year = GetFullYear(Int32.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dateElementOrder == "ymd") {
|
||||
return null;
|
||||
}
|
||||
|
||||
// also check for the year last format
|
||||
string dateYearLastExpression = "^\\s*(\\d{1,2})([-/]|\\. ?)(\\d{1,2})(?:\\s|\\2)((\\d{4})|(\\d{2}))(?:\\s\u0433\\.|\\.)?\\s*$";
|
||||
m = Regex.Match(text, dateYearLastExpression);
|
||||
if (!m.Success) {
|
||||
return null;
|
||||
}
|
||||
if (dateElementOrder == "mdy") {
|
||||
day = Int32.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture);
|
||||
month = Int32.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else {
|
||||
day = Int32.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture);
|
||||
month = Int32.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
if (m.Groups[5].Success) {
|
||||
year = Int32.Parse(m.Groups[5].Value, CultureInfo.InvariantCulture);
|
||||
} else {
|
||||
year = GetFullYear(Int32.Parse(m.Groups[6].Value, CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
return new DateTime(year, month, day);
|
||||
}
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// Compare two strings using the type and operator
|
||||
/// </devdoc>
|
||||
protected static bool Compare(string leftText, string rightText, ValidationCompareOperator op, ValidationDataType type) {
|
||||
return Compare(leftText, false, rightText, false, op, type);
|
||||
}
|
||||
|
||||
|
||||
protected static bool Compare(string leftText, bool cultureInvariantLeftText,
|
||||
string rightText, bool cultureInvariantRightText,
|
||||
ValidationCompareOperator op, ValidationDataType type) {
|
||||
object leftObject;
|
||||
if (!Convert(leftText, type, cultureInvariantLeftText, out leftObject))
|
||||
return false;
|
||||
|
||||
if (op == ValidationCompareOperator.DataTypeCheck)
|
||||
return true;
|
||||
|
||||
object rightObject;
|
||||
if (!Convert(rightText, type, cultureInvariantRightText, out rightObject))
|
||||
return true;
|
||||
|
||||
int compareResult;
|
||||
switch (type) {
|
||||
case ValidationDataType.String:
|
||||
compareResult = String.Compare((string)leftObject, (string) rightObject, false, CultureInfo.CurrentCulture);
|
||||
break;
|
||||
|
||||
case ValidationDataType.Integer:
|
||||
compareResult = ((int)leftObject).CompareTo(rightObject);
|
||||
break;
|
||||
|
||||
case ValidationDataType.Double:
|
||||
compareResult = ((double)leftObject).CompareTo(rightObject);
|
||||
break;
|
||||
|
||||
case ValidationDataType.Date:
|
||||
compareResult = ((DateTime)leftObject).CompareTo(rightObject);
|
||||
break;
|
||||
|
||||
case ValidationDataType.Currency:
|
||||
compareResult = ((Decimal)leftObject).CompareTo(rightObject);
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.Fail("Unknown Type");
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case ValidationCompareOperator.Equal:
|
||||
return compareResult == 0;
|
||||
case ValidationCompareOperator.NotEqual:
|
||||
return compareResult != 0;
|
||||
case ValidationCompareOperator.GreaterThan:
|
||||
return compareResult > 0 ;
|
||||
case ValidationCompareOperator.GreaterThanEqual:
|
||||
return compareResult >= 0 ;
|
||||
case ValidationCompareOperator.LessThan:
|
||||
return compareResult < 0 ;
|
||||
case ValidationCompareOperator.LessThanEqual:
|
||||
return compareResult <= 0 ;
|
||||
default:
|
||||
Debug.Fail("Unknown Operator");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
protected override bool DetermineRenderUplevel() {
|
||||
// We don't do client-side validation for dates with non gregorian calendars
|
||||
if (Type == ValidationDataType.Date && DateTimeFormatInfo.CurrentInfo.Calendar.GetType() != typeof(GregorianCalendar)) {
|
||||
return false;
|
||||
}
|
||||
return base.DetermineRenderUplevel();
|
||||
}
|
||||
|
||||
internal string ConvertToShortDateString(string text) {
|
||||
// VSWhidbey 83099, 85305, we should ignore error if it happens and
|
||||
// leave text as intact when parsing the date. We assume the caller
|
||||
// (validator) is able to handle invalid text itself.
|
||||
DateTime date;
|
||||
if (DateTime.TryParse(text, CultureInfo.CurrentCulture, DateTimeStyles.None, out date)) {
|
||||
text = date.ToShortDateString();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
internal bool IsInStandardDateFormat(string date) {
|
||||
// VSWhidbey 115454: We identify that date string with only numbers
|
||||
// and specific punctuation separators is in standard date format.
|
||||
const string standardDateExpression = "^\\s*(\\d+)([-/]|\\. ?)(\\d+)\\2(\\d+)\\s*$";
|
||||
return Regex.Match(date, standardDateExpression).Success;
|
||||
}
|
||||
|
||||
internal string ConvertCultureInvariantToCurrentCultureFormat(string valueInString,
|
||||
ValidationDataType type) {
|
||||
object value;
|
||||
Convert(valueInString, type, true, out value);
|
||||
if (value is DateTime) {
|
||||
// For Date type we explicitly want the date portion only
|
||||
return ((DateTime) value).ToShortDateString();
|
||||
}
|
||||
else {
|
||||
return System.Convert.ToString(value, CultureInfo.CurrentCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user