diff --git a/src/MicroElements.Swashbuckle.FluentValidation/OpenApi/OpenApiSchemaCompatibility.cs b/src/MicroElements.Swashbuckle.FluentValidation/OpenApi/OpenApiSchemaCompatibility.cs index f2e9932..d3d9f5c 100644 --- a/src/MicroElements.Swashbuckle.FluentValidation/OpenApi/OpenApiSchemaCompatibility.cs +++ b/src/MicroElements.Swashbuckle.FluentValidation/OpenApi/OpenApiSchemaCompatibility.cs @@ -452,7 +452,10 @@ public static IEnumerable> GetProperties(Ope #if OPENAPI_V2 if (schema.Properties == null) return Enumerable.Empty>(); + // Filter out OpenApiSchemaReference entries (e.g., enum types) to avoid InvalidCastException + // Issue #176: https://github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation/issues/176 return schema.Properties + .Where(kvp => kvp.Value is OpenApiSchema) .Select(kvp => new KeyValuePair(kvp.Key, (OpenApiSchema)kvp.Value)); #else return schema.Properties ?? Enumerable.Empty>(); diff --git a/test/MicroElements.Swashbuckle.FluentValidation.Tests/SchemaGenerationTests.EnumProperties.cs b/test/MicroElements.Swashbuckle.FluentValidation.Tests/SchemaGenerationTests.EnumProperties.cs new file mode 100644 index 0000000..a079166 --- /dev/null +++ b/test/MicroElements.Swashbuckle.FluentValidation.Tests/SchemaGenerationTests.EnumProperties.cs @@ -0,0 +1,80 @@ +// Copyright (c) MicroElements. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using FluentAssertions; +using FluentValidation; +#if OPENAPI_V2 +using Microsoft.OpenApi; +#else +using Microsoft.OpenApi.Models; +#endif +using Swashbuckle.AspNetCore.SwaggerGen; +using Xunit; + +namespace MicroElements.Swashbuckle.FluentValidation.Tests +{ + /// + /// Tests for models with enum properties. + /// Issue #176: https://github.com/micro-elements/MicroElements.Swashbuckle.FluentValidation/issues/176 + /// + public partial class SchemaGenerationTests + { + public enum SampleStatus + { + Pending, + Active, + Completed + } + + public class ModelWithEnumProperty + { + public string Name { get; set; } = string.Empty; + public SampleStatus Status { get; set; } + public string Description { get; set; } = string.Empty; + } + + public class ModelWithEnumPropertyValidator : AbstractValidator + { + public ModelWithEnumPropertyValidator() + { + RuleFor(x => x.Name).NotEmpty().MaximumLength(100); + RuleFor(x => x.Description).MaximumLength(500); + } + } + + /// + /// Issue #176: InvalidCastException when models contain enum properties. + /// In OpenAPI v2 (Microsoft.OpenApi 2.x), enum properties are represented as OpenApiSchemaReference, + /// not OpenApiSchema, causing InvalidCastException in GetProperties method. + /// + [Fact] + public void Model_With_Enum_Property_Should_Not_Throw_InvalidCastException() + { + // Arrange + var schemaRepository = new SchemaRepository(); + + // Act - This should not throw InvalidCastException + var referenceSchema = SchemaGenerator(new ModelWithEnumPropertyValidator()) + .GenerateSchema(typeof(ModelWithEnumProperty), schemaRepository); + + // Assert + var schema = schemaRepository.GetSchema(referenceSchema.GetRefId()!); + + // Non-enum properties should have validation rules applied (using PascalCase as in C# property names) + var nameProperty = schema.GetProperty("Name"); + nameProperty.Should().NotBeNull("Name property should exist in schema"); + nameProperty!.MinLength.Should().Be(1); + nameProperty.MaxLength.Should().Be(100); + + var descriptionProperty = schema.GetProperty("Description"); + descriptionProperty.Should().NotBeNull("Description property should exist in schema"); + descriptionProperty!.MaxLength.Should().Be(500); + + // Schema should have all properties (including enum) + schema.Properties.Should().HaveCount(3); + schema.Properties.Keys.Should().Contain("Name"); + schema.Properties.Keys.Should().Contain("Status"); + schema.Properties.Keys.Should().Contain("Description"); + } + } +} diff --git a/version.props b/version.props index 6150d78..64b2916 100644 --- a/version.props +++ b/version.props @@ -1,6 +1,6 @@ - 7.0.1 + 7.0.2