Blazor:基于另一个字段的自定义验证

Jav*_*aKB 5 blazor blazor-server-side blazor-webassembly

我正在尝试根据表单上的另一个字段在 Blazor 中构建自定义验证器。要求是当用户选中“接收短信”复选框时强制输入电话号码。我用谷歌搜索了很多,但只能找到验证空字符串或某些硬编码字符串的自定义验证器。有没有办法可以根据 Blazor 中另一个字段的值验证一个字段?

电话号码验证器:

public class PhoneNumberValidaton : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null)
        {
            return new ValidationResult("Phone Number is mandatory if you want to receive text messages", new[] { validationContext.MemberName });
        }

        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

模型:

public class UserModel
{
    public int Id { get; set; }

    [Required]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Required]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    [PhoneNumberValidaton]
    [Display(Name = "Phone Number")]
    public string Phone { get; set; }

    [Required]
    [Display(Name = "Receive Text Messages")]
    public bool CanReceiveText { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Ibr*_*imi 7

要求是当用户选中“接收短信”复选框时强制输入电话号码

您可以创建一个验证属性来检查另一个属性的值,如果它与目标值匹配,则该属性是必需的。例如,如果CanReceiveTextvalue 为true,则将该Phone属性设置为必需。

[RequiredIfAttribute("CanReceiveText", true)]
[Display(Name = "Phone Number")]
public string Phone { get; set; }

[Required]
[Display(Name = "Receive Text Messages")]
public bool CanReceiveText { get; set; }
Run Code Online (Sandbox Code Playgroud)
public class RequiredIfAttribute : ValidationAttribute
{
    readonly RequiredAttribute _innerAttribute = new RequiredAttribute();
    private string _dependentProperty { get; }
    private object _targetValue { get; }

    public RequiredIfAttribute(string dependentProperty, object targetValue)
    {
        _dependentProperty = dependentProperty;
        _targetValue = targetValue;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var field = validationContext.ObjectType.GetProperty(_dependentProperty);
        if (field != null)
        {
            var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
            if ((dependentValue == null && _targetValue == null) || dependentValue.Equals(_targetValue))
            {
                if (!_innerAttribute.IsValid(value))
                {
                    var name = validationContext.DisplayName;
                    var specificErrorMessage = ErrorMessage;
                    if (string.IsNullOrEmpty(specificErrorMessage))
                        specificErrorMessage = $"{name} is required.";

                    return new ValidationResult(specificErrorMessage, new[] { validationContext.MemberName });
                }
            }
            return ValidationResult.Success;
        }
        return new ValidationResult(FormatErrorMessage(_dependentProperty));
    }
}
Run Code Online (Sandbox Code Playgroud)

在线演示:

https://blazorfiddle.com/s/p5zfylbm

工作示例:

@page "/"
@using System.ComponentModel.DataAnnotations

<EditForm Model="@userModel" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator/>
    <ValidationSummary/>

    <p>
        <label for="FirstName">FirstName: </label>
        <InputText id="FirstName" @bind-Value="userModel.FirstName"/>
        <ValidationMessage For="() => userModel.FirstName"/>
    </p>
    <p>
        <label for="LastName">LastName: </label>
        <InputText id="LastName" @bind-Value="userModel.LastName"/>
        <ValidationMessage For="() => userModel.LastName"/>
    </p>
    <p>
        <label for="Phone">Phone Number: </label>
        <InputText id="Phone" @bind-Value="userModel.Phone"/>
        <ValidationMessage For="() => userModel.Phone"/>
    </p>
    <p>
        <label for="CanReceiveText">Receive Text Messages: </label>
        <InputCheckbox id="CanReceiveText" @bind-Value="userModel.CanReceiveText"/>
        <ValidationMessage For="() => userModel.CanReceiveText"/>
    </p>

    <button type="submit">Submit</button>
</EditForm>

@code {

    readonly UserModel userModel = new UserModel();

    private void HandleValidSubmit()
    {
    // Save the data
    }

    public class UserModel
    {
        public int Id { get; set; }

        [Required]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [Required]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [RequiredIfAttribute("CanReceiveText", true)]
        [Display(Name = "Phone Number")]
        public string Phone { get; set; }

        [Required]
        [Display(Name = "Receive Text Messages")]
        public bool CanReceiveText { get; set; }
    }

    public class RequiredIfAttribute : ValidationAttribute
    {
        readonly RequiredAttribute _innerAttribute = new RequiredAttribute();
        private string _dependentProperty { get; }
        private object _targetValue { get; }

        public RequiredIfAttribute(string dependentProperty, object targetValue)
        {
            _dependentProperty = dependentProperty;
            _targetValue = targetValue;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var field = validationContext.ObjectType.GetProperty(_dependentProperty);
            if (field != null)
            {
                var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
                if ((dependentValue == null && _targetValue == null) || dependentValue.Equals(_targetValue))
                {
                    if (!_innerAttribute.IsValid(value))
                    {
                        var name = validationContext.DisplayName;
                        var specificErrorMessage = ErrorMessage;
                        if (string.IsNullOrEmpty(specificErrorMessage))
                            specificErrorMessage = $"{name} is required.";

                        return new ValidationResult(specificErrorMessage, new[] { validationContext.MemberName });
                    }
                }
                return ValidationResult.Success;
            }
            return new ValidationResult(FormatErrorMessage(_dependentProperty));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果: 在此输入图像描述