-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Open
Labels
area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesIncludes: MVC, Actions and Controllers, Localization, CORS, most templates
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
- Silent ignore validation on visibility issues
- Silent ignore validation on
IValidatableObjecton interfaces - Silent ignore validation on Validation Attributes on interface properties
- Silent ignore validation on types used via Interfaces with no Validation Attributes properties
- Mess with ValidatableType in .Embedded and adding
[SkipValidation]which adds ausingthat then causes a name conflict for ValidatableType.
Expected Behavior
Validation is done, or compile error
Steps To Reproduce
using System.ComponentModel.DataAnnotations;
namespace BlazorApp22.Components.Pages;
/*
//uncomment for compile error
using Microsoft.Extensions.Validation;
[ValidatableType]
public class CompileError
{
[SkipValidation] public TheChild Child { get; } = new();
public class TheChild
{
[Required]
public string? Name { get; set; }
}
}
*/
public partial class Home
{
private PrivateModel PrivateVisibility { get; } = new();
private InternalModel InternalVisibility { get; } = new();
private PublicModel PublicVisibility { get; } = new();
private PublicWithInternalChildModel PublicWithInternalChild { get; } = new();
private PublicWithInternalChildPropModel PublicWithInternalChildProp { get; } = new();
private ChildWithIValidatableObject ChildWithIValidatableObject { get; } = new();
private ChildWithAttribute ChildWithAttribute { get; } = new();
private ChildWithDoubleValidatableType ChildWithDoubleValidatableType { get; } = new();
private ChildWithClassWithAttribute ChildWithClassWithAttribute { get; } = new();
private ChildWithClassWithTrippleAttribute ChildWithClassWithTrippleAttribute { get; } = new();
private ChildWithClassWithAdditionalProp ChildWithClassWithAdditionalProp { get; } = new();
/// <summary>
/// No validation done!
/// </summary>
[ValidatableType]
private class PrivateModel
{
public TheChild Child { get; } = new();
public class TheChild
{
[Required] public string? Name { get; set; }
}
}
private void ValidSubmit()
{
Console.WriteLine("Failed");
}
}
/// <summary>
/// No validation done!
/// </summary>
[ValidatableType]
internal class InternalModel
{
public TheChild Child { get; } = new();
public class TheChild
{
[Required] public string? Name { get; set; }
}
}
/// <summary>
/// Required error => Works
/// </summary>
[ValidatableType]
public class PublicModel
{
public TheChild Child { get; } = new();
public class TheChild
{
[Required] public string? Name { get; set; }
}
}
/// <summary>
/// No validation done!
/// </summary>
[ValidatableType]
public class PublicWithInternalChildModel
{
internal TheChild Child { get; } = new();
public class TheChild
{
[Required] public string? Name { get; set; }
}
}
/// <summary>
/// No validation done!
/// </summary>
[ValidatableType]
public class PublicWithInternalChildPropModel
{
public TheChild Child { get; } = new();
public class TheChild
{
[Required] internal string? Name { get; set; }
}
}
/// <summary>
/// No validation done!
/// </summary>
[ValidatableType]
public class ChildWithIValidatableObject
{
public IChild Child { get; } = new TheChild();
public interface IChild : IValidatableObject
{
public string? Name { get; set; }
}
public class TheChild : IChild
{
public string? Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) => [new("Custom", [nameof(Name)])];
}
}
/// <summary>
/// No validation done!
/// </summary>
[ValidatableType]
public class ChildWithAttribute
{
public IChild Child { get; } = new TheChild();
public interface IChild
{
[Required] public string? Name { get; set; }
}
public class TheChild : IChild
{
public string? Name { get; set; }
}
}
/// <summary>
/// No validation done!
/// </summary>
[ValidatableType]
public class ChildWithDoubleValidatableType
{
public IChild Child { get; } = new TheChild();
public interface IChild
{
[Required] public string? Name { get; set; }
}
[ValidatableType]
public class TheChild : IChild
{
public string? Name { get; set; }
}
}
/// <summary>
/// No validation done!
/// </summary>
[ValidatableType]
public class ChildWithClassWithAttribute
{
public IChild Child { get; } = new TheChild();
public interface IChild
{
public string? Name { get; set; }
}
[ValidatableType]
public class TheChild : IChild, IValidatableObject
{
[Required] public string? Name { get; set; }
[Required] public string? Name2 { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) => [new("Custom", [nameof(Name)])];
}
}
/// <summary>
/// Required error => Works
/// </summary>
[ValidatableType]
public class ChildWithClassWithTrippleAttribute
{
public IChild Child { get; } = new TheChild();
public interface IChild
{
[Required] public string? Name { get; set; }
}
[ValidatableType]
public class TheChild : IChild
{
[Required] public string? Name { get; set; }
}
}
/// <summary>
/// Required error => Works
/// </summary>
[ValidatableType]
public class ChildWithClassWithAdditionalProp
{
public IChild Child { get; } = new TheChild();
public interface IChild
{
[Required] public bool Dummy { get; }
public string? Name { get; set; }
}
[ValidatableType]
public class TheChild : IChild
{
public bool Dummy => true;
[Required] public string? Name { get; set; }
}
}@page "/"
@rendermode InteractiveServer
<PageTitle>Home</PageTitle>
Leave the value empty and press submit! They should all give a required error!!
<EditForm Model="PrivateVisibility" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator/>
<label>
PrivateVisibility
<InputText @bind-Value="@PrivateVisibility.Child.Name"/>
</label>
<ValidationMessage For="() => PrivateVisibility.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="InternalVisibility" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
InternalVisibility
<InputText @bind-Value="@InternalVisibility.Child.Name" />
</label>
<ValidationMessage For="() => InternalVisibility.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="PublicVisibility" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
PublicVisibility
<InputText @bind-Value="@PublicVisibility.Child.Name" />
</label>
<ValidationMessage For="() => PublicVisibility.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="PublicWithInternalChild" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
PublicWithInternalChild
<InputText @bind-Value="@PublicWithInternalChild.Child.Name" />
</label>
<ValidationMessage For="() => PublicWithInternalChild.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="PublicWithInternalChildProp" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
PublicWithInternalChildProp
<InputText @bind-Value="@PublicWithInternalChildProp.Child.Name" />
</label>
<ValidationMessage For="() => PublicWithInternalChildProp.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="ChildWithIValidatableObject" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
ChildWithIValidatableObject
<InputText @bind-Value="@ChildWithIValidatableObject.Child.Name" />
</label>
<ValidationMessage For="() => ChildWithIValidatableObject.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="ChildWithAttribute" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
ChildWithAttribute
<InputText @bind-Value="@ChildWithAttribute.Child.Name" />
</label>
<ValidationMessage For="() => ChildWithAttribute.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="ChildWithDoubleValidatableType" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
ChildWithDoubleValidatableType
<InputText @bind-Value="@ChildWithDoubleValidatableType.Child.Name" />
</label>
<ValidationMessage For="() => ChildWithDoubleValidatableType.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="ChildWithClassWithAttribute" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
ChildWithClassWithAttribute
<InputText @bind-Value="@ChildWithClassWithAttribute.Child.Name" />
</label>
<ValidationMessage For="() => ChildWithClassWithAttribute.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="ChildWithClassWithTrippleAttribute" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<label>
ChildWithClassWithTrippleAttribute
<InputText @bind-Value="@ChildWithClassWithTrippleAttribute.Child.Name" />
</label>
<ValidationMessage For="() => ChildWithClassWithTrippleAttribute.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
<EditForm Model="ChildWithClassWithAdditionalProp" OnValidSubmit="ValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary/>
<label>
ChildWithClassWithAdditionalProp
<InputText @bind-Value="@ChildWithClassWithAdditionalProp.Child.Name" />
</label>
<ValidationMessage For="() => ChildWithClassWithAdditionalProp.Child.Name"></ValidationMessage>
<button type="submit">Submit</button>
</EditForm>
and ofcrouse builder.Services.AddValidation(); in program.cs
Exceptions (if any)
No response
.NET Version
10.0.100
Anything else?
Visual Studio 2026 Developer PowerShell v18.3.0-insiders
Metadata
Metadata
Assignees
Labels
area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesIncludes: MVC, Actions and Controllers, Localization, CORS, most templates