Skip to content

Validation source code generation not working for annotated field #4184

Closed
@nickrandolph

Description

@nickrandolph

Describe the bug

If you annotate a field with ObservableProperty along with validation attributes, the generated source code for the ValidateAllProperties method doesn't include all the properties.

Steps to Reproduce

Create a class that inherits from ObservableValidator and has at least one field that has the ObservableProperty and validation attributes, eg:

public partial class MainViewModel : ObservableValidator
{
    [Required()]
    [MinLength(2,
        ErrorMessageResourceType = typeof(ErrorResolver),
        ErrorMessageResourceName = nameof(ErrorResolver.CustomMinLength))]
    [MaxLength(100)]
    [Display(Name = "FirstName", ResourceType = typeof(DisplayResolver))]
    [ObservableProperty]
    private string first = "Bob";

    [Display(Name = nameof(DisplayResolver.LastName), ResourceType = typeof(DisplayResolver))]
    [Required(
        ErrorMessageResourceType = typeof(ErrorResolver),
        ErrorMessageResourceName = nameof(ErrorResolver.CustomRequired))]
    [MinLength(2,
        ErrorMessageResourceType = typeof(ErrorResourceResolver),
        ErrorMessageResourceName = nameof(ErrorResourceResolver.MinLengthError))]
    [MaxLength(100)]
    [NoSpecialCharacters]
    [CustomValidation(typeof(MainViewModel), nameof(StartsWithUppercaseValidation))]
    [ObservableProperty]
    private string last = "Jones";

    public static ValidationResult StartsWithUppercaseValidation(object value, ValidationContext context)
    {
        var text = value + "";
        var isValid = string.IsNullOrWhiteSpace(text) ? false : char.IsUpper(text.First());
        return isValid ? ValidationResult.Success : new ValidationResult(null);
    }
}

Compile code and look at the generated code in the __ObservableValidatorExtensions class.
Generated code looks like:

internal static partial class __ObservableValidatorExtensions
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    [global::System.Obsolete("This method is not intended to be called directly by user code")]
    public static global::System.Action<object> CreateAllPropertiesValidator(global::WinUIControl.MainViewModel _)
    {
        static void ValidateAllProperties(object obj)
        {
            var instance = (global::WinUIControl.MainViewModel)obj;
        }

        return ValidateAllProperties;
    }
}

Expected behavior

Generated code should look similar to:

internal static partial class __ObservableValidatorExtensions
{
    [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
    [global::System.Obsolete("This method is not intended to be called directly by user code")]
    public static global::System.Action<object> CreateAllPropertiesValidator(global::WinUIControl.MainViewModel _)
    {
        static void ValidateAllProperties(object obj)
        {
            var instance = (global::WinUIControl.MainViewModel)obj;
            __ObservableValidatorHelper.ValidateProperty(instance, instance.First, nameof(instance.First));
            __ObservableValidatorHelper.ValidateProperty(instance, instance.Last, nameof(instance.Last));
        }

        return ValidateAllProperties;
    }
}

Screenshots

N/A

Environment

N/A

NuGet Package(s):
Microsoft.Toolkit.Mvvm v7.1.0-preview1

Package Version(s):

Windows 10 Build Number:

  • Fall Creators Update (16299)
  • April 2018 Update (17134)
  • October 2018 Update (17763)
  • May 2019 Update (18362)
  • May 2020 Update (19041)
  • Insider Build ({build_number})
  • Windows 11

App min and target version:

  • Fall Creators Update (16299)
  • April 2018 Update (17134)
  • [ X ] October 2018 Update (17763)
  • May 2019 Update (18362)
  • May 2020 Update (19041)
  • Insider Build ({build_number})

Device form factor:

  • Desktop
  • Xbox
  • Surface Hub
  • IoT

Visual Studio version:

  • 2017 (15.{minor_version})
  • 2019 (16.{minor_version})
  • 2022 (17.{minor_version})

Additional context

N/A

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions