Blazor ValidationMessage being conditional

Kuler Master 306 Reputation points
2024-12-03T11:08:10.6566667+00:00

Hello,

I have a registration form where the users can select if they are private or company.

What I need is to make the Company Name validation conditional. Meaning, if they select a company it gets enabled and if they select a private it gets disabled.

public class Credential : ValidationAttribute 
{
    [Required(ErrorMessageResourceName = "Validation_RequiredField", ErrorMessageResourceType = typeof(Resources))]
    public int? AccountType { get; set; }
    [Required(ErrorMessageResourceName = "Validation_RequiredField", ErrorMessageResourceType = typeof(Resources))]
    public string? FirstName { get; set; }
    [Required(ErrorMessageResourceName = "Validation_RequiredField", ErrorMessageResourceType = typeof(Resources))]
    public string? LastName { get; set; }
    [Required(ErrorMessageResourceName = "Validation_RequiredField", ErrorMessageResourceType = typeof(Resources))]
    public string? CompanyName { get; set; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var cred = (Credential)validationContext.ObjectInstance;
        if(cred.AccountType == 0)
        {
            //-- Disable CompanyName validation;
        }
        else
       {
           //-- Enable CompanyName validation;
       }
        return ValidationResult.Success;
    }
}

<div class="row mb-4">
    <div class="col">
        <div class="btn-group" role="group">
            @foreach (var accounttype in accounttypes)
            {
                @if (accounttypes.IndexOf(accounttype) == 0)
                {
                    <input type="radio" class="btn-check" name="acctType" id="acctType1" autocomplete="off" onchange="AccountTypeChanged('private');" checked>
                    <label class="btn btn-outline-primary" for="acctType1">@accounttype <i class="fa-solid fa-briefcase"></i></label>
                }
                else
                {
                    <input type="radio" class="btn-check" name="acctType" id="acctType2" autocomplete="off" onchange="AccountTypeChanged('company');">
                    <label class="btn btn-outline-primary" for="acctType2">@accounttype <i class="fa-solid fa-building"></i></label>
                }
            }
        </div>
    </div>
</div>

<div class="row mb-4">
    <div class="col-6">
        <div class="form-floating">
            <InputText type="text" class="form-control" id="firstname" placeholder="John" @bind-Value="@_credential.FirstName" />
            <label for="firstname"><i class="fa-solid fa-user"></i> First name</label>
            <ValidationMessage For="@(() => _credential.FirstName)" />
        </div>
    </div>
    <div class="col-6">
        <div class="form-floating">
            <InputText type="text" class="form-control" id="lastname" placeholder="Doe" @bind-Value="@_credential.LastName" />
            <label for="lastname"><i class="fa-regular fa-user"></i> Last name</label>
            <ValidationMessage For="@(() => _credential.LastName)" />
        </div>
    </div>
</div>

<div class="row mb-4 d-none" id="rowCompany">
    <div class="col">
        <div class="form-floating">
            <InputText type="text" class="form-control" id="companyname" placeholder="Foo LLC" @bind-Value="@_credential.CompanyName" />
            <label for="companyname"><i class="fa-regular fa-building"></i> Company name</label>
            <ValidationMessage For="@(() => _credential.CompanyName)" />
        </div>
    </div>
</div>

<script>
    function AccountTypeChanged(typeofaccount){
        var alert = $("#alertWarning");
        var company = $("#rowCompany");
        if (typeofaccount == 'company') {
            alert.removeClass("d-none");
            company.removeClass("d-none");
        }
        else{
            alert.addClass("d-none");
            company.addClass("d-none");
        }
    }
</script>

Thank you so much!

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,704 questions
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,636 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,547 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 68,486 Reputation points
    2024-12-03T16:24:45.51+00:00

    You will need to write custom validation, or pick a 3rd party validation library that supports conditional validation.

    https://learn.microsoft.com/en-us/aspnet/core/blazor/forms/validation?view=aspnetcore-9.0

    0 comments No comments

  2. Ping Ni-MSFT 4,805 Reputation points Microsoft Vendor
    2024-12-24T05:36:01.05+00:00

    Hi @Kuler Master

    For conditional validation you could refer to the demo below:

    Model design and custom ValidationAttribute

    public class Credential
    {
        [Required]
        public int AccountType { get; set; } 
        [Required]
        public string? FirstName { get; set; }
        [Required]
        public string LastName { get; set; }
        [RequieredIf(Condition = "AccountType")]
        public string CompanyName { get; set; }  // Make CompanyName not required initially.
    }
    public class RequieredIfAttribute : ValidationAttribute
    {
        public string? Condition { get; set; }
        public RequieredIfAttribute()
        {
        }
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            string data = (string)value;
            int? selectedType = (int?)validationContext.ObjectType.GetProperty(Condition).GetValue(validationContext.ObjectInstance, null);
            if (string.IsNullOrEmpty(data) && selectedType != 0)
            {
                return new ValidationResult("Company Name is requiered.");
            }
            return ValidationResult.Success;
        }
    }
    

    Razor Component

    @page "/"
    @rendermode InteractiveServer
    <EditForm Model="_credential" OnValidSubmit="Submit" FormName="TestForm">
        <ValidationSummary />
        <DataAnnotationsValidator />
        <div class="row mb-4">
            <div class="col">
                <div class="btn-group" role="group">
                    <InputRadioGroup @bind-Value="@_credential.AccountType">
                        @foreach (var accounttype in accounttypes)
                        {
                            var index = accounttypes.IndexOf(accounttype);
                            <InputRadio Value="index" />
                            @accounttype
                            <br>
                        }
                    </InputRadioGroup>
                  
                </div>
            </div>
        </div>
        <div class="row mb-4">
            <div class="col-6">
                <div class="form-floating">
                    <InputText type="text" class="form-control" id="firstname" placeholder="John" @bind-Value="@_credential.FirstName" />
                    <label for="firstname"><i class="fa-solid fa-user"></i> First name</label>
                    <ValidationMessage For="@(() => _credential.FirstName)" />
                </div>
            </div>
            <div class="col-6">
                <div class="form-floating">
                    <InputText type="text" class="form-control" id="lastname" placeholder="Doe" @bind-Value="@_credential.LastName" />
                    <label for="lastname"><i class="fa-regular fa-user"></i> Last name</label>
                    <ValidationMessage For="@(() => _credential.LastName)" />
                </div>
            </div>
        </div>
        <div class="row mb-4" id="rowCompany">
            <div class="col">
                <div class="form-floating">
                    <InputText type="text" class="form-control" id="companyname" placeholder="Foo LLC" @bind-Value="@_credential.CompanyName" />
                    <label for="companyname"><i class="fa-regular fa-building"></i> Company name</label>
                    <ValidationMessage For="@(() => _credential.CompanyName)" />
                </div>
            </div>
        </div>
        <button type="submit">Submit</button>
    </EditForm>
    @code {
        private EditContext? editContext;
        private List<string> accounttypes = new List<string> { "Private", "Company" };
        private Credential _credential { get; set; } = new();
        private void Submit(){
            
        }
    }
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Rena

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.