Add new validation attribute framework
This commit is contained in:
parent
37477b4df0
commit
57ee784cc6
13
Validation/AlphanumericAttribute.cs
Normal file
13
Validation/AlphanumericAttribute.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NejCommon.Validation;
|
||||
|
||||
public class AlphanumericAttribute : RegexAttribute{
|
||||
public AlphanumericAttribute() : base("^[a-zA-Z0-9]*$","Aabb123"){
|
||||
|
||||
}
|
||||
}
|
||||
50
Validation/IbanAttribute.cs
Normal file
50
Validation/IbanAttribute.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NejCommon.Validation;
|
||||
|
||||
public class IbanAttribute : RegexAttribute{
|
||||
public const string IbanRegex = @"^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$";
|
||||
public IbanAttribute() : base(IbanRegex,"CZ4622500000000104816258"){
|
||||
|
||||
}
|
||||
|
||||
protected override ValidationResult IsValid(object value, ValidationContext ctx)
|
||||
{
|
||||
if (value is null)
|
||||
return ValidationResult.Success!;
|
||||
var res = base.IsValid(value, ctx);
|
||||
if (res != ValidationResult.Success)
|
||||
return res;
|
||||
|
||||
string iban = value as string;
|
||||
|
||||
string rearranged = iban.Substring(4) + iban.Substring(0, 4);
|
||||
|
||||
// Convert letters to numbers (A=10, B=11, ..., Z=35)
|
||||
StringBuilder numericIban = new StringBuilder();
|
||||
foreach (char ch in rearranged)
|
||||
{
|
||||
if (char.IsLetter(ch))
|
||||
{
|
||||
int charVal = ch - 'A' + 10;
|
||||
numericIban.Append(charVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
numericIban.Append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to BigInteger and compute mod 97
|
||||
BigInteger ibanNumber = BigInteger.Parse(numericIban.ToString());
|
||||
|
||||
if(ibanNumber % 97 == 1)
|
||||
return ValidationResult.Success;
|
||||
else
|
||||
return new ValidationResult("Invalid checksum of IBAN");
|
||||
}
|
||||
}
|
||||
19
Validation/NejValidationAttribute.cs
Normal file
19
Validation/NejValidationAttribute.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace NejCommon.Validation;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public abstract class NejValidationAttribute : ValidationAttribute
|
||||
{
|
||||
public NejValidationAttribute(string errorMsg = null)
|
||||
{
|
||||
ErrorMessage = errorMsg ?? $"Invalid format";
|
||||
}
|
||||
|
||||
public abstract string ExampleJson { get; }
|
||||
|
||||
public virtual void ApplySchema(OpenApiSchema schema) { }
|
||||
}
|
||||
42
Validation/NejValidationAttributeFilter.cs
Normal file
42
Validation/NejValidationAttributeFilter.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace NejCommon.Validation;
|
||||
|
||||
public class NejValidationAttributeFilter : ISchemaFilter
|
||||
{
|
||||
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
|
||||
{
|
||||
var type = context.Type;
|
||||
var attrOnType = context.MemberInfo?.GetCustomAttributes(typeof(NejValidationAttribute), true)?.Select(a => a as NejValidationAttribute)?.FirstOrDefault();
|
||||
if (attrOnType != null)
|
||||
{
|
||||
Console.WriteLine("Added examples for: " + context.MemberInfo?.Name);
|
||||
schema.Example = OpenApiAnyFactory.CreateFromJson(attrOnType.ExampleJson);
|
||||
attrOnType.ApplySchema(schema);
|
||||
}
|
||||
|
||||
var attrOnType2 = context.ParameterInfo?.GetCustomAttributes(typeof(NejValidationAttribute), true)?.Select(a => a as NejValidationAttribute)?.FirstOrDefault();
|
||||
if (attrOnType2 != null)
|
||||
{
|
||||
Console.WriteLine("Added examples for: " + context.ParameterInfo?.Name);
|
||||
schema.Example = OpenApiAnyFactory.CreateFromJson(attrOnType2.ExampleJson);
|
||||
attrOnType.ApplySchema(schema);
|
||||
}
|
||||
|
||||
foreach (var prop in type.GetProperties())
|
||||
{
|
||||
if (schema.Properties.TryGetValue(prop.Name, out var pschema))
|
||||
{
|
||||
Console.WriteLine("Schema for: " + prop.Name);
|
||||
var attr = prop.GetCustomAttributes(typeof(NejValidationAttribute), true).Select(a => a as NejValidationAttribute).FirstOrDefault();
|
||||
if (attr != null)
|
||||
{
|
||||
Console.WriteLine("Added examples for: " + prop.Name);
|
||||
pschema.Example = OpenApiAnyFactory.CreateFromJson(attr.ExampleJson);
|
||||
attrOnType.ApplySchema(schema);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Validation/RegexAttribute.cs
Normal file
36
Validation/RegexAttribute.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace NejCommon.Validation;
|
||||
|
||||
public class RegexAttribute : NejValidationAttribute
|
||||
{
|
||||
public override string ExampleJson { get; }
|
||||
public string Pattern { get; }
|
||||
public RegexAttribute(string pattern, string example, string errorMsg = null)
|
||||
{
|
||||
Pattern = pattern;
|
||||
ExampleJson = JsonSerializer.Serialize(example);
|
||||
ErrorMessage = errorMsg ?? $"Invalid format (must match {pattern})";
|
||||
}
|
||||
|
||||
protected override ValidationResult IsValid(object value, ValidationContext ctx)
|
||||
{
|
||||
if (value is null)
|
||||
return ValidationResult.Success!;
|
||||
|
||||
var str = value as string;
|
||||
if (string.IsNullOrWhiteSpace(str) || !Regex.IsMatch(str, Pattern))
|
||||
return new ValidationResult(ErrorMessage);
|
||||
return ValidationResult.Success!;
|
||||
}
|
||||
|
||||
public override void ApplySchema(OpenApiSchema schema)
|
||||
{
|
||||
base.ApplySchema(schema);
|
||||
schema.Pattern = Pattern;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user