Blazor 带有18位身份证号校验的TextBox

TextBox.razor :

TextBox.razor.cs

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Text.RegularExpressions;

namespace BlazorApp.Components
{
    public partial class TextBox : ComponentBase, IDisposable
    {
        [CascadingParameter]
        private EditContext? CascadedEditContext { get; set; }

        [Parameter]
        public string? Value { get; set; }

        [Parameter] public EventCallback ValueChanged { get; set; }

        [Parameter] public Expression>? ValueExpression { get; set; }

        [Parameter]
        public string LabelWidth { get; set; } = "80";

        [Parameter]
        public required string Label { get; set; }

        [Parameter]
        public string InputWidth { get; set; } = "300";


        [Parameter]
        public bool Disabled { get; set; }

        [Parameter]
        public bool IsIdCard { get; set; }

        [DisallowNull] public ElementReference? Element { get; protected set; }

        public TextBox()
        {
            _validationStateChangedHandler = OnValidateStateChanged;
        }
        private readonly EventHandler? _validationStateChangedHandler;
        private ValidationMessageStore? _validationMessages;

        private bool _hasInitializedParameters;
        protected string? CurrentValue
        {
            get => Value;
            set
            {
                if (Value != value)
                {
                    Value = value;

                    _ = ValueChanged.InvokeAsync(Value);
                    EditContext?.NotifyFieldChanged(FieldIdentifier);
                }
            }
        }
        private string cssDanger = "";
        protected EditContext EditContext { get; set; } = default!;
        protected internal FieldIdentifier FieldIdentifier { get; set; }
        protected override void OnParametersSet()
        {
            base.OnParametersSet();
            if (!_hasInitializedParameters)
            {

                if (ValueExpression == null)
                {
                    throw new InvalidOperationException($"Date requires a value for the 'ValueExpression'" +
                        $"parameter. Normally this is provided automatically when using 'bind-Value'.");
                }

                FieldIdentifier = FieldIdentifier.Create(ValueExpression);
                if (CascadedEditContext != null)
                {
                    EditContext = CascadedEditContext;
                    EditContext.OnValidationStateChanged += _validationStateChangedHandler;
                }

                _hasInitializedParameters = true;

            }
            Label = GetLabel(Label);
            LabelWidth = LabelWidth.Contains("px") ? LabelWidth : LabelWidth + "px";
            InputWidth = InputWidth.Contains("px") ? InputWidth : InputWidth + "px";
        }
        private static string GetLabel(string label)
        {
            if (string.IsNullOrWhiteSpace(label))
            {
                return string.Empty;
            }
            if (label.Contains(':'))
            {
                return label;
            }
            return label + ":";
        }
        private void OnValidateStateChanged(object? sender, ValidationStateChangedEventArgs eventArgs)
        {
            if (EditContext is null)
            {
                return;
            }

            if (IsIdCard)
            {
                _validationMessages?.Clear(FieldIdentifier);
                var erryMessage = CheckIDCard18(Value);
                if (!string.IsNullOrEmpty(erryMessage))
                {
                    _validationMessages ??= new ValidationMessageStore(EditContext);
                    _validationMessages.Add(FieldIdentifier, erryMessage);
                }
            }

            if (EditContext.GetValidationMessages(FieldIdentifier).Any())
            {
                cssDanger = "border-danger";
            }
            else
            {
                cssDanger = "";
            }

            StateHasChanged();
        }
        private static string CheckIDCard18(string? cardId)
        {
            if (string.IsNullOrWhiteSpace(cardId))
                return "身份证号必须填写!";

            if (cardId.Length != 18)
                return "身份证号必须长度为18位!";

            var address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (!address.Contains(cardId.Remove(2), StringComparison.CurrentCulture))
                return "身份证号前2位代码错误!";

            string pattern = @"^\d{17}(?:\d|X|x)$";
            string birth = cardId.Substring(6, 8).Insert(6, "-").Insert(4, "-");

            // 加权数组,用于验证最后一位的校验数字
            int[] arr_weight = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
            // 最后一位计算出来的校验数组,如果不等于这些数字将不正确
            string[] id_last = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" };
            int sum = 0;
            //通过循环前16位计算出最后一位的数字
            for (int i = 0; i < 17; i++)
            {
                sum += arr_weight[i] * int.Parse(cardId[i].ToString());
            }
            // 实际校验位的值
            var result = sum % 11;

            // 首先18位格式检查
            if (Regex.IsMatch(cardId, pattern))
            {   // 出生日期检查
                if (DateTime.TryParse(birth, out _))
                {
                    // 校验位检查
                    if (id_last[result] == cardId[17].ToString().ToUpper())
                    {
                        return "";//身份证验证成功!
                    }
                    else
                    {
                        return "身份证最后一位校验错误!";
                    }
                }
                else
                {
                    return "出生日期验证失败!";
                }
            }
            else
            {
                return "身份证号格式错误!";
            }
        }

        public void Dispose()
        {
            if (EditContext is not null)
            {
                EditContext.OnValidationStateChanged -= _validationStateChangedHandler;
            }
            GC.SuppressFinalize(this);
        }
    }

}

Blazor 带有18位身份证号校验的TextBox_第1张图片

 

你可能感兴趣的:(Blazor,C#,c#,Blazor,自定义,可重用基础组件,身份证号校验)