Skip to content

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

@drdamour

Description

@drdamour

Is there an existing issue for this?

  • 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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-model-binding

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions