1
- using FluentValidation ;
1
+ using FluentValidation ;
2
2
using FluentValidation . Results ;
3
+
3
4
using Microsoft . AspNetCore . Http ;
4
5
using Microsoft . AspNetCore . Mvc ;
5
6
using Microsoft . Extensions . Configuration ;
6
7
using Microsoft . Extensions . DependencyInjection ;
7
8
using Microsoft . Extensions . DependencyInjection . Extensions ;
8
9
using Microsoft . Extensions . Options ;
10
+
9
11
using Rocket . Surgery . Conventions ;
10
12
using Rocket . Surgery . Conventions . DependencyInjection ;
11
13
using Rocket . Surgery . LaunchPad . AspNetCore . Validation ;
@@ -21,7 +23,7 @@ namespace Rocket.Surgery.LaunchPad.AspNetCore.Conventions;
21
23
/// <seealso cref="IServiceConvention" />
22
24
[ PublicAPI ]
23
25
[ ExportConvention ]
24
- [ AfterConvention ( typeof ( AspNetCoreConvention ) ) ]
26
+ [ AfterConvention < AspNetCoreConvention > ]
25
27
[ ConventionCategory ( ConventionCategory . Application ) ]
26
28
public class ProblemDetailsConvention : IServiceConvention
27
29
{
@@ -33,14 +35,14 @@ public void Register(IConventionContext context, IConfiguration configuration, I
33
35
options =>
34
36
{
35
37
var old = options . StatusCodeSelector ;
36
- options . StatusCodeSelector = ( exception ) => exception switch
37
- {
38
- NotFoundException => StatusCodes . Status404NotFound ,
39
- RequestFailedException => StatusCodes . Status400BadRequest ,
40
- NotAuthorizedException => StatusCodes . Status403Forbidden ,
41
- ValidationException => StatusCodes . Status422UnprocessableEntity ,
42
- _ => old ? . Invoke ( exception ) ?? StatusCodes . Status500InternalServerError ,
43
- } ;
38
+ options . StatusCodeSelector = exception => exception switch
39
+ {
40
+ NotFoundException => StatusCodes . Status404NotFound ,
41
+ RequestFailedException => StatusCodes . Status400BadRequest ,
42
+ NotAuthorizedException => StatusCodes . Status403Forbidden ,
43
+ ValidationException => StatusCodes . Status422UnprocessableEntity ,
44
+ _ => old ? . Invoke ( exception ) ?? StatusCodes . Status500InternalServerError ,
45
+ } ;
44
46
}
45
47
) ;
46
48
services . TryAddEnumerable ( ServiceDescriptor . Singleton < IProblemDetailsWriter , OnBeforeWriteProblemDetailsWriter > ( ) ) ;
@@ -53,28 +55,33 @@ public void Register(IConventionContext context, IConfiguration configuration, I
53
55
}
54
56
}
55
57
56
- class OnBeforeWriteProblemDetailsWriter ( IOptions < ApiBehaviorOptions > apiBehaviorOptions ) : IProblemDetailsWriter
58
+ internal class OnBeforeWriteProblemDetailsWriter ( IOptions < ApiBehaviorOptions > apiBehaviorOptions ) : IProblemDetailsWriter
57
59
{
58
60
public ValueTask WriteAsync ( ProblemDetailsContext context ) => throw new NotImplementedException ( ) ;
59
61
60
62
public bool CanWrite ( ProblemDetailsContext context )
61
63
{
62
64
if ( ! context . ProblemDetails . Status . HasValue
63
65
|| ! apiBehaviorOptions . Value . ClientErrorMapping . TryGetValue ( context . ProblemDetails . Status . Value , out var clientErrorData ) )
66
+ {
64
67
return false ;
68
+ }
65
69
66
70
context . ProblemDetails . Title ??= clientErrorData . Title ;
67
71
context . ProblemDetails . Type ??= clientErrorData . Link ;
68
72
return false ;
69
73
}
70
74
}
71
75
72
- class FluentValidationProblemDetailsWriter ( IOptions < ApiBehaviorOptions > apiBehaviorOptions ) : IProblemDetailsWriter
76
+ internal class FluentValidationProblemDetailsWriter ( IOptions < ApiBehaviorOptions > apiBehaviorOptions ) : IProblemDetailsWriter
73
77
{
74
78
public ValueTask WriteAsync ( ProblemDetailsContext context )
75
79
{
76
80
if ( context is not { Exception : IProblemDetailsData details }
77
- || context . HttpContext . Items [ typeof ( ValidationResult ) ] is not ValidationResult validationResult ) return ValueTask . CompletedTask ;
81
+ || context . HttpContext . Items [ typeof ( ValidationResult ) ] is not ValidationResult validationResult )
82
+ {
83
+ return ValueTask . CompletedTask ;
84
+ }
78
85
79
86
context . ProblemDetails = new FluentValidationProblemDetails ( validationResult . Errors )
80
87
{
@@ -88,13 +95,10 @@ public ValueTask WriteAsync(ProblemDetailsContext context)
88
95
return ValueTask . CompletedTask ;
89
96
}
90
97
91
- public bool CanWrite ( ProblemDetailsContext context )
92
- {
93
- return context . Exception is not IProblemDetailsData && context . HttpContext . Items [ typeof ( ValidationResult ) ] is ValidationResult ;
94
- }
98
+ public bool CanWrite ( ProblemDetailsContext context ) => context . Exception is not IProblemDetailsData && context . HttpContext . Items [ typeof ( ValidationResult ) ] is ValidationResult ;
95
99
}
96
100
97
- class ValidationExceptionProblemDetailsWriter ( IOptions < ApiBehaviorOptions > apiBehaviorOptions ) : IProblemDetailsWriter
101
+ internal class ValidationExceptionProblemDetailsWriter ( IOptions < ApiBehaviorOptions > apiBehaviorOptions ) : IProblemDetailsWriter
98
102
{
99
103
public ValueTask WriteAsync ( ProblemDetailsContext context )
100
104
{
0 commit comments