-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* `CurrencyCodes.Currency` is record now * `EuVatId.Syntax` is frozen now * `(I)ValidationInfo.Seen` is a hash set now * `ObjectValidationEventArgs.Seen` is a hash set now * `ReflectionHelper` stores frozen sets now * `ValidatableTypes` stores hash sets now * By-ref and by-ref-like properties will be skipped + Updated references + `CurrencyCodes.Currency.Factor/Validate` are virtual now + Added `(Item)HostAttribute`
- Loading branch information
Showing
31 changed files
with
313 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace ObjectValidation_Tests | ||
{ | ||
[TestClass] | ||
public class A_Initialization | ||
{ | ||
[AssemblyInitialize] | ||
public static void Init(TestContext tc) => wan24.Tests.TestsInitialization.Init(tc); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using System.Net; | ||
using System.Net.NetworkInformation; | ||
using System.Net.Sockets; | ||
using System.Security.Cryptography; | ||
|
||
namespace wan24.ObjectValidation | ||
{ | ||
/// <summary> | ||
/// Host name or IP address validation attribute | ||
/// </summary> | ||
/// <remarks> | ||
/// Constructor | ||
/// </remarks> | ||
public class HostAttribute() : ValidationAttributeBase() | ||
{ | ||
/// <summary> | ||
/// If IPv4 addresses are allowed | ||
/// </summary> | ||
public bool AllowIPv4 { get; set; } = true; | ||
|
||
/// <summary> | ||
/// If IPv6 addresses are allowed | ||
/// </summary> | ||
public bool AllowIPv6 { get; set; } = true; | ||
|
||
/// <summary> | ||
/// Check if the hostname (DNS lookup) or IP address (ICMP) exists | ||
/// </summary> | ||
public bool CheckIfExists { get; set; } | ||
|
||
/// <summary> | ||
/// Ping timeout in ms | ||
/// </summary> | ||
public int PingTimeout { get; set; } = 300; | ||
|
||
/// <inheritdoc/> | ||
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) | ||
{ | ||
if (value is null) return null; | ||
if (value is not string str) return this.CreateValidationResult($"Hostname or IP address value as {typeof(string)} expected", validationContext); | ||
UriHostNameType type = Uri.CheckHostName(str); | ||
IPAddress? ip; | ||
switch (type) | ||
{ | ||
case UriHostNameType.Dns: | ||
if (!CheckIfExists) return null; | ||
try | ||
{ | ||
Dns.GetHostEntry(str); | ||
return null; | ||
} | ||
catch (Exception ex) | ||
{ | ||
return this.CreateValidationResult($"Hostname DNS lookup failed: {ex.Message ?? ex.GetType().ToString()}", validationContext); | ||
} | ||
case UriHostNameType.IPv4: | ||
if(!IPAddress.TryParse(str, out ip)) return this.CreateValidationResult($"Host IPv4 address parsing failed", validationContext); | ||
if (ip.AddressFamily != AddressFamily.InterNetwork) return this.CreateValidationResult($"Detected host IPv4 address parsed to IPv6", validationContext); | ||
break; | ||
case UriHostNameType.IPv6: | ||
if (!IPAddress.TryParse(str, out ip)) return this.CreateValidationResult($"Host IPv6 address parsing failed", validationContext); | ||
if (ip.AddressFamily != AddressFamily.InterNetworkV6) return this.CreateValidationResult($"Detected host IPv6 address parsed to IPv4", validationContext); | ||
break; | ||
default: | ||
return this.CreateValidationResult($"Hostname or IP address value invalid ({type})", validationContext); | ||
} | ||
if (!CheckIfExists) return null; | ||
using Ping ping = new(); | ||
try | ||
{ | ||
PingReply pong = ping.Send(ip, PingTimeout, RandomNumberGenerator.GetBytes(count: 32), new() | ||
{ | ||
DontFragment = true | ||
}); | ||
return pong.Status == IPStatus.Success | ||
? null | ||
: this.CreateValidationResult($"Ping to {ip} failed: {pong.Status}", validationContext); | ||
} | ||
catch(Exception ex) | ||
{ | ||
return this.CreateValidationResult($"Ping to {ip} failed exceptional: {ex.Message ?? ex.GetType().ToString()}", validationContext); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
namespace wan24.ObjectValidation | ||
{ | ||
/// <summary> | ||
/// Host name or IP address validation attribute | ||
/// </summary> | ||
/// <remarks> | ||
/// Constructor | ||
/// </remarks> | ||
/// <param name="target">Validation target</param> | ||
public class ItemHostAttribute(ItemValidationTargets target = ItemValidationTargets.Item) : ItemValidationAttribute(target, new HostAttribute()) | ||
{ | ||
/// <summary> | ||
/// If IPv4 addresses are allowed | ||
/// </summary> | ||
public bool AllowIPv4 | ||
{ | ||
get => ((HostAttribute)ValidationAttribute).AllowIPv4; | ||
set => ((HostAttribute)ValidationAttribute).AllowIPv4 = value; | ||
} | ||
|
||
/// <summary> | ||
/// If IPv6 addresses are allowed | ||
/// </summary> | ||
public bool AllowIPv6 | ||
{ | ||
get => ((HostAttribute)ValidationAttribute).AllowIPv6; | ||
set => ((HostAttribute)ValidationAttribute).AllowIPv6 = value; | ||
} | ||
|
||
/// <summary> | ||
/// Check if the hostname (DNS lookup) or IP address (ICMP) exists | ||
/// </summary> | ||
public bool CheckIfExists | ||
{ | ||
get => ((HostAttribute)ValidationAttribute).CheckIfExists; | ||
set => ((HostAttribute)ValidationAttribute).CheckIfExists = value; | ||
} | ||
|
||
/// <summary> | ||
/// Ping timeout in ms | ||
/// </summary> | ||
public int PingTimeout | ||
{ | ||
get => ((HostAttribute)ValidationAttribute).PingTimeout; | ||
set => ((HostAttribute)ValidationAttribute).PingTimeout = value; | ||
} | ||
} | ||
} |
Oops, something went wrong.