Repository: dotnet/aspnetcore
File: src/Validation/gen/Parsers/ValidationsGenerator.TypesParser.cs (C#)

Code before:

            if (primaryConstructor != null)
            {
                // Process all parameters in constructor order to maintain parameter ordering
                foreach (var parameter in primaryConstructor.Parameters)
                {
                    // Find the corresponding property in this type, we ignore
                    // base types here since that will be handled by the inheritance
                    // checks in the default ValidatableTypeInfo implementation.
                    var correspondingProperty = typeSymbol.GetMembers()
                        .OfType<IPropertySymbol>()
                        .FirstOrDefault(p => string.Equals(p.Name, parameter.Name, System.StringComparison.OrdinalIgnoreCase));

                    if (correspondingProperty != null)
                    {
                        resolvedRecordProperty.Add(correspondingProperty);

                        // Skip parameters that are injected as services
                        if (parameter.IsServiceParameter(fromServiceMetadataSymbol, fromKeyedServiceAttributeSymbol))
                        {
                            continue;
                        }

                        // Skip properties that are not accessible from generated code
                        if (correspondingProperty.DeclaredAccessibility is not Accessibility.Public)
                        {
                            continue;
                        }

                        // Check if the property's type is validatable, this resolves
                        // validatable types in the inheritance hierarchy
                        var hasValidatableType = TryExtractValidatableType(
                            correspondingProperty.Type,
                            wellKnownTypes,
                            ref validatableTypes,
                            ref visitedTypes);

                        members.Add(new ValidatableProperty(
                            ContainingType: correspondingProperty.ContainingType,
                            Type: correspondingProperty.Type,
                            Name: correspondingProperty.Name,
                            DisplayName: parameter.GetDisplayName(wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_ComponentModel_DataAnnotations_DisplayAttribute)) ??
                                        correspondingProperty.GetDisplayName(wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_ComponentModel_DataAnnotations_DisplayAttribute)),
                            Attributes: []));
                    }
                }
            }
        }

        // Handle properties for classes and any properties not handled by the constructor
        foreach (var member in typeSymbol.GetMembers().OfType<IPropertySymbol>())

Review comment (suggestion):
Consider adding a comment explaining why non-public properties are skipped, similar to the type-level check, to maintain consistency in documentation.
```suggestion
                        // Skip properties that are not accessible from generated code
                        // Only public properties can be accessed by generated code, so non-public properties are skipped.
```

Code after:
                .FirstOrDefault(c => c.Parameters.Length > 0 && c.Parameters.All(p =>
                    namedType.FindPropertyIncludingBaseTypes(p.Name) != null));

            if (primaryConstructor != null)
            {
                // Process all parameters in constructor order to maintain parameter ordering
                foreach (var parameter in primaryConstructor.Parameters)
                {
                    // Find the corresponding property in this type, we ignore
                    // base types here since that will be handled by the inheritance
                    // checks in the default ValidatableTypeInfo implementation.
                    var correspondingProperty = typeSymbol.GetMembers()
                        .OfType<IPropertySymbol>()
                        .FirstOrDefault(p => string.Equals(p.Name, parameter.Name, System.StringComparison.OrdinalIgnoreCase));

                    if (correspondingProperty != null)
                    {
                        resolvedRecordProperty.Add(correspondingProperty);

                        // Skip parameters that are injected as services
                        if (parameter.IsServiceParameter(fromServiceMetadataSymbol, fromKeyedServiceAttributeSymbol))
                        {
                            continue;
                        }

                        // Skip properties that are not accessible from generated code
                        if (correspondingProperty.DeclaredAccessibility is not Accessibility.Public)
                        {
                            continue;
                        }

                        // Skip properties that have JsonIgnore attribute
                        if (correspondingProperty.IsJsonIgnoredProperty(jsonIgnoreAttributeSymbol))
                        {
                            continue;
                        }

                        // Check if the property's type is validatable, this resolves
                        // validatable types in the inheritance hierarchy
                        var hasValidatableType = TryExtractValidatableType(
                            correspondingProperty.Type,
                            wellKnownTypes,
                            ref validatableTypes,
                            ref visitedTypes);

                        members.Add(new ValidatableProperty(
                            ContainingType: correspondingProperty.ContainingType,
                            Type: correspondingProperty.Type,
                            Name: correspondingProperty.Name,
                            DisplayName: parameter.GetDisplayName(wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_ComponentModel_DataAnnotations_DisplayAttribute)) ??
                                        correspondingProperty.GetDisplayName(wellKnownTypes.Get(WellKnownTypeData.WellKnownType.System_ComponentModel_DataAnnotations_DisplayAttribute)),