Skip to content

Instantly share code, notes, and snippets.

@yuka1984
Created July 7, 2019 08:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuka1984/3b31be38e3b52f396bd7c045c0fc8f3e to your computer and use it in GitHub Desktop.
Save yuka1984/3b31be38e3b52f396bd7c045c0fc8f3e to your computer and use it in GitHub Desktop.
public abstract class ApiFunctionBase
{
public ILogger Logger { get; protected set; }
public HttpRequest Request { get; protected set; }
protected virtual ApiError GetExceptionApiError(Exception e)
{
return new ApiError
{
Title = "Internal server error",
Detail = e.Message,
HttpStatusCode = (int)HttpStatusCode.InternalServerError,
};
}
protected IActionResult NotFound(object content = null)
{
if (content == null)
{
return new NotFoundResult(); ;
}
else
{
return new NotFoundObjectResult(content);
}
}
protected IActionResult BadRequest<T>(ApiRequest<T> apiRequest)
{
var result = new ApiError
{
Title = "Request parameter is incorrect",
Detail = apiRequest.ValidationResultMessage,
HttpStatusCode = (int)HttpStatusCode.BadRequest,
Parameters = apiRequest.ValidationResults
.SelectMany(x => x.MemberNames, (validationResult, s) => (s, validationResult.ErrorMessage))
.ToDictionary(x => x.s, x => x.ErrorMessage)
};
return new BadRequestObjectResult(apiRequest);
}
protected IActionResult PreconditionFailed(string message)
{
var result = new ApiError()
{
Title = message,
};
return new ObjectResult(result) { StatusCode = 412 };
}
protected T Merge<T, TRequest>(T destination, ApiRequest<TRequest> request)
{
var destinationJobject = JObject.FromObject(destination);
destinationJobject.Merge(request.RequestJObject);
return destinationJobject.ToObject<T>();
}
protected virtual async Task<ApiRequest<TRequestBody>> GetApiRequest<TRequestBody>(string body)
{
TRequestBody request;
var jObject = default(JObject);
try
{
jObject = JObject.Parse(body);
request = jObject.ToObject<TRequestBody>();
}
catch (Exception e)
{
return new ApiRequest<TRequestBody>
{
IsValid = false,
ValidationResults = new List<ValidationResult> { new ValidationResult("Can not Deserialize json") }
};
}
if (request == null)
{
return new ApiRequest<TRequestBody>
{
IsValid = false,
ValidationResults = new List<ValidationResult> { new ValidationResult("Can not Deserialize json") }
};
}
var validationResults = new List<ValidationResult>();
if (request is IValidation valid)
{
validationResults.AddRange(valid.GetValidationResults());
}
var result = new ApiRequest<TRequestBody>
{
Request = request,
RequestJObject = jObject,
IsValid = Validator.TryValidateObject(request, new ValidationContext(request), validationResults, true),
ValidationResults = validationResults
};
return result;
}
}
public abstract class ApiFunction<TRequestBody> : ApiFunctionBase
{
protected abstract Task<IActionResult> FunctionLogic(ApiRequest<TRequestBody> apiRequest);
public virtual async Task<IActionResult> InvokeAsync(HttpRequest httpRequest, ILogger logger)
{
Request = httpRequest;
Logger = logger;
var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();
var apiRequest = await GetApiRequest<TRequestBody>(body);
if (!apiRequest.IsValid)
{
var result = new ApiError
{
Title = "Request parameter is incorrect",
Detail = apiRequest.ValidationResultMessage,
HttpStatusCode = (int)HttpStatusCode.BadRequest,
Parameters = apiRequest.ValidationResults
.SelectMany(x => x.MemberNames, (validationResult, s) => (s, validationResult.ErrorMessage))
.ToDictionary(x => x.s, x => x.ErrorMessage)
};
return new BadRequestObjectResult(result);
}
try
{
return await FunctionLogic(apiRequest);
}
catch (Exception e)
{
Logger.LogError(e, e.Message);
var apiError = GetExceptionApiError(e);
return new ObjectResult(apiError) {StatusCode = (int) HttpStatusCode.InternalServerError};
}
}
}
public abstract class ApiFunction<TRequestBody, TParam> : ApiFunctionBase
{
protected abstract Task<IActionResult> FunctionLogic(ApiRequest<TRequestBody> apiRequest, TParam param);
public virtual async Task<IActionResult> InvokeAsync(HttpRequest httpRequest, ILogger logger, TParam param)
{
Request = httpRequest;
Logger = logger;
var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();
var apiRequest = await GetApiRequest<TRequestBody>(body);
if (!apiRequest.IsValid)
{
var result = new ApiError
{
Title = "Request parameter is incorrect",
Detail = apiRequest.ValidationResultMessage,
HttpStatusCode = (int)HttpStatusCode.BadRequest,
Parameters = apiRequest.ValidationResults
.SelectMany(x => x.MemberNames, (validationResult, s) => (s, validationResult.ErrorMessage))
.ToDictionary(x => x.s, x => x.ErrorMessage)
};
return new BadRequestObjectResult(result);
}
try
{
return await FunctionLogic(apiRequest, param);
}
catch (Exception e)
{
Logger.LogError(e, e.Message);
var apiError = GetExceptionApiError(e);
return new ObjectResult(apiError) { StatusCode = (int)HttpStatusCode.InternalServerError };
}
}
}
public abstract class ApiFunction<TRequestBody, TParam1, TParam2> : ApiFunctionBase
{
protected abstract Task<IActionResult> FunctionLogic(ApiRequest<TRequestBody> apiRequest, TParam1 param1, TParam2 param2);
public virtual async Task<IActionResult> InvokeAsync(HttpRequest httpRequest, ILogger logger, TParam1 param1, TParam2 param2)
{
Request = httpRequest;
Logger = logger;
var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();
var apiRequest = await GetApiRequest<TRequestBody>(body);
if (!apiRequest.IsValid)
{
var result = new ApiError
{
Title = "Request parameter is incorrect",
Detail = apiRequest.ValidationResultMessage,
HttpStatusCode = (int)HttpStatusCode.BadRequest,
Parameters = apiRequest.ValidationResults
.SelectMany(x => x.MemberNames, (validationResult, s) => (s, validationResult.ErrorMessage))
.ToDictionary(x => x.s, x => x.ErrorMessage)
};
return new BadRequestObjectResult(result);
}
try
{
return await FunctionLogic(apiRequest, param1, param2);
}
catch (Exception e)
{
Logger.LogError(e, e.Message);
var apiError = GetExceptionApiError(e);
return new ObjectResult(apiError) { StatusCode = (int)HttpStatusCode.InternalServerError };
}
}
}
public abstract class NoBodyApiFunction : ApiFunctionBase
{
protected abstract Task<IActionResult> FunctionLogic();
public virtual async Task<IActionResult> InvokeAsync(HttpRequest httpRequest, ILogger logger)
{
Request = httpRequest;
Logger = logger;
try
{
return await FunctionLogic();
}
catch (Exception e)
{
Logger.LogError(e, e.Message);
var apiError = GetExceptionApiError(e);
return new ObjectResult(apiError) { StatusCode = (int)HttpStatusCode.InternalServerError };
}
}
}
public abstract class NoBodyApiFunction<TParam> : ApiFunctionBase
{
protected abstract Task<IActionResult> FunctionLogic(TParam param);
public virtual async Task<IActionResult> InvokeAsync(HttpRequest httpRequest, ILogger logger, TParam param)
{
try
{
Request = httpRequest;
Logger = logger;
return await FunctionLogic(param);
}
catch (Exception e)
{
Logger.LogError(e, e.Message);
var apiError = GetExceptionApiError(e);
return new ObjectResult(apiError) { StatusCode = (int)HttpStatusCode.InternalServerError };
}
}
}
public abstract class NoBodyApiFunction<TParam1, TParam2> : ApiFunctionBase
{
protected abstract Task<IActionResult> FunctionLogic(TParam1 param1, TParam2 param2);
public virtual async Task<IActionResult> InvokeAsync(HttpRequest httpRequest, ILogger logger, TParam1 param1, TParam2 param2)
{
Request = httpRequest;
Logger = logger;
try
{
return await FunctionLogic(param1, param2);
}
catch (Exception e)
{
Logger.LogError(e, e.Message);
var apiError = GetExceptionApiError(e);
return new ObjectResult(apiError) { StatusCode = (int)HttpStatusCode.InternalServerError };
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment