Skip to content

Commit 0bbf8da

Browse files
Chris Martinezcommonsensesoftware
authored andcommitted
Address possible NullReferenceException building allowed HTTP methods
1 parent fd6be16 commit 0bbf8da

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/Microsoft.AspNetCore.Mvc.Versioning/Routing/DefaultApiVersionRoutePolicy.cs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using Microsoft.AspNetCore.Http;
44
using Microsoft.AspNetCore.Http.Extensions;
55
using Microsoft.AspNetCore.Mvc.Abstractions;
6-
using Microsoft.AspNetCore.Mvc.ActionConstraints;
76
using Microsoft.AspNetCore.Mvc.Infrastructure;
87
using Microsoft.AspNetCore.Mvc.Internal;
98
using Microsoft.AspNetCore.Routing;
@@ -16,6 +15,7 @@
1615
using Versioning;
1716
using static ApiVersion;
1817
using static System.Environment;
18+
using static System.Linq.Enumerable;
1919
using static System.String;
2020
using static Versioning.ErrorCodes;
2121

@@ -193,10 +193,7 @@ RequestHandler ClientError( RouteContext context, ActionSelectionResult selectio
193193
var requestedVersion = default( string );
194194
var parsedVersion = properties.ApiVersion;
195195
var actionNames = new Lazy<string>( () => Join( NewLine, candidates.Select( a => a.DisplayName ) ) );
196-
var allowedMethods = new Lazy<HashSet<string>>(
197-
() => new HashSet<string>( candidates.SelectMany( c => c.ActionConstraints.OfType<HttpMethodActionConstraint>() )
198-
.SelectMany( ac => ac.HttpMethods ),
199-
StringComparer.OrdinalIgnoreCase ) );
196+
var allowedMethods = new Lazy<HashSet<string>>( () => AllowedMethodsFromCandidates( candidates ) );
200197
var newRequestHandler = default( Func<IErrorResponseProvider, string, string, RequestHandler> );
201198

202199
if ( parsedVersion == null )
@@ -250,6 +247,29 @@ RequestHandler ClientError( RouteContext context, ActionSelectionResult selectio
250247
return newRequestHandler( ErrorResponseProvider, code, message );
251248
}
252249

250+
static HashSet<string> AllowedMethodsFromCandidates( IEnumerable<ActionDescriptor> candidates )
251+
{
252+
Contract.Requires( candidates != null );
253+
Contract.Ensures( Contract.Result<HashSet<string>>() != null );
254+
255+
var httpMethods = new HashSet<string>( StringComparer.OrdinalIgnoreCase );
256+
257+
foreach ( var candidate in candidates )
258+
{
259+
if ( candidate.ActionConstraints == null )
260+
{
261+
continue;
262+
}
263+
264+
foreach ( var constraint in candidate.ActionConstraints.OfType<HttpMethodActionConstraint>() )
265+
{
266+
httpMethods.AddRange( constraint.HttpMethods );
267+
}
268+
}
269+
270+
return httpMethods;
271+
}
272+
253273
sealed class DefaultActionHandler
254274
{
255275
readonly IActionContextAccessor actionContextAccessor;

0 commit comments

Comments
 (0)