Skip to content

Commit 32c3700

Browse files
Chris Martinezcommonsensesoftware
authored andcommitted
Respect [ApiExplorerSettings(IgnoreApi = false)]. Fixes #405.
1 parent b851fe2 commit 32c3700

File tree

5 files changed

+136
-12
lines changed

5 files changed

+136
-12
lines changed

src/Microsoft.AspNetCore.OData.Versioning.ApiExplorer/AspNetCore.Mvc.ApiExplorer/ODataApiDescriptionProvider.cs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,9 @@ public virtual void OnProvidersExecuted( ApiDescriptionProviderContext context )
153153

154154
foreach ( var action in context.Actions.OfType<ControllerActionDescriptor>() )
155155
{
156-
if ( !action.ControllerTypeInfo.IsODataController() || action.ControllerTypeInfo.IsMetadataController() )
157-
{
158-
continue;
159-
}
160-
161-
var controller = action.GetProperty<ControllerModel>();
162-
var apiExplorer = controller?.ApiExplorer;
163-
var visible = ignoreApiExplorerSettings || ( apiExplorer?.IsVisible ?? true );
164-
165-
if ( !visible )
156+
if ( !action.ControllerTypeInfo.IsODataController() ||
157+
action.ControllerTypeInfo.IsMetadataController() ||
158+
!IsVisible( action ) )
166159
{
167160
continue;
168161
}
@@ -226,6 +219,27 @@ public virtual void OnProvidersExecuted( ApiDescriptionProviderContext context )
226219
/// <remarks>The default implementation performs no operation.</remarks>
227220
public virtual void OnProvidersExecuting( ApiDescriptionProviderContext context ) { }
228221

222+
/// <summary>
223+
/// Returns a value indicating whether the specified action is visible to the API Explorer.
224+
/// </summary>
225+
/// <param name="action">The <see cref="ActionDescriptor">action</see> to evaluate.</param>
226+
/// <returns>True if the <paramref name="action"/> is visible; otherwise, false.</returns>
227+
protected bool IsVisible( ActionDescriptor action )
228+
{
229+
Arg.NotNull( action, nameof( action ) );
230+
231+
var ignoreApiExplorerSettings = !Options.UseApiExplorerSettings;
232+
233+
if ( ignoreApiExplorerSettings )
234+
{
235+
return true;
236+
}
237+
238+
return action.GetProperty<ApiExplorerModel>()?.IsODataVisible() ??
239+
action.GetProperty<ControllerModel>()?.ApiExplorer?.IsODataVisible() ??
240+
false;
241+
}
242+
229243
/// <summary>
230244
/// Populates the API version parameters for the specified API description.
231245
/// </summary>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace Microsoft.AspNetCore.Mvc.ApplicationModels
2+
{
3+
using System;
4+
5+
/// <summary>
6+
/// Provides extension methods for the <see cref="ApiExplorerModel"/> class.
7+
/// </summary>
8+
[CLSCompliant( false )]
9+
public static class ApiExplorerModelExtensions
10+
{
11+
/// <summary>
12+
/// Returns a value indicating whether the specified model is visible to OData.
13+
/// </summary>
14+
/// <param name="model">The <see cref="ApiExplorerModel">model</see> to evaluate.</param>
15+
/// <returns>True if the associated controller or action is visible to OData; otherwise, false.</returns>
16+
public static bool? IsODataVisible( this ApiExplorerModel model )
17+
{
18+
Arg.NotNull( model, nameof( model ) );
19+
return model is ODataApiExplorerModel odataModel ? odataModel.IsODataVisible : model.IsVisible;
20+
}
21+
}
22+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
namespace Microsoft.AspNetCore.Mvc.ApplicationModels
2+
{
3+
using System;
4+
5+
/// <summary>
6+
/// Represents a model for the API Explorer for an OData controller or action.
7+
/// </summary>
8+
[CLSCompliant( false )]
9+
public class ODataApiExplorerModel : ApiExplorerModel
10+
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="ODataApiExplorerModel"/> class.
13+
/// </summary>
14+
public ODataApiExplorerModel() { }
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="ODataApiExplorerModel"/> class.
18+
/// </summary>
19+
/// <param name="other">The other <see cref="ApiExplorerModel">model</see> to copy from.</param>
20+
public ODataApiExplorerModel( ApiExplorerModel other ) : base( other )
21+
{
22+
Arg.NotNull( other, nameof( other ) );
23+
24+
IsVisible = null;
25+
IsODataVisible = other.IsVisible;
26+
}
27+
28+
/// <summary>
29+
/// Initializes a new instance of the <see cref="ODataApiExplorerModel"/> class.
30+
/// </summary>
31+
/// <param name="other">The other <see cref="ODataApiExplorerModel">model</see> to copy from.</param>
32+
public ODataApiExplorerModel( ODataApiExplorerModel other ) : base( other )
33+
{
34+
Arg.NotNull( other, nameof( other ) );
35+
36+
IsVisible = null;
37+
IsODataVisible = other.IsODataVisible;
38+
}
39+
40+
/// <summary>
41+
/// Gets or sets a value indicating whether the OData controller or action will be visible in the API Explorer.
42+
/// </summary>
43+
/// <value>True if the OData controller or action will be visible in the API Explorer; otherwise, false.</value>
44+
public bool? IsODataVisible { get; set; }
45+
}
46+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace Microsoft.AspNetCore.Mvc.Versioning
2+
{
3+
using Microsoft.AspNet.OData;
4+
using Microsoft.AspNetCore.Mvc.ApplicationModels;
5+
6+
sealed class ApiExplorerModelConvention : IApplicationModelConvention
7+
{
8+
public void Apply( ApplicationModel application )
9+
{
10+
foreach ( var controller in application.Controllers )
11+
{
12+
if ( !controller.ControllerType.IsODataController() )
13+
{
14+
continue;
15+
}
16+
17+
if ( controller.ApiExplorer != null )
18+
{
19+
controller.ApiExplorer = new ODataApiExplorerModel( controller.ApiExplorer );
20+
}
21+
22+
foreach ( var action in controller.Actions )
23+
{
24+
if ( action.ApiExplorer != null )
25+
{
26+
action.ApiExplorer = new ODataApiExplorerModel( action.ApiExplorer );
27+
action.SetProperty( action.ApiExplorer );
28+
}
29+
}
30+
}
31+
}
32+
}
33+
}

src/Microsoft.AspNetCore.OData.Versioning/AspNetCore.Mvc/Versioning/ODataApplicationModelProvider.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,17 @@ sealed class ODataApplicationModelProvider : IApplicationModelProvider
1616

1717
public void OnProvidersExecuted( ApplicationModelProviderContext context )
1818
{
19-
var convention = new MetadataControllerConvention( Options );
20-
convention.Apply( context.Result );
19+
var application = context.Result;
20+
var conventions = new IApplicationModelConvention[]
21+
{
22+
new MetadataControllerConvention( Options ),
23+
new ApiExplorerModelConvention(),
24+
};
25+
26+
for ( var i = 0; i < conventions.Length; i++ )
27+
{
28+
conventions[i].Apply( application );
29+
}
2130
}
2231

2332
public void OnProvidersExecuting( ApplicationModelProviderContext context ) { }

0 commit comments

Comments
 (0)