Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="statusCode"></param>
        /// <param name="detail"></param>
        /// <param name="instance"></param>
        /// <param name="title"></param>
        /// <param name="type"></param>
        /// <param name="extensions"></param>
        /// <returns></returns>
        public static ProblemDetails FromStatusCode(int statusCode, string detail, string instance = null, string title = null, string type = null, IDictionary <string, object> extensions = null)
        {
            ProblemDetails returnValue = null;

            switch (statusCode)
            {
            case StatusCodes.Status200OK:
                returnValue = DoActionResult.Ok();
                break;

            case StatusCodes.Status201Created:
                returnValue = DoActionResult.Created();
                break;

            case StatusCodes.Status204NoContent:
                returnValue = DoActionResult.NoContent();
                break;

            case StatusCodes.Status400BadRequest:
                returnValue = DoActionResult.BadRequest(detail, instance, title, extensions);
                break;

            case StatusCodes.Status404NotFound:
                returnValue = DoActionResult.NotFound(detail, instance, title, extensions);
                break;

            case StatusCodes.Status413PayloadTooLarge:
                returnValue = DoActionResult.PayloadTooLarge(detail, instance, title, extensions);
                break;

            case StatusCodes.Status500InternalServerError:
                returnValue = DoActionResult.InternalServerError(detail, instance, title, extensions);
                break;

            case StatusCodes.Status501NotImplemented:
                returnValue = DoActionResult.NotImplemented(detail, instance, title, extensions);
                break;

            default:
                returnValue = new ProblemDetails()
                {
                    Status   = statusCode,
                    Type     = type,
                    Title    = title,
                    Detail   = detail,
                    Instance = instance
                };
                break;
            }

            return(returnValue);
        }
        /// <summary>
        /// Executes the controller method without the given parameter.
        /// </summary>
        /// <typeparam name="TInputs"></typeparam>
        /// <typeparam name="TResult">The type of object returned by the action.</typeparam>
        /// <param name="actionKey">The name of the action retrieved from the container.</param>
        /// <param name="inputs">The input parameter for the action.</param>
        /// <returns>An ActionResult encapsulating the expected return type.</returns>
        protected virtual async Task <ActionResult <TResult> > Do <TInputs, TResult>(TInputs inputs, [CallerMemberName] string actionKey = null)
        {
            ActionResult <TResult> returnValue = default;

            try
            {
                //
                // Log the method call.
                //
                this.LogMethodCall();

                //
                // Get the IDoAction
                //
                IDoAction <TInputs, TResult> action = null;

                try
                {
                    this.Logger.LogDebug($"Retrieving controller method action '{actionKey}'.");
                    action = await this.DoActionFactory.GetAsync <TInputs, TResult>(actionKey);

                    this.Logger.LogDebug($"Controller method action '{actionKey}' was successfully retrieved.");
                }
                catch (DoActionNotFoundException)
                {
                    //
                    // An implementation of this method was not found.
                    //
                    this.Logger.LogWarning($"Controller method action '{actionKey}' was not found in the container.");
                    returnValue = this.StatusCode(StatusCodes.Status501NotImplemented, this.OnCreateProblemDetail(DoActionResult.NotImplemented($"The method has not been implemented. This could be a configuration error or the service is still under development.")));
                    action      = null;
                }
                catch (Exception ex)
                {
                    //
                    // An implementation of this method was not found.
                    //
                    this.Logger.LogError(ex, $"Exception while retrieving do action.");
                    returnValue = this.StatusCode(StatusCodes.Status500InternalServerError, this.OnCreateProblemDetail(DoActionResult.InternalServerError("An unknown internal server error occurred.")));
                    action      = null;
                }

                if (action != null)
                {
                    using (ITryDisposable <IDoAction <TInputs, TResult> > disposable = new TryDisposable <IDoAction <TInputs, TResult> >(action))
                    {
                        //
                        // Perform the extra model validation step.
                        //
                        (bool modelResult, string errorMessage) = await action.ValidateModel(inputs);

                        if (modelResult)
                        {
                            //
                            // Execute the action.
                            //
                            this.Logger.LogDebug($"Executing controller method action '{actionKey}.TakeActionAsync()'.");
                            IControllerActionResult <TResult> result = await action.ExecuteActionAsync(inputs);

                            if (result.ResultDetails.Status == StatusCodes.Status200OK)
                            {
                                this.Logger.LogDebug($"Controller method action '{actionKey}.TakeActionAsync()' completed successfully.");
                                returnValue = this.Ok(result.Result);
                            }
                            else
                            {
                                this.Logger.LogDebug($"Controller method action '{actionKey}.TakeActionAsync()' completed with HTTP Status Code of {result.ResultDetails.Status}.");
                                this.Logger.LogDebug($"The action returned: '{result.ResultDetails.Detail}'.");

                                //
                                // Check if the instance is null.
                                //
                                if (result.ResultDetails.Instance == null)
                                {
                                    //
                                    // Add the request path.
                                    //
                                    result.ResultDetails.Instance = HttpContext.Request.Path;
                                }

                                returnValue = this.StatusCode(result.ResultDetails.Status.Value, this.OnCreateProblemDetail(result.ResultDetails));
                            }
                        }
                        else
                        {
                            //
                            // Model validation failed. Return a 400
                            //
                            ProblemDetails problemDetails = DoActionResult.BadRequest(errorMessage);
                            returnValue = this.BadRequest(this.OnCreateProblemDetail(problemDetails));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //
                // Internal error.
                //
                this.Logger.LogError(ex, nameof(Do));
                returnValue = this.StatusCode(StatusCodes.Status500InternalServerError);
            }

            return(returnValue);
        }