Skip to content

Commit

Permalink
Reduce arguments on TryRead*Async methods
Browse files Browse the repository at this point in the history
Just accept the HttpContext and the FactoryContext and do the work with them in the static local methods, rather than in the caller.
  • Loading branch information
martincostello committed Nov 6, 2021
1 parent fc017c2 commit 599e72c
Showing 1 changed file with 32 additions and 54 deletions.
86 changes: 32 additions & 54 deletions src/Http/Http.Extensions/src/RequestDelegateFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -575,19 +575,6 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
{
Debug.Assert(factoryContext.JsonRequestBodyParameter is not null, "factoryContext.JsonRequestBodyParameter is null for a JSON body.");

var bodyType = factoryContext.JsonRequestBodyParameter.ParameterType;
var parameterTypeName = TypeNameHelper.GetTypeDisplayName(factoryContext.JsonRequestBodyParameter.ParameterType, fullName: false);
var parameterName = factoryContext.JsonRequestBodyParameter.Name;

Debug.Assert(parameterName is not null, "CreateArgument() should throw if parameter.Name is null.");

object? defaultBodyValue = null;

if (factoryContext.AllowEmptyRequestBody && bodyType.IsValueType)
{
defaultBodyValue = Activator.CreateInstance(bodyType);
}

if (factoryContext.ParameterBinders.Count > 0)
{
// We need to generate the code for reading from the body before calling into the delegate
Expand All @@ -608,13 +595,7 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
boundValues[i] = await binders[i](httpContext);
}

(var bodyValue, var successful) = await TryReadBodyAsync(
parameterTypeName,
parameterName,
bodyType,
defaultBodyValue,
httpContext,
factoryContext.ThrowOnBadRequest);
(var bodyValue, var successful) = await TryReadBodyAsync(httpContext, factoryContext);

if (!successful)
{
Expand All @@ -632,13 +613,7 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,

return async (target, httpContext) =>
{
(var bodyValue, var successful) = await TryReadBodyAsync(
parameterTypeName,
parameterName,
bodyType,
defaultBodyValue,
httpContext,
factoryContext.ThrowOnBadRequest);
(var bodyValue, var successful) = await TryReadBodyAsync(httpContext, factoryContext);

if (!successful)
{
Expand All @@ -650,21 +625,32 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
}

static async Task<(object? FormValue, bool Successful)> TryReadBodyAsync(
string parameterTypeName,
string parameterName,
Type bodyType,
object? defaultBodyValue,
HttpContext httpContext,
bool throwOnBadRequest)
FactoryContext factoryContext)
{
Debug.Assert(factoryContext.JsonRequestBodyParameter is not null, "TryReadFormAsync() should not be called if there is no JSON body parameter.");

var bodyType = factoryContext.JsonRequestBodyParameter.ParameterType;
var parameterTypeName = TypeNameHelper.GetTypeDisplayName(factoryContext.JsonRequestBodyParameter.ParameterType, fullName: false);
var parameterName = factoryContext.JsonRequestBodyParameter.Name;

Debug.Assert(parameterName is not null, "CreateArgument() should throw if parameter.Name is null.");

object? defaultBodyValue = null;

if (factoryContext.AllowEmptyRequestBody && bodyType.IsValueType)
{
defaultBodyValue = Activator.CreateInstance(bodyType);
}

var bodyValue = defaultBodyValue;
var feature = httpContext.Features.Get<IHttpRequestBodyDetectionFeature>();

if (feature?.CanHaveBody == true)
{
if (!httpContext.Request.HasJsonContentType())
{
Log.UnexpectedJsonContentType(httpContext, httpContext.Request.ContentType, throwOnBadRequest);
Log.UnexpectedJsonContentType(httpContext, httpContext.Request.ContentType, factoryContext.ThrowOnBadRequest);
httpContext.Response.StatusCode = StatusCodes.Status415UnsupportedMediaType;
return (null, false);
}
Expand All @@ -679,7 +665,7 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
}
catch (JsonException ex)
{
Log.InvalidJsonRequestBody(httpContext, parameterTypeName, parameterName, ex, throwOnBadRequest);
Log.InvalidJsonRequestBody(httpContext, parameterTypeName, parameterName, ex, factoryContext.ThrowOnBadRequest);
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
return (null, false);
}
Expand All @@ -695,11 +681,6 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
{
Debug.Assert(factoryContext.FormRequestBodyParameter is not null, "factoryContext.FormRequestBodyParameter is null for a form body.");

var parameterTypeName = TypeNameHelper.GetTypeDisplayName(factoryContext.FormRequestBodyParameter.ParameterType, fullName: false);
var parameterName = factoryContext.FormRequestBodyParameter.Name;

Debug.Assert(parameterName is not null, "CreateArgument() should throw if parameter.Name is null.");

if (factoryContext.ParameterBinders.Count > 0)
{
// We need to generate the code for reading from the body or form before calling into the delegate
Expand All @@ -720,11 +701,7 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
boundValues[i] = await binders[i](httpContext);
}

(var formValue, var successful) = await TryReadFormAsync(
parameterTypeName,
parameterName,
httpContext,
factoryContext.ThrowOnBadRequest);
(var formValue, var successful) = await TryReadFormAsync(httpContext, factoryContext);

if (!successful)
{
Expand All @@ -742,11 +719,7 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,

return async (target, httpContext) =>
{
(var formValue, var successful) = await TryReadFormAsync(
parameterTypeName,
parameterName,
httpContext,
factoryContext.ThrowOnBadRequest);
(var formValue, var successful) = await TryReadFormAsync(httpContext, factoryContext);

if (!successful)
{
Expand All @@ -758,19 +731,24 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
}

static async Task<(object? FormValue, bool Successful)> TryReadFormAsync(
string parameterTypeName,
string parameterName,
HttpContext httpContext,
bool throwOnBadRequest)
FactoryContext factoryContext)
{
Debug.Assert(factoryContext.FormRequestBodyParameter is not null, "TryReadFormAsync() should not be called if there are no form parameters.");

var parameterTypeName = TypeNameHelper.GetTypeDisplayName(factoryContext.FormRequestBodyParameter.ParameterType, fullName: false);
var parameterName = factoryContext.FormRequestBodyParameter.Name;

Debug.Assert(parameterName is not null, "CreateArgument() should throw if parameter.Name is null.");

object? formValue = null;
var feature = httpContext.Features.Get<IHttpRequestBodyDetectionFeature>();

if (feature?.CanHaveBody == true)
{
if (!httpContext.Request.HasFormContentType)
{
Log.UnexpectedFormContentType(httpContext, httpContext.Request.ContentType, throwOnBadRequest);
Log.UnexpectedFormContentType(httpContext, httpContext.Request.ContentType, factoryContext.ThrowOnBadRequest);
httpContext.Response.StatusCode = StatusCodes.Status415UnsupportedMediaType;
return (null, false);
}
Expand All @@ -785,7 +763,7 @@ private static Expression AddResponseWritingToMethodCall(Expression methodCall,
}
catch (InvalidDataException ex)
{
Log.InvalidFormRequestBody(httpContext, parameterTypeName, parameterName, ex, throwOnBadRequest);
Log.InvalidFormRequestBody(httpContext, parameterTypeName, parameterName, ex, factoryContext.ThrowOnBadRequest);
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
return (null, false);
}
Expand Down

0 comments on commit 599e72c

Please sign in to comment.