I'm using Blazor to create a form where users need to select a "roda" from a dropdown.
The problem is that both the custom error message i defined in the viewModel ("Por favor escolha uma roda") and the default error message appear when no selection is made. I only want my custom error message to be displayed.
How can I ensure that only the custom error message appears?
Error Image
My ViewModel has a validation rule to show an error message if no "roda" is selected:
[Required(ErrorMessage = "Por favor escolha uma roda")]
public int? rodaEscolhida { get; set; }
In the form, I'm binding the property like this:
<div class="mb-3">
<label for="roda" class="form-label">RODA:</label>
<InputSelect id="roda" @bind-Value="ProductViewModel.rodaEscolhida" class="form-control">
<option hidden value="">Selecione...</option>
@foreach (var component in Components.Where(c => c.tipo == "RODA"))
{
<option value="@component.Id">@component.nome</option>
}
</InputSelect>
<ValidationMessage For="() => ProductViewModel.rodaEscolhida" class="text-danger" />
</div>
EDIT: Sorry for the dump of code! Below is the code for the Entity and ViewModel I use to manage products, along with the full Create Product method.
@page "/products/create"
@using Microsoft.EntityFrameworkCore
@using CadeirasLusitanas.Models.Entities
@using CadeirasLusitanas.Models.ViewModels
@inject IDbContextFactory<CadeirasLusitanas.Data.CadeirasLusitanasContext> DbFactory
@inject NavigationManager NavigationManager
<style>
.container {
margin-left: 0;
font-family: Arial, sans-serif;
text-align: center;
justify-content: center;
height: 76vh;
overflow-y: auto;
padding-top: 0;
}
.container::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.container::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 10px;
border: 2px solid #f2f2f2;
}
.container::-webkit-scrollbar-thumb:hover {
background-color: #555;
}
.container .table {
margin-left: 0;
padding-top: 0;
justify-content: left;
text-align: left;
width: 100%;
background-color: #E9E9E8;
border: none;
}
.container .table th {
position: sticky;
top: 0;
z-index: 10;
border: none;
font-size: 1.6rem;
text-align: center;
font-weight: 500;
background-color: white;
}
.container .table td {
line-height: 3;
border: none;
text-align: center;
font-size: 1.6rem;
}
.container .table tbody {
border-top: none;
}
.container .table thead {
border-bottom: none;
background-color: white;
}
.mb-3 .form-control {
border: 3px solid #4a4a4a; /* Cinza escuro */
background-color: #E9E9E8;
padding: 1%;
width: 100%;
font-size: 1.5rem; /* Texto maior */
}
.mb-3 .form-control:focus {
background-color: white;
}
h1 {
font-weight: 800;
font-size: 1.6rem;
padding-bottom: 3%;
padding-left: 2%;
}
</style>
<PageTitle>Criar novo Produto</PageTitle>
<h1>Criar novo Produto</h1>
<hr />
<div class="container" style="background-color: #E9E9E8;height : 75vh; padding :2%; text-align:center;">
<EditForm method="post" Model="ProductViewModel" OnValidSubmit="AddProduct" FormName="create" Enhance>
<DataAnnotationsValidator />
<div class="mb-3">
<label for="nome" class="form-label">Nome:</label>
<InputText id="nome" @bind-Value="ProductViewModel.nome" class="form-control" />
<ValidationMessage For="() => ProductViewModel.nome" class="text-danger" />
</div>
<div class="mb-3">
<label for="descricao" class="form-label">Descrição:</label>
<InputText id="descricao" @bind-Value="ProductViewModel.descricao" class="form-control" />
<ValidationMessage For="() => ProductViewModel.descricao" class="text-danger" />
</div>
<div class="mb-3">
<label for="roda" class="form-label">RODA:</label>
<InputSelect id="roda" @bind-Value="ProductViewModel.rodaEscolhida" class="form-control">
<option value="">Selecione...</option>
@foreach (var component in Components.Where(c => c.tipo == "RODA"))
{
<option value="@component.Id">@component.nome</option>
}
</InputSelect>
<ValidationMessage For="() => ProductViewModel.rodaEscolhida" class="text-danger" />
</div>
<!-- pistao -->
<div class="mb-3">
<label for="pistao" class="form-label">PISTÃO:</label>
<InputSelect id="pistao" @bind-Value="ProductViewModel.pistaoEscolhido" class="form-control">
<option value="">Selecione...</option>
@foreach (var component in Components.Where(c => c.tipo == "PISTÃO"))
{
<option value="@component.Id">@component.nome</option>
}
</InputSelect>
<ValidationMessage For="() => ProductViewModel.pistaoEscolhido" class="text-danger" />
</div>
<!-- encosto -->
<div class="mb-3">
<label for="encosto" class="form-label">ENCOSTO:</label>
<InputSelect id="encosto" @bind-Value="ProductViewModel.encostoEscolhido" class="form-control">
<option value="">Selecione...</option>
@foreach (var component in Components.Where(c => c.tipo == "ENCOSTO"))
{
<option value="@component.Id">@component.nome</option>
}
</InputSelect>
<ValidationMessage For="() => ProductViewModel.encostoEscolhido" class="text-danger" />
</div>
<!-- braco direito -->
<div class="mb-3">
<label for="bracodir" class="form-label">BRAÇO DIREITO:</label>
<InputSelect id="bracodir" @bind-Value="ProductViewModel.bracoDirEscolhido" class="form-control">
<option value="">Selecione...</option>
@foreach (var component in Components.Where(c => c.tipo == "BRAÇO_DIREITO"))
{
<option value="@component.Id">@component.nome</option>
}
</InputSelect>
<ValidationMessage For="() => ProductViewModel.bracoDirEscolhido" class="text-danger" />
</div>
<!-- braco esquerdo -->
<div class="mb-3">
<label for="bracoesq" class="form-label">BRAÇO ESQUERDO:</label>
<InputSelect id="bracoesq" @bind-Value="ProductViewModel.bracoEsqEscolhido" class="form-control">
<option value="">Selecione...</option>
@foreach (var component in Components.Where(c => c.tipo == "BRAÇO_ESQUERDO"))
{
<option value="@component.Id">@component.nome</option>
}
</InputSelect>
<ValidationMessage For="() => ProductViewModel.bracoEsqEscolhido" class="text-danger" />
</div>
<!-- almofada -->
<div class="mb-3">
<label for="almofada" class="form-label">ALMOFADA:</label>
<InputSelect id="almofada" @bind-Value="ProductViewModel.almofadaEscolhida" class="form-control">
<option value="">Selecione...</option>
@foreach (var component in Components.Where(c => c.tipo == "ALMOFADA"))
{
<option value="@component.Id">@component.nome</option>
}
</InputSelect>
<ValidationMessage For="() => ProductViewModel.almofadaEscolhida" class="text-danger" />
</div>
<div style="margin-top: 3%;text-align: center; width: 100%;">
<button type="submit" class="btn" style="background-color: black; color: white; width: 35%; height: 25%; font-size: 1.5rem; border-radius: 8px;">
Adicionar Produto
</button>
</div>
</EditForm>
</div>
@code {
[SupplyParameterFromForm]
private ProductCreateViewModel ProductViewModel { get; set; } = new ProductCreateViewModel {
nome = String.Empty,
descricao = String.Empty,
peso = .0f,
custo = .0f,
rodaEscolhida = -1,
pistaoEscolhido = -1,
encostoEscolhido = -1,
bracoDirEscolhido = -1,
bracoEsqEscolhido = -1,
almofadaEscolhida = -1
};
private List<Component> Components { get; set; } = new List<Component>();
protected override async Task OnInitializedAsync()
{
using var context = DbFactory.CreateDbContext();
Components = await context.Component.ToListAsync();
}
private async Task AddProduct()
{
float peso_produto = 0;
float custo_produto = 0;
using var context = DbFactory.CreateDbContext();
var teste = ProductViewModel;
var produto = new Product
{
nome = ProductViewModel.nome,
descricao = ProductViewModel.descricao,
peso = ProductViewModel.peso,
custo = ProductViewModel.custo,
Components = new List<Component>()
};
var componentes = new List<Component>();
if (ProductViewModel.rodaEscolhida != null)
{
var componenteRoda = await context.Component.FindAsync(ProductViewModel.rodaEscolhida);
if (componenteRoda != null)
{
componentes.Add(componenteRoda);
peso_produto += componenteRoda.peso;
custo_produto += componenteRoda.custo;
}
}
if (ProductViewModel.pistaoEscolhido != null)
{
var componentePistao = await context.Component.FindAsync(ProductViewModel.pistaoEscolhido);
if (componentePistao != null)
{
componentes.Add(componentePistao);
peso_produto += componentePistao.peso;
custo_produto += componentePistao.custo;
}
}
if (ProductViewModel.encostoEscolhido != null)
{
var componenteEncosto = await context.Component.FindAsync(ProductViewModel.encostoEscolhido);
if (componenteEncosto != null)
{
componentes.Add(componenteEncosto);
peso_produto += componenteEncosto.peso;
custo_produto += componenteEncosto.custo;
}
}
if (ProductViewModel.bracoDirEscolhido != null)
{
var componenteBracoDir = await context.Component.FindAsync(ProductViewModel.bracoDirEscolhido);
if (componenteBracoDir != null)
{
componentes.Add(componenteBracoDir);
peso_produto += componenteBracoDir.peso;
custo_produto += componenteBracoDir.custo;
}
}
if (ProductViewModel.bracoEsqEscolhido != null)
{
var componenteBracoEsq = await context.Component.FindAsync(ProductViewModel.bracoEsqEscolhido);
if (componenteBracoEsq != null)
{
componentes.Add(componenteBracoEsq);
peso_produto += componenteBracoEsq.peso;
custo_produto += componenteBracoEsq.custo;
}
}
if (ProductViewModel.almofadaEscolhida != null)
{
var componenteAlmofada = await context.Component.FindAsync(ProductViewModel.almofadaEscolhida);
if (componenteAlmofada != null)
{
componentes.Add(componenteAlmofada);
peso_produto += componenteAlmofada.peso;
custo_produto += componenteAlmofada.custo;
}
}
produto.Components = componentes;
produto.peso = peso_produto;
produto.custo = custo_produto;
context.Product.Add(produto);
await context.SaveChangesAsync();
NavigationManager.NavigateTo("/products");
}
}
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
namespace CadeirasLusitanas.Models.Entities
{
public class Product
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Column("Nome")]
public required string nome { get; set; }
[Column("Descrição")]
public required string descricao { get; set; }
[Column("Peso")]
public float peso { get; set; }
[Column("Custo")]
public float custo { get; set; }
[Column("Stock")]
public int stock { get; set; }
public ICollection<Component> Components { get; set; }
}
}
using System.ComponentModel.DataAnnotations;
namespace CadeirasLusitanas.Models.ViewModels
{
public class ProductCreateViewModel
{
[Required(AllowEmptyStrings = false, ErrorMessage = "Por favor insira um nome")]
public string nome { get; set; }
public string descricao { get; set; }
public float peso { get; set; }
public float custo { get; set; }
[Required(ErrorMessage = "Por favor escolha uma roda")]
public int? rodaEscolhida { get; set; }
[Required(ErrorMessage = "Por favor escolha um pistão")]
public int? pistaoEscolhido { get; set; }
[Required(ErrorMessage = "Por favor escolha um encosto")]
public int? encostoEscolhido { get; set; }
[Required(ErrorMessage = "Por favor escolha um braço direito")]
public int? bracoDirEscolhido { get; set; }
[Required(ErrorMessage = "Por favor escolha um braço esquerdo")]
public int? bracoEsqEscolhido { get; set; }
[Required(ErrorMessage = "Por favor escolha uma almofada")]
public int? almofadaEscolhida { get; set; }
}
}