diff options
author | 杨宇千 <crupest@outlook.com> | 2019-10-22 20:49:52 +0800 |
---|---|---|
committer | 杨宇千 <crupest@outlook.com> | 2019-10-22 20:49:52 +0800 |
commit | 3ddb38839ac07de4edf071faeb753b62acb0bed1 (patch) | |
tree | cd8dea96c88e9784ceeb7342f486160ceadc6a58 /Timeline/Models/Validation | |
parent | ec7dfb73ace61a1aba5156cc1048cbe32ee1cee6 (diff) | |
download | timeline-3ddb38839ac07de4edf071faeb753b62acb0bed1.tar.gz timeline-3ddb38839ac07de4edf071faeb753b62acb0bed1.tar.bz2 timeline-3ddb38839ac07de4edf071faeb753b62acb0bed1.zip |
...
Diffstat (limited to 'Timeline/Models/Validation')
-rw-r--r-- | Timeline/Models/Validation/UsernameValidator.cs | 37 | ||||
-rw-r--r-- | Timeline/Models/Validation/Validator.cs | 58 |
2 files changed, 45 insertions, 50 deletions
diff --git a/Timeline/Models/Validation/UsernameValidator.cs b/Timeline/Models/Validation/UsernameValidator.cs index ecc3b5b3..65d4da71 100644 --- a/Timeline/Models/Validation/UsernameValidator.cs +++ b/Timeline/Models/Validation/UsernameValidator.cs @@ -1,46 +1,39 @@ -using Microsoft.Extensions.Localization;
-using System.Linq;
-using System.Text.RegularExpressions;
+using System.Linq;
namespace Timeline.Models.Validation
{
public class UsernameValidator : Validator<string>
{
public const int MaxLength = 26;
- public const string RegexPattern = @"^[a-zA-Z0-9_][a-zA-Z0-9-_]*$";
- private readonly Regex _regex = new Regex(RegexPattern);
-
- protected override bool DoValidate(string value, IStringLocalizerFactory localizerFactory, out string message)
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Already checked in base class.")]
+ protected override (bool, ValidationMessageGenerator) DoValidate(string value)
{
if (value.Length == 0)
{
- message = "An empty string is not permitted.";
- return false;
+ return (false, factory =>
+ factory?.Create(typeof(UsernameValidator))?["ValidationMessageEmptyString"]
+ ?? Resources.Models.Validation.UsernameValidator.InvariantValidationMessageEmptyString);
}
if (value.Length > 26)
{
- message = $"Too long, more than 26 characters is not premitted, found {value.Length}.";
- return false;
+ return (false, factory =>
+ factory?.Create(typeof(UsernameValidator))?["ValidationMessageTooLong"]
+ ?? Resources.Models.Validation.UsernameValidator.InvariantValidationMessageTooLong);
}
foreach ((char c, int i) in value.Select((c, i) => (c, i)))
- if (char.IsWhiteSpace(c))
+ {
+ if (!(char.IsLetterOrDigit(c) || c == '-' || c == '_'))
{
- message = $"A whitespace is found at {i} . Whitespace is not permited.";
- return false;
+ return (false, factory =>
+ factory?.Create(typeof(UsernameValidator))?["ValidationMessageInvalidChar"]
+ ?? Resources.Models.Validation.UsernameValidator.InvariantValidationMessageInvalidChar);
}
-
- var match = _regex.Match(value);
- if (!match.Success)
- {
- message = "Regex match failed.";
- return false;
}
- message = ValidationConstants.SuccessMessage;
- return true;
+ return (true, SuccessMessageGenerator);
}
}
}
diff --git a/Timeline/Models/Validation/Validator.cs b/Timeline/Models/Validation/Validator.cs index a3800b71..606ba7b4 100644 --- a/Timeline/Models/Validation/Validator.cs +++ b/Timeline/Models/Validation/Validator.cs @@ -7,8 +7,15 @@ using Timeline.Helpers; namespace Timeline.Models.Validation
{
/// <summary>
+ /// Generate a message from a localizer factory.
+ /// If localizerFactory is null, it should return a neutral-cultural message.
+ /// </summary>
+ /// <param name="localizerFactory">The localizer factory. Could be null.</param>
+ /// <returns>The message.</returns>
+ public delegate string ValidationMessageGenerator(IStringLocalizerFactory? localizerFactory);
+
+ /// <summary>
/// A validator to validate value.
- /// See <see cref="Validate(object?, out string)"/>.
/// </summary>
public interface IValidator
{
@@ -16,14 +23,8 @@ namespace Timeline.Models.Validation /// Validate given value.
/// </summary>
/// <param name="value">The value to validate.</param>
- /// <param name="message">The validation message.</param>
- /// <returns>True if validation passed. Otherwise false.</returns>
- bool Validate(object? value, IStringLocalizerFactory localizerFactory, out string message);
- }
-
- public static class ValidationConstants
- {
- public const string SuccessMessage = "Validation succeeded.";
+ /// <returns>Validation success or not and the message generator.</returns>
+ (bool, ValidationMessageGenerator) Validate(object? value);
}
/// <summary>
@@ -39,36 +40,32 @@ namespace Timeline.Models.Validation /// </remarks>
public abstract class Validator<T> : IValidator
{
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "<Pending>")]
- public bool Validate(object? value, IStringLocalizerFactory localizerFactory, out string message)
+ public (bool, ValidationMessageGenerator) Validate(object? value)
{
if (value == null)
{
- var localizer = localizerFactory.Create("Models.Validation.Validator");
- message = localizer["ValidatorMessageNull"];
- return false;
+ return (false, factory =>
+ factory?.Create("Models.Validation.Validator")?["ValidatorMessageNull"]
+ ?? Resources.Models.Validation.Validator.InvariantValidatorMessageNull
+ );
}
if (value is T v)
{
- return DoValidate(v, localizerFactory, out message);
+ return DoValidate(v);
}
else
{
- var localizer = localizerFactory.Create("Models.Validation.Validator");
- message = localizer["ValidatorMessageBadType", typeof(T).FullName];
- return false;
+ return (false, factory =>
+ factory?.Create("Models.Validation.Validator")?["ValidatorMessageBadType", typeof(T).FullName]
+ ?? Resources.Models.Validation.Validator.InvariantValidatorMessageBadType);
}
}
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods")]
- protected static string GetSuccessMessage(IStringLocalizerFactory factory)
- {
- var localizer = factory.Create("Models.Validation.Validator");
- return localizer["ValidatorMessageSuccess"];
- }
+ protected static ValidationMessageGenerator SuccessMessageGenerator { get; } = factory =>
+ factory?.Create("Models.Validation.Validator")?["ValidatorMessageSuccess"] ?? Resources.Models.Validation.Validator.InvariantValidatorMessageSuccess;
- protected abstract bool DoValidate(T value, IStringLocalizerFactory localizerFactory, out string message);
+ protected abstract (bool, ValidationMessageGenerator) DoValidate(T value);
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
@@ -113,11 +110,16 @@ namespace Timeline.Models.Validation protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
- var localizerFactory = validationContext.GetRequiredService<IStringLocalizerFactory>();
- if (_validator.Validate(value, localizerFactory, out var message))
+ var (result, messageGenerator) = _validator.Validate(value);
+ if (result)
+ {
return ValidationResult.Success;
+ }
else
- return new ValidationResult(message);
+ {
+ var localizerFactory = validationContext.GetRequiredService<IStringLocalizerFactory>();
+ return new ValidationResult(messageGenerator(localizerFactory));
+ }
}
}
}
|