dotnet / dotnet/aspnetcore

Make it possible for me to opt out of ThrowIfRecordTypeHasValidationOnProperties or ignore if attribute IS present on params

Open
#41,546 6 comments 8 reactions 0 assignees View on GitHub
area-mvc feature-model-binding
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

### Is your feature request related to a problem? Please describe the problem.

I have a command record like
```
public record UpdateCommand(
[Required]
[StringLength(250, MinimumLength = 100)]
string NewName,
);
```

and i'm loving the short syntax for commands, great feature!

but i happen to want to validate my command outside of MVC so i was using Validator.TryValidateObject ...but it wasn't every returning false indicating validation erorr...well of course not because those attribute end up on the constructor params and NOT the properties.

so i changed it to
```
public record UpdateCommand(
[property: Required]
[property: StringLength(250, MinimumLength = 100)]
string NewName,
);
```

and my Validator call worked! but now my MVC throws because of https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs#L61

which i get, no parameterless constructor and this seems like a good warning to people not expecting this...BUT i want my cake and eat it too.

### Describe the solution you'd like

Option 1: let me opt out

I should be able to tell MVC to not throw in this case, that i totally understand that property attributes won't be used and that i'm ok with that (cause i put my param attributes):

MVCConfig{
DisableErrorAboutRecordPropertiesHavingValidation = yesplease
}

```
public record UpdateCommand(
[param: Required]
[param: StringLength(250, MinimumLength = 100)]
[property: Required]
[property: StringLength(250, MinimumLength = 100)]
string NewName,
);
```

redundant, but still succient

Option 2: have ThrowIfRecordTypeHasValidationOnProperties be smarter. If it sees params on the constructor assume the dev knows what they're doing...or maybe check if the params are a subset or something..though that might be dicey.

Option 3: add a method to Validator to TryValidateObjectWithConstructorParamsLikeMVCDoesItPlease()

### Additional context

the workaround of going to the long form is easy enough

```
public record UpdateCommand
{
public UpdateCommand()
{

}
public UpdateCommand(name) => This.Name = name

public string NewName {get;init;}
}
```

but man that sucks, sucks more with more params, and sucks a LOT that now i can create an UpdateCommand with a default never init'd NewName that'll be null yuck! kinda kills the beauty of records!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.