Skip to content

Commit 0555113

Browse files
Reorder visitation such that EnableQueryAttribute can override Model Bound Settings. Related to #928
1 parent c9745a6 commit 0555113

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

src/AspNetCore/OData/test/Asp.Versioning.OData.ApiExplorer.Tests/Conventions/ODataValidationSettingsConventionTest.cs

+58
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace Asp.Versioning.Conventions;
1919
using Microsoft.OData.ModelBuilder;
2020
using Microsoft.OData.ModelBuilder.Config;
2121
using System.Reflection;
22+
using Xunit;
2223
using static Microsoft.AspNetCore.Http.StatusCodes;
2324
using static Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource;
2425
using static Microsoft.AspNetCore.OData.Query.AllowedArithmeticOperators;
@@ -469,6 +470,50 @@ public void apply_to_should_use_model_bound_query_attributes()
469470
options => options.ExcludingMissingMembers() );
470471
}
471472

473+
[Fact]
474+
public void apply_should_override_model_bound_settings_with_enable_query_attribute()
475+
{
476+
// arrange
477+
var builder = new ODataConventionModelBuilder().EnableLowerCamelCase();
478+
479+
builder.EntitySet<Customer>( "Customers" );
480+
481+
var validationSettings = new ODataValidationSettings()
482+
{
483+
AllowedQueryOptions = AllowedQueryOptions.None,
484+
AllowedArithmeticOperators = AllowedArithmeticOperators.None,
485+
AllowedLogicalOperators = AllowedLogicalOperators.None,
486+
AllowedFunctions = AllowedFunctions.None,
487+
};
488+
var settings = new TestODataQueryOptionSettings( typeof( Customer ) );
489+
var convention = new ODataValidationSettingsConvention( validationSettings, settings );
490+
var model = builder.GetEdmModel();
491+
var description = NewApiDescription( typeof( CustomersController ), typeof( IEnumerable<Customer> ), model );
492+
493+
// act
494+
convention.ApplyTo( description );
495+
496+
// assert
497+
var parameter = description.ParameterDescriptions.Single();
498+
499+
parameter.Should().BeEquivalentTo(
500+
new
501+
{
502+
Name = "$filter",
503+
Source = Query,
504+
Type = typeof( string ),
505+
DefaultValue = default( object ),
506+
IsRequired = false,
507+
ModelMetadata = new { Description = "Test" },
508+
ParameterDescriptor = new
509+
{
510+
Name = "$filter",
511+
ParameterType = typeof( string ),
512+
},
513+
},
514+
options => options.ExcludingMissingMembers() );
515+
}
516+
472517
[Fact]
473518
public void apply_to_should_process_odataX2Dlike_api_description()
474519
{
@@ -678,6 +723,13 @@ public class OrdersController : ODataController
678723
public IActionResult Get( ODataQueryOptions<Order> options ) => Ok();
679724
}
680725

726+
public class CustomersController : ODataController
727+
{
728+
[EnableQuery( AllowedQueryOptions = Filter )]
729+
[ProducesResponseType( typeof( IEnumerable<Customer> ), Status200OK )]
730+
public IActionResult Get( ODataQueryOptions<Customer> options ) => Ok();
731+
}
732+
681733
[Select]
682734
[Filter]
683735
[Count]
@@ -693,6 +745,12 @@ public class Order
693745
public int Quantity { get; set; }
694746
}
695747

748+
[Page( MaxTop = 25, PageSize = 25 )]
749+
public class Customer
750+
{
751+
public int CustomerId { get; set; }
752+
}
753+
696754
private sealed class TestODataQueryOptionSettings : ODataQueryOptionSettings
697755
{
698756
internal TestODataQueryOptionSettings( Type type, bool dollarPrefix = true ) :

src/Common/src/Common.OData.ApiExplorer/Conventions/ODataAttributeVisitor.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ internal ODataAttributeVisitor(
3838

3939
internal void Visit( ApiDescription apiDescription )
4040
{
41-
VisitAction( apiDescription.ActionDescriptor );
42-
4341
var modelType = context.ReturnType;
4442

4543
if ( modelType != null )
4644
{
4745
VisitModel( modelType );
4846
}
47+
48+
VisitAction( apiDescription.ActionDescriptor );
4949
}
5050

5151
private void VisitModel( IEdmStructuredType modelType )

0 commit comments

Comments
 (0)