@@ -203,48 +203,20 @@ private static Expression CreateArgument(ParameterInfo parameter, FactoryContext
203
203
}
204
204
else if ( parameterCustomAttributes . OfType < IFromBodyMetadata > ( ) . FirstOrDefault ( ) is { } bodyAttribute )
205
205
{
206
- if ( factoryContext . RequestBodyMode is RequestBodyMode . AsJson )
206
+ if ( factoryContext . JsonRequestBodyType is not null )
207
207
{
208
208
throw new InvalidOperationException ( "Action cannot have more than one FromBody attribute." ) ;
209
209
}
210
210
211
- if ( factoryContext . RequestBodyMode is RequestBodyMode . AsForm )
212
- {
213
- ThrowCannotReadBodyDirectlyAndAsForm ( ) ;
214
- }
215
-
216
- factoryContext . RequestBodyMode = RequestBodyMode . AsJson ;
217
211
factoryContext . JsonRequestBodyType = parameter . ParameterType ;
218
212
factoryContext . AllowEmptyRequestBody = bodyAttribute . AllowEmpty ;
219
213
220
214
return Expression . Convert ( BodyValueExpr , parameter . ParameterType ) ;
221
215
}
222
- else if ( parameterCustomAttributes . OfType < IFromFormMetadata > ( ) . FirstOrDefault ( ) is { } formAttribute )
223
- {
224
- if ( factoryContext . RequestBodyMode is RequestBodyMode . AsJson )
225
- {
226
- ThrowCannotReadBodyDirectlyAndAsForm ( ) ;
227
- }
228
-
229
- factoryContext . RequestBodyMode = RequestBodyMode . AsForm ;
230
-
231
- return BindParameterFromProperty ( parameter , FormExpr , formAttribute . Name ?? parameter . Name , factoryContext ) ;
232
- }
233
216
else if ( parameter . CustomAttributes . Any ( a => typeof ( IFromServiceMetadata ) . IsAssignableFrom ( a . AttributeType ) ) )
234
217
{
235
218
return Expression . Call ( GetRequiredServiceMethod . MakeGenericMethod ( parameter . ParameterType ) , RequestServicesExpr ) ;
236
219
}
237
- else if ( parameter . ParameterType == typeof ( IFormCollection ) )
238
- {
239
- if ( factoryContext . RequestBodyMode is RequestBodyMode . AsJson )
240
- {
241
- ThrowCannotReadBodyDirectlyAndAsForm ( ) ;
242
- }
243
-
244
- factoryContext . RequestBodyMode = RequestBodyMode . AsForm ;
245
-
246
- return Expression . Property ( HttpRequestExpr , nameof ( HttpRequest . Form ) ) ;
247
- }
248
220
else if ( parameter . ParameterType == typeof ( HttpContext ) )
249
221
{
250
222
return HttpContextExpr ;
@@ -446,67 +418,41 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
446
418
447
419
private static Func < object ? , HttpContext , Task > HandleRequestBodyAndCompileRequestDelegate ( Expression responseWritingMethodCall , FactoryContext factoryContext )
448
420
{
449
- if ( factoryContext . RequestBodyMode is RequestBodyMode . AsJson )
421
+ if ( factoryContext . JsonRequestBodyType is null )
450
422
{
451
- // We need to generate the code for reading from the body before calling into the delegate
452
- var invoker = Expression . Lambda < Func < object ? , HttpContext , object ? , Task > > (
453
- responseWritingMethodCall , TargetExpr , HttpContextExpr , BodyValueExpr ) . Compile ( ) ;
454
-
455
- var bodyType = factoryContext . JsonRequestBodyType ! ;
456
- object ? defaultBodyValue = null ;
457
-
458
- if ( factoryContext . AllowEmptyRequestBody && bodyType . IsValueType )
459
- {
460
- defaultBodyValue = Activator . CreateInstance ( bodyType ) ;
461
- }
423
+ return Expression . Lambda < Func < object ? , HttpContext , Task > > (
424
+ responseWritingMethodCall , TargetExpr , HttpContextExpr ) . Compile ( ) ;
425
+ }
462
426
463
- return async ( target , httpContext ) =>
464
- {
465
- object ? bodyValue ;
427
+ // We need to generate the code for reading from the body before calling into the delegate
428
+ var invoker = Expression . Lambda < Func < object ? , HttpContext , object ? , Task > > (
429
+ responseWritingMethodCall , TargetExpr , HttpContextExpr , BodyValueExpr ) . Compile ( ) ;
466
430
467
- if ( factoryContext . AllowEmptyRequestBody && httpContext . Request . ContentLength == 0 )
468
- {
469
- bodyValue = defaultBodyValue ;
470
- }
471
- else
472
- {
473
- try
474
- {
475
- bodyValue = await httpContext . Request . ReadFromJsonAsync ( bodyType ) ;
476
- }
477
- catch ( IOException ex )
478
- {
479
- Log . RequestBodyIOException ( httpContext , ex ) ;
480
- return ;
481
- }
482
- catch ( InvalidDataException ex )
483
- {
484
- Log . RequestBodyInvalidDataException ( httpContext , ex ) ;
485
- httpContext . Response . StatusCode = 400 ;
486
- return ;
487
- }
488
- }
431
+ var bodyType = factoryContext . JsonRequestBodyType ! ;
432
+ object ? defaultBodyValue = null ;
489
433
490
- await invoker ( target , httpContext , bodyValue ) ;
491
- } ;
434
+ if ( factoryContext . AllowEmptyRequestBody && bodyType . IsValueType )
435
+ {
436
+ defaultBodyValue = Activator . CreateInstance ( bodyType ) ;
492
437
}
493
- else if ( factoryContext . RequestBodyMode is RequestBodyMode . AsForm )
438
+
439
+ return async ( target , httpContext ) =>
494
440
{
495
- var invoker = Expression . Lambda < Func < object ? , HttpContext , Task > > (
496
- responseWritingMethodCall , TargetExpr , HttpContextExpr ) . Compile ( ) ;
441
+ object ? bodyValue ;
497
442
498
- return async ( target , httpContext ) =>
443
+ if ( factoryContext . AllowEmptyRequestBody && httpContext . Request . ContentLength == 0 )
444
+ {
445
+ bodyValue = defaultBodyValue ;
446
+ }
447
+ else
499
448
{
500
- // Generating async code would just be insane so if the method needs the form populate it here
501
- // so the within the method it's cached
502
449
try
503
450
{
504
- await httpContext . Request . ReadFormAsync ( ) ;
451
+ bodyValue = await httpContext . Request . ReadFromJsonAsync ( bodyType ) ;
505
452
}
506
453
catch ( IOException ex )
507
454
{
508
455
Log . RequestBodyIOException ( httpContext , ex ) ;
509
- httpContext . Abort ( ) ;
510
456
return ;
511
457
}
512
458
catch ( InvalidDataException ex )
@@ -515,15 +461,10 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
515
461
httpContext . Response . StatusCode = 400 ;
516
462
return ;
517
463
}
464
+ }
518
465
519
- await invoker ( target , httpContext ) ;
520
- } ;
521
- }
522
- else
523
- {
524
- return Expression . Lambda < Func < object ? , HttpContext , Task > > (
525
- responseWritingMethodCall , TargetExpr , HttpContextExpr ) . Compile ( ) ;
526
- }
466
+ await invoker ( target , httpContext , bodyValue ) ;
467
+ } ;
527
468
}
528
469
529
470
private static MethodInfo GetEnumTryParseMethod ( )
@@ -793,22 +734,8 @@ private static async Task ExecuteTaskResult<T>(Task<T> task, HttpContext httpCon
793
734
await ( await task ) . ExecuteAsync ( httpContext ) ;
794
735
}
795
736
796
- [ StackTraceHidden ]
797
- private static void ThrowCannotReadBodyDirectlyAndAsForm ( )
798
- {
799
- throw new InvalidOperationException ( "Action cannot mix FromBody and FromForm on the same method." ) ;
800
- }
801
-
802
- private enum RequestBodyMode
803
- {
804
- None ,
805
- AsJson ,
806
- AsForm ,
807
- }
808
-
809
737
private class FactoryContext
810
738
{
811
- public RequestBodyMode RequestBodyMode { get ; set ; }
812
739
public Type ? JsonRequestBodyType { get ; set ; }
813
740
public bool AllowEmptyRequestBody { get ; set ; }
814
741
0 commit comments