Skip to content

Commit 5ba0e73

Browse files
AndreaCuneocommonsensesoftware
authored andcommitted
fix(ApiExplorer): SubstitutedType have invalid property setter
The PropertySetter of the SubstitutedType have 0 parameters: they had the same signature of the Getter. resolves: #1104
1 parent 371eda4 commit 5ba0e73

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/Common/src/Common.OData.ApiExplorer/OData/DefaultModelTypeBuilder.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,11 @@ private static PropertyBuilder AddProperty(
417417
var field = addTo.DefineField( "_" + name, shouldBeAdded, FieldAttributes.Private );
418418
var propertyBuilder = addTo.DefineProperty( name, PropertyAttributes.HasDefault, shouldBeAdded, null );
419419
var getter = addTo.DefineMethod( "get_" + name, propertyMethodAttributes, shouldBeAdded, Type.EmptyTypes );
420-
var setter = addTo.DefineMethod( "set_" + name, propertyMethodAttributes, shouldBeAdded, Type.EmptyTypes );
420+
421+
/* returnType is 'null' instead of type(void) as per docs
422+
* see: https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.propertybuilder?view=net-9.0
423+
*/
424+
var setter = addTo.DefineMethod( "set_" + name, propertyMethodAttributes, null, [shouldBeAdded] );
421425
var il = getter.GetILGenerator();
422426

423427
il.Emit( OpCodes.Ldarg_0 );

src/Common/test/Common.OData.ApiExplorer.Tests/OData/DefaultModelTypeBuilderTest.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,41 @@ public void substitute_should_resolve_types_that_reference_a_model_that_match_th
409409
substitutionType.Should().NotBeOfType<TypeBuilder>();
410410
}
411411

412+
[Fact]
413+
public void substituted_type_should_have_valid_runtime_properties__issue1104()
414+
{
415+
// arrange
416+
var modelBuilder = new ODataConventionModelBuilder();
417+
418+
var address = modelBuilder.EntitySet<Address>( nameof( Address ) ).EntityType;
419+
address.Ignore( x => x.City ); // force substitution
420+
var addressType = typeof( Address );
421+
422+
var context = NewContext( modelBuilder.GetEdmModel() );
423+
424+
// act
425+
var substitutedType = addressType.SubstituteIfNecessary( context );
426+
427+
// assert
428+
substitutedType.Should().NotBe( addressType );
429+
#if NET452
430+
substitutedType.GetRuntimeProperties().Should().HaveCount( 5 );
431+
foreach ( var substitutedProperty in substitutedType.GetRuntimeProperties() )
432+
{
433+
substitutedProperty.Should().NotBeNull();
434+
substitutedProperty.GetSetMethod( true ).Should().NotBeNull()
435+
.And.Match( p => p.ReturnType == typeof( void ) )
436+
.And.Match( p => p.GetParameters().Length == 1 );
437+
}
438+
#else
439+
substitutedType.GetRuntimeProperties().Should().HaveCount( 5 )
440+
.And.AllSatisfy( prop => prop.GetSetMethod( true ).Should()
441+
.NotBeNull()
442+
.And.ReturnVoid()
443+
.And.Match( setter => setter.GetParameters().Length == 1 ) );
444+
#endif
445+
}
446+
412447
public static IEnumerable<object[]> SubstitutionNotRequiredData
413448
{
414449
get

0 commit comments

Comments
 (0)