ValidatableType silent ignore validation for most use cases
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
* Silent ignore validation on visibility issues
* Silent ignore validation on `IValidatableObject` on 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 a `using` that then causes a name conflict for ValidatableType.
### Expected Behavior
Validation is done, or compile error
### Steps To Reproduce
```csharp
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();
///
/// No validation done!
///
[ValidatableType]
private class PrivateModel
{
public TheChild Child { get; } = new();
public class TheChild
{
[Required] public string? Name { get; set; }
}
}
private void ValidSubmit()
{
Console.WriteLine("Failed");
}
}
///
/// No validation done!
///
[ValidatableType]
internal class InternalModel
{
public TheChild Child { get; } = new();
public class TheChild
{
[Required] public string? Name { get; set; }
}
}
///
/// Required error => Works
///
[ValidatableType]
public class PublicModel
{
public TheChild Child { get; } = new();
public class TheChild
{
[Required] public string? Name { get; set; }
}
}
///
/// No validation done!
///
[ValidatableType]
public class PublicWithInternalChildModel
{
internal TheChild Child { get; } = new();
public class TheChild
{
[Required] public string? Name { get; set; }
}
}
///
/// No validation done!
///
[ValidatableType]
public class PublicWithInternalChildPropModel
{
public TheChild Child { get; } = new();
public class TheChild
{
[Required] internal string? Name { get; set; }
}
}
///
/// No validation done!
///
[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 Validate(ValidationContext validationContext) => [new("Custom", [nameof(Name)])];
}
}
///
/// No validation done!
///
[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; }
}
}
///
/// No validation done!
///
[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; }
}
}
///
/// No validation done!
///
[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 Validate(ValidationContext validationContext) => [new("Custom", [nameof(Name)])];
}
}
///
/// Required error => Works
///
[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; }
}
}
///
/// Required error => Works
///
[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; }
}
}
```
```razor
@page "/"
@rendermode InteractiveServer
Home
Leave the value empty and press submit! They should all give a required error!!
PrivateVisibility
Submit
InternalVisibility
Submit
PublicVisibility
Submit
PublicWithInternalChild
Submit
PublicWithInternalChildProp
Submit
ChildWithIValidatableObject
Submit
ChildWithAttribute
Submit
ChildWithDoubleValidatableType
Submit
ChildWithClassWithAttribute
Submit
ChildWithClassWithTrippleAttribute
Submit
ChildWithClassWithAdditionalProp
Submit
```
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
Contributor guide
Assessment
This issue has not been assessed yet.