Files
2024-03-27 15:05:33 +00:00

225 lines
9.0 KiB
C#

using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Text.RegularExpressions;
namespace Sarand.Net.Standard.Base.Helpers
{
//=======================================================================
public static class SacsDataValidationHelper
{
//-------------------------------------------------------------------
// Email address.
//-------------------------------------------------------------------
/// <summary>
/// Validate the email address.
/// <para>Ref. https://stackoverflow.com/questions/1365407/c-sharp-code-to-validate-email-address</para>
/// </summary>
public static bool IsValidEmailAddress(String value)
{
if (StringUtil.IsEmpty(value)) return false;
if (!new EmailAddressAttribute().IsValid(value)) return false;
// Exclude spaces.
if (Regex.Matches(value, " ").Count > 0) return false;
// Exclude consecutive dots.
if (Regex.Matches(value, "\\.\\.").Count > 0) return false;
// Check for at least one dot after @ [to ensure john@smith is invalid].
if (Regex.Matches(value, "@[^@.]+\\.").Count < 1) return false;
return true;
}
//-------------------------------------------------------------------
// URL.
//-------------------------------------------------------------------
/// <summary>
/// Validate the URL, including protocol and leading slashes ('//').
/// </summary>
public static bool IsCompleteUrl(String value)
{
if (StringUtil.IsEmpty(value)) return false;
if (!new UrlAttribute().IsValid(value))
return false;
return true;
}
/// <summary>
/// Validate the URL.
/// <para>NB AllowsURL to start with leading slashes ('//'), ie. no protocol ('https:') or to start with the domain (no protocol or slashes).</para>
/// <para>NB Use IsCompleteUrl to validate that protocol and slashes are also present.</para>
/// </summary>
public static bool IsValidUrl(String value)
{
if (StringUtil.IsEmpty((value ?? "").Trim())) return false;
// Ensure that value has at least one dot.
if (Regex.Matches(value, "\\.").Count == 0) return false;
// Ensure that value has no '@ symbols (unless encoded).
if (Regex.Matches(value, "\\@").Count > 0) return false;
// URL validation.
if (!new UrlAttribute().IsValid(value))
{
// URL validation insists on the full URL.
if (!new UrlAttribute().IsValid("//" + value))
{
if (!new UrlAttribute().IsValid("http://" + value))
return false;
}
}
return true;
}
// Wikipedia URLs. [[https:]//]xx.wikipedia.org...
private static readonly Regex reWikipediaUrl = new Regex("^(?:(?:http(?:s)?:)?//)?\\w{2}" + Regex.Escape(".wikipedia.org/wiki/") + ".+", RegexOptions.IgnoreCase);
private static readonly Regex reWikipediaUrl_Alt = new Regex("^(?:(?:http(?:s)?:)?//)?\\w{2}" + Regex.Escape(".wikipedia.org/w/index.php?") + ".+", RegexOptions.IgnoreCase);
public static bool IsValidWikipediaUrl(String value)
{
if (!IsValidUrl(value)) return false;
if (reWikipediaUrl.Matches(value).Count > 0) return true;
if (reWikipediaUrl_Alt.Matches(value).Count > 0) return true;
return false;
}
// Location URLs. [[https:]//]www.google.*/maps/place/...
private static readonly Regex reLocationUrl = new Regex("^(?:(?:http(?:s)?:)?//)?\\" + Regex.Escape("www.google.") + "\\w{2,3}" + Regex.Escape("/maps/place/") + ".+", RegexOptions.IgnoreCase);
private static readonly Regex reLocationUrl_Alt = new Regex("^(?:(?:http(?:s)?:)?//)?\\" + Regex.Escape("www.google.") + "\\w{2,3}" + Regex.Escape("/maps?") + ".+", RegexOptions.IgnoreCase);
public static bool IsValidLocationUrl(String value)
{
if (!IsValidUrl(value)) return false;
if (reLocationUrl.Matches(value).Count > 0) return true;
if (reLocationUrl_Alt.Matches(value).Count > 0) return true;
return false;
}
// LinkedIn URLs. [[https:]//][www|xx].linkedin.com/in...
private static readonly Regex reLinkedInUrl = new Regex("^(?:(?:http(?:s)?:)?//)?(?:(?:www|\\w{2})\\.)?" + Regex.Escape("linkedin.com/in/") + ".+", RegexOptions.IgnoreCase);
private static readonly Regex reLinkedInUrl_Company = new Regex("^(?:(?:http(?:s)?:)?//)?(?:(?:www|\\w{2})\\.)?" + Regex.Escape("linkedin.com/company/") + ".+", RegexOptions.IgnoreCase);
public static bool IsValidLinkedInUrl(String value)
{
if (!IsValidUrl(value)) return false;
if (reLinkedInUrl.Matches(value).Count > 0) return true;
if (reLinkedInUrl_Company.Matches(value).Count > 0) return true;
return false;
}
// Twitter URLs. [[http[s]:]//][wwww.]twitter.com/...
private static readonly Regex reTwitterUrl = new Regex("^(?:(?:http(?:s)?:)?//)?(?:www\\.)?" + Regex.Escape("twitter.com/") + ".+", RegexOptions.IgnoreCase);
public static bool IsValidTwitterUrl(String value)
{
if (!IsValidUrl(value)) return false;
if (reTwitterUrl.Matches(value).Count > 0) return true;
return false;
}
// Facebook URLs. [[https:]//][www.|xx.|xx-xx.]facebook.com/in...
private static readonly Regex reFacebookUrl = new Regex("^(?:(?:http(?:s)?:)?//)?(?:(?:www|\\w{2}|\\w{2}-\\w{2})\\.)?" + Regex.Escape("facebook.com/") + ".+", RegexOptions.IgnoreCase);
public static bool IsValidFacebookUrl(String value)
{
if (!IsValidUrl(value)) return false;
if (reFacebookUrl.Matches(value).Count > 0) return true;
return false;
}
// Instagram URLs. [[https:]//][www.]instagram.com/...
private static readonly Regex reInstagramUrl = new Regex("^(?:(?:http(?:s)?:)?//)?(?:www\\.)?" + Regex.Escape("instagram.com/") + ".+", RegexOptions.IgnoreCase);
public static bool IsValidInstagramUrl(String value)
{
if (!IsValidUrl(value)) return false;
if (reInstagramUrl.Matches(value).Count > 0) return true;
return false;
}
// YouTube URLs. [[https:]//][www.]youtube.com/...
private static readonly Regex reYouTubeUrl = new Regex("^(?:(?:http(?:s)?:)?//)?(?:www\\.)?" + Regex.Escape("youtube.com/") + ".+", RegexOptions.IgnoreCase);
public static bool IsValidYouTubeUrl(String value)
{
if (!IsValidUrl(value)) return false;
if (reYouTubeUrl.Matches(value).Count > 0) return true;
return false;
}
// Twitch URLs. [[https:]//][www.]twitch.com/...
private static readonly Regex reTwitchUrl = new Regex("^(?:(?:http(?:s)?:)?//)?(?:www\\.)?" + Regex.Escape("twitch.tv/") + ".+", RegexOptions.IgnoreCase);
public static bool IsValidTwitchUrl(String value)
{
if (!IsValidUrl(value)) return false;
if (reTwitchUrl.Matches(value).Count > 0) return true;
return false;
}
//-------------------------------------------------------------------
/// <summary>
/// Ensure that the website address is a valid URL, ie. at least starts with '//'.
/// <para>To allow the value to be used in an anchor element href attribute.</para>
/// </summary>
public static String QualifyAbsoluteUrl(String url)
{
if (!IsValidUrl(url)) return url;
if (IsCompleteUrl(url)) return url;
if (IsCompleteUrl("https:" + url)) return url;
return "//" + url;
}
//-------------------------------------------------------------------
// Phone number.
//-------------------------------------------------------------------
/// <summary>
/// Validate the phone number.
/// <para>Ref. https://www.twilio.com/blog/validating-phone-numbers-effectively-with-c-and-the-net-frameworks</para>
/// </summary>
public static bool IsValidPhone(String value)
{
if (StringUtil.IsEmpty(value)) return false;
if (!new PhoneAttribute().IsValid(value)) return false;
// Apply minimum length.
if (StringUtil.GetLength(value) < 8) return false;
return true;
}
//-------------------------------------------------------------------
// Tax identification number.
// European country Tax Identification Numbers:
// https://ec.europa.eu/taxation_customs/vies/faqvies.do#item_11
//-------------------------------------------------------------------
/// <summary>
/// Validate the tax identification number.
/// </summary>
public static bool IsValidTaxIdentificationNumber(String countryCode, String value)
{
if (StringUtil.IsEmpty(value)) return false;
//---------------------------------------------------------------
// GB, United Kingdom.
// Standard:
// GB999 9999 99 block of 3 digits, block of 4 digits and block of 2 digits [00-96]
// Branch:
// GB999 9999 99 9995 as above followed by block of 3 digits
// Government departments:
// GBGD9996 'GD' followed by block of 3 or 4 digits
// Health Authoritites:
// GBHA9997 'HA' followed by block of 3 or 4 digits
//---------------------------------------------------------------
// Apply minimum length.
if (StringUtil.GetLength(value) < 8) return false;
// Country prefix.
if (!value.StartsWith("GB")) return false;
return true;
}
//-------------------------------------------------------------------
}
//=======================================================================
}