8
8
using System . Reflection ;
9
9
using System . Security . Claims ;
10
10
using System . Text ;
11
+ using System . Text . Json ;
11
12
using Microsoft . AspNetCore . Http . Features ;
12
13
using Microsoft . AspNetCore . Http . Metadata ;
13
14
using Microsoft . Extensions . DependencyInjection ;
@@ -504,7 +505,7 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
504
505
505
506
private static Func < object ? , HttpContext , Task > HandleRequestBodyAndCompileRequestDelegate ( Expression responseWritingMethodCall , FactoryContext factoryContext )
506
507
{
507
- if ( factoryContext . JsonRequestBodyType is null )
508
+ if ( factoryContext . JsonRequestBodyParameter is null )
508
509
{
509
510
if ( factoryContext . ParameterBinders . Count > 0 )
510
511
{
@@ -533,7 +534,12 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
533
534
responseWritingMethodCall , TargetExpr , HttpContextExpr ) . Compile ( ) ;
534
535
}
535
536
536
- var bodyType = factoryContext . JsonRequestBodyType ;
537
+ var bodyType = factoryContext . JsonRequestBodyParameter . ParameterType ;
538
+ var parameterTypeName = TypeNameHelper . GetTypeDisplayName ( factoryContext . JsonRequestBodyParameter . ParameterType , fullName : false ) ;
539
+ var parameterName = factoryContext . JsonRequestBodyParameter . Name ;
540
+
541
+ Debug . Assert ( parameterName is not null , "CreateArgument() should throw if parameter.Name is null." ) ;
542
+
537
543
object ? defaultBodyValue = null ;
538
544
539
545
if ( factoryContext . AllowEmptyRequestBody && bodyType . IsValueType )
@@ -580,10 +586,10 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
580
586
Log . RequestBodyIOException ( httpContext , ex ) ;
581
587
return ;
582
588
}
583
- catch ( InvalidDataException ex )
589
+ catch ( JsonException ex )
584
590
{
585
- Log . RequestBodyInvalidDataException ( httpContext , ex , factoryContext . ThrowOnBadRequest ) ;
586
- httpContext . Response . StatusCode = 400 ;
591
+ Log . InvalidJsonRequestBody ( httpContext , parameterTypeName , parameterName , ex , factoryContext . ThrowOnBadRequest ) ;
592
+ httpContext . Response . StatusCode = StatusCodes . Status400BadRequest ;
587
593
return ;
588
594
}
589
595
}
@@ -618,10 +624,10 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
618
624
Log . RequestBodyIOException ( httpContext , ex ) ;
619
625
return ;
620
626
}
621
- catch ( InvalidDataException ex )
627
+ catch ( JsonException ex )
622
628
{
623
629
624
- Log . RequestBodyInvalidDataException ( httpContext , ex , factoryContext . ThrowOnBadRequest ) ;
630
+ Log . InvalidJsonRequestBody ( httpContext , parameterTypeName , parameterName , ex , factoryContext . ThrowOnBadRequest ) ;
625
631
httpContext . Response . StatusCode = StatusCodes . Status400BadRequest ;
626
632
return ;
627
633
}
@@ -879,11 +885,14 @@ private static Expression BindParameterFromBindAsync(ParameterInfo parameter, Fa
879
885
880
886
private static Expression BindParameterFromBody ( ParameterInfo parameter , bool allowEmpty , FactoryContext factoryContext )
881
887
{
882
- if ( factoryContext . JsonRequestBodyType is not null )
888
+ if ( factoryContext . JsonRequestBodyParameter is not null )
883
889
{
884
890
factoryContext . HasMultipleBodyParameters = true ;
885
891
var parameterName = parameter . Name ;
886
- if ( parameterName is not null && factoryContext . TrackedParameters . ContainsKey ( parameterName ) )
892
+
893
+ Debug . Assert ( parameterName is not null , "CreateArgument() should throw if parameter.Name is null." ) ;
894
+
895
+ if ( factoryContext . TrackedParameters . ContainsKey ( parameterName ) )
887
896
{
888
897
factoryContext . TrackedParameters . Remove ( parameterName ) ;
889
898
factoryContext . TrackedParameters . Add ( parameterName , "UNKNOWN" ) ;
@@ -892,7 +901,7 @@ private static Expression BindParameterFromBody(ParameterInfo parameter, bool al
892
901
893
902
var isOptional = IsOptionalParameter ( parameter , factoryContext ) ;
894
903
895
- factoryContext . JsonRequestBodyType = parameter . ParameterType ;
904
+ factoryContext . JsonRequestBodyParameter = parameter ;
896
905
factoryContext . AllowEmptyRequestBody = allowEmpty || isOptional ;
897
906
factoryContext . Metadata . Add ( new AcceptsMetadata ( parameter . ParameterType , factoryContext . AllowEmptyRequestBody , DefaultAcceptsContentType ) ) ;
898
907
@@ -1164,7 +1173,7 @@ private class FactoryContext
1164
1173
public bool DisableInferredFromBody { get ; init ; }
1165
1174
1166
1175
// Temporary State
1167
- public Type ? JsonRequestBodyType { get ; set ; }
1176
+ public ParameterInfo ? JsonRequestBodyParameter { get ; set ; }
1168
1177
public bool AllowEmptyRequestBody { get ; set ; }
1169
1178
1170
1179
public bool UsingTempSourceString { get ; set ; }
@@ -1197,7 +1206,8 @@ private static class RequestDelegateFactoryConstants
1197
1206
1198
1207
private static partial class Log
1199
1208
{
1200
- private const string RequestBodyInvalidDataExceptionMessage = "Reading the request body failed with an InvalidDataException." ;
1209
+ private const string InvalidJsonRequestBodyMessage = @"Failed to read parameter ""{ParameterType} {ParameterName}"" from the request body as JSON." ;
1210
+ private const string InvalidJsonRequestBodyExceptionMessage = @"Failed to read parameter ""{0} {1}"" from the request body as JSON." ;
1201
1211
1202
1212
private const string ParameterBindingFailedLogMessage = @"Failed to bind parameter ""{ParameterType} {ParameterName}"" from ""{SourceValue}""." ;
1203
1213
private const string ParameterBindingFailedExceptionMessage = @"Failed to bind parameter ""{0} {1}"" from ""{2}""." ;
@@ -1207,6 +1217,7 @@ private static partial class Log
1207
1217
1208
1218
private const string UnexpectedContentTypeLogMessage = @"Expected a supported JSON media type but got ""{ContentType}""." ;
1209
1219
private const string UnexpectedContentTypeExceptionMessage = @"Expected a supported JSON media type but got ""{0}""." ;
1220
+
1210
1221
private const string ImplicitBodyNotProvidedLogMessage = @"Implicit body inferred for parameter ""{ParameterName}"" but no body was provided. Did you mean to use a Service instead?" ;
1211
1222
private const string ImplicitBodyNotProvidedExceptionMessage = @"Implicit body inferred for parameter ""{0}"" but no body was provided. Did you mean to use a Service instead?" ;
1212
1223
@@ -1218,18 +1229,19 @@ public static void RequestBodyIOException(HttpContext httpContext, IOException e
1218
1229
[ LoggerMessage ( 1 , LogLevel . Debug , "Reading the request body failed with an IOException." , EventName = "RequestBodyIOException" ) ]
1219
1230
private static partial void RequestBodyIOException ( ILogger logger , IOException exception ) ;
1220
1231
1221
- public static void RequestBodyInvalidDataException ( HttpContext httpContext , InvalidDataException exception , bool shouldThrow )
1232
+ public static void InvalidJsonRequestBody ( HttpContext httpContext , string parameterTypeName , string parameterName , Exception exception , bool shouldThrow )
1222
1233
{
1223
1234
if ( shouldThrow )
1224
1235
{
1225
- throw new BadHttpRequestException ( RequestBodyInvalidDataExceptionMessage , exception ) ;
1236
+ var message = string . Format ( CultureInfo . InvariantCulture , InvalidJsonRequestBodyExceptionMessage , parameterTypeName , parameterName ) ;
1237
+ throw new BadHttpRequestException ( message , exception ) ;
1226
1238
}
1227
1239
1228
- RequestBodyInvalidDataException ( GetLogger ( httpContext ) , exception ) ;
1240
+ InvalidJsonRequestBody ( GetLogger ( httpContext ) , parameterTypeName , parameterName , exception ) ;
1229
1241
}
1230
1242
1231
- [ LoggerMessage ( 2 , LogLevel . Debug , RequestBodyInvalidDataExceptionMessage , EventName = "RequestBodyInvalidDataException " ) ]
1232
- private static partial void RequestBodyInvalidDataException ( ILogger logger , InvalidDataException exception ) ;
1243
+ [ LoggerMessage ( 2 , LogLevel . Debug , InvalidJsonRequestBodyMessage , EventName = "InvalidJsonRequestBody " ) ]
1244
+ private static partial void InvalidJsonRequestBody ( ILogger logger , string parameterType , string parameterName , Exception exception ) ;
1233
1245
1234
1246
public static void ParameterBindingFailed ( HttpContext httpContext , string parameterTypeName , string parameterName , string sourceValue , bool shouldThrow )
1235
1247
{
@@ -1259,16 +1271,6 @@ public static void RequiredParameterNotProvided(HttpContext httpContext, string
1259
1271
[ LoggerMessage ( 4 , LogLevel . Debug , RequiredParameterNotProvidedLogMessage , EventName = "RequiredParameterNotProvided" ) ]
1260
1272
private static partial void RequiredParameterNotProvided ( ILogger logger , string parameterType , string parameterName , string source ) ;
1261
1273
1262
- public static void UnexpectedContentType ( HttpContext httpContext , string ? contentType , bool shouldThrow )
1263
- {
1264
- if ( shouldThrow )
1265
- {
1266
- var message = string . Format ( CultureInfo . InvariantCulture , UnexpectedContentTypeExceptionMessage , contentType ) ;
1267
- throw new BadHttpRequestException ( message , StatusCodes . Status415UnsupportedMediaType ) ;
1268
- }
1269
-
1270
- UnexpectedContentType ( GetLogger ( httpContext ) , contentType ?? "(none)" ) ;
1271
- }
1272
1274
public static void ImplicitBodyNotProvided ( HttpContext httpContext , string parameterName , bool shouldThrow )
1273
1275
{
1274
1276
if ( shouldThrow )
@@ -1283,8 +1285,16 @@ public static void ImplicitBodyNotProvided(HttpContext httpContext, string param
1283
1285
[ LoggerMessage ( 5 , LogLevel . Debug , ImplicitBodyNotProvidedLogMessage , EventName = "ImplicitBodyNotProvided" ) ]
1284
1286
private static partial void ImplicitBodyNotProvided ( ILogger logger , string parameterName ) ;
1285
1287
1286
- public static void UnexpectedContentType ( HttpContext httpContext , string ? contentType )
1287
- => UnexpectedContentType ( GetLogger ( httpContext ) , contentType ?? "(none)" ) ;
1288
+ public static void UnexpectedContentType ( HttpContext httpContext , string ? contentType , bool shouldThrow )
1289
+ {
1290
+ if ( shouldThrow )
1291
+ {
1292
+ var message = string . Format ( CultureInfo . InvariantCulture , UnexpectedContentTypeExceptionMessage , contentType ) ;
1293
+ throw new BadHttpRequestException ( message , StatusCodes . Status415UnsupportedMediaType ) ;
1294
+ }
1295
+
1296
+ UnexpectedContentType ( GetLogger ( httpContext ) , contentType ?? "(none)" ) ;
1297
+ }
1288
1298
1289
1299
[ LoggerMessage ( 6 , LogLevel . Debug , UnexpectedContentTypeLogMessage , EventName = "UnexpectedContentType" ) ]
1290
1300
private static partial void UnexpectedContentType ( ILogger logger , string contentType ) ;
0 commit comments