diff --git a/src/Ardalis.Result.AspNetCore/MinimalApiResultExtensions.cs b/src/Ardalis.Result.AspNetCore/MinimalApiResultExtensions.cs
index 3988a2f..29df941 100644
--- a/src/Ardalis.Result.AspNetCore/MinimalApiResultExtensions.cs
+++ b/src/Ardalis.Result.AspNetCore/MinimalApiResultExtensions.cs
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using System.Text;
+
+using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -36,8 +38,8 @@ internal static Microsoft.AspNetCore.Http.IResult ToMinimalApiResult(this IResul
ResultStatus.Ok => result is Result ? Results.Ok() : Results.Ok(result.GetValue()),
ResultStatus.Created => Results.Created("", result.GetValue()),
ResultStatus.NotFound => NotFoundEntity(result),
- ResultStatus.Unauthorized => Results.Unauthorized(),
- ResultStatus.Forbidden => Results.Forbid(),
+ ResultStatus.Unauthorized => UnAuthorized(result),
+ ResultStatus.Forbidden => Forbidden(result),
ResultStatus.Invalid => Results.BadRequest(result.ValidationErrors),
ResultStatus.Error => UnprocessableEntity(result),
ResultStatus.Conflict => ConflictEntity(result),
@@ -140,5 +142,47 @@ private static Microsoft.AspNetCore.Http.IResult UnavailableEntity(IResult resul
return Results.StatusCode(StatusCodes.Status503ServiceUnavailable);
}
}
+
+ private static Microsoft.AspNetCore.Http.IResult Forbidden(IResult result)
+ {
+ var details = new StringBuilder("Next error(s) occurred:");
+
+ if (result.Errors.Any())
+ {
+ foreach (var error in result.Errors) details.Append("* ").Append(error).AppendLine();
+
+ return Results.Problem(new ProblemDetails
+ {
+ Title = "Forbidden.",
+ Detail = details.ToString(),
+ Status = StatusCodes.Status403Forbidden
+ });
+ }
+ else
+ {
+ return Results.Forbid();
+ }
+ }
+
+ private static Microsoft.AspNetCore.Http.IResult UnAuthorized(IResult result)
+ {
+ var details = new StringBuilder("Next error(s) occurred:");
+
+ if (result.Errors.Any())
+ {
+ foreach (var error in result.Errors) details.Append("* ").Append(error).AppendLine();
+
+ return Results.Problem(new ProblemDetails
+ {
+ Title = "Unauthorized.",
+ Detail = details.ToString(),
+ Status = StatusCodes.Status401Unauthorized
+ });
+ }
+ else
+ {
+ return Results.Unauthorized();
+ }
+ }
}
#endif
diff --git a/src/Ardalis.Result/Result.Void.cs b/src/Ardalis.Result/Result.Void.cs
index 8486536..b9ba543 100644
--- a/src/Ardalis.Result/Result.Void.cs
+++ b/src/Ardalis.Result/Result.Void.cs
@@ -136,6 +136,17 @@ public static Result Error(string errorMessage)
return new Result(ResultStatus.Forbidden);
}
+ ///
+ /// The parameters to the call were correct, but the user does not have permission to perform some action.
+ /// See also HTTP 403 Forbidden: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors
+ ///
+ /// A list of string error messages.
+ /// A Result
+ public new static Result Forbidden(params string[] errorMessages)
+ {
+ return new Result(ResultStatus.Forbidden) { Errors = errorMessages };
+ }
+
///
/// This is similar to Forbidden, but should be used when the user has not authenticated or has attempted to authenticate but failed.
/// See also HTTP 401 Unauthorized: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors
@@ -145,7 +156,18 @@ public static Result Error(string errorMessage)
{
return new Result(ResultStatus.Unauthorized);
}
-
+
+ ///
+ /// This is similar to Forbidden, but should be used when the user has not authenticated or has attempted to authenticate but failed.
+ /// See also HTTP 401 Unauthorized: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors
+ ///
+ /// A list of string error messages.
+ /// A Result
+ public new static Result Unauthorized(params string[] errorMessages)
+ {
+ return new Result(ResultStatus.Unauthorized) { Errors = errorMessages };
+ }
+
///
/// Represents a situation where a service is in conflict due to the current state of a resource,
/// such as an edit conflict between multiple concurrent updates.
diff --git a/src/Ardalis.Result/Result.cs b/src/Ardalis.Result/Result.cs
index 9176e5b..79b2569 100644
--- a/src/Ardalis.Result/Result.cs
+++ b/src/Ardalis.Result/Result.cs
@@ -217,6 +217,17 @@ public static Result Forbidden()
return new Result(ResultStatus.Forbidden);
}
+ ///
+ /// The parameters to the call were correct, but the user does not have permission to perform some action.
+ /// See also HTTP 403 Forbidden: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors
+ ///
+ /// A list of string error messages.
+ /// A Result
+ public static Result Forbidden(params string[] errorMessages)
+ {
+ return new Result(ResultStatus.Forbidden) { Errors = errorMessages };
+ }
+
///
/// This is similar to Forbidden, but should be used when the user has not authenticated or has attempted to authenticate but failed.
/// See also HTTP 401 Unauthorized: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors
@@ -226,7 +237,18 @@ public static Result Unauthorized()
{
return new Result(ResultStatus.Unauthorized);
}
-
+
+ ///
+ /// This is similar to Forbidden, but should be used when the user has not authenticated or has attempted to authenticate but failed.
+ /// See also HTTP 401 Unauthorized: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_client_errors
+ ///
+ /// A list of string error messages.
+ /// A Result
+ public static Result Unauthorized(params string[] errorMessages)
+ {
+ return new Result(ResultStatus.Unauthorized) { Errors = errorMessages };
+ }
+
///
/// Represents a situation where a service is in conflict due to the current state of a resource,
/// such as an edit conflict between multiple concurrent updates.
diff --git a/src/Ardalis.Result/ResultExtensions.cs b/src/Ardalis.Result/ResultExtensions.cs
index ad96f5f..5efca42 100644
--- a/src/Ardalis.Result/ResultExtensions.cs
+++ b/src/Ardalis.Result/ResultExtensions.cs
@@ -25,8 +25,12 @@ public static Result Map(this Result.NotFound(result.Errors.ToArray())
: Result.NotFound();
- case ResultStatus.Unauthorized: return Result.Unauthorized();
- case ResultStatus.Forbidden: return Result.Forbidden();
+ case ResultStatus.Unauthorized: return result.Errors.Any()
+ ? Result.Unauthorized(result.Errors.ToArray())
+ : Result.Unauthorized();
+ case ResultStatus.Forbidden: return result.Errors.Any()
+ ? Result.Forbidden(result.Errors.ToArray())
+ : Result.Forbidden();
case ResultStatus.Invalid: return Result.Invalid(result.ValidationErrors);
case ResultStatus.Error: return Result.Error(new ErrorList(result.Errors.ToArray(), result.CorrelationId));
case ResultStatus.Conflict: return result.Errors.Any()
diff --git a/tests/Ardalis.Result.UnitTests/ResultConstructor.cs b/tests/Ardalis.Result.UnitTests/ResultConstructor.cs
index 8f4fde1..44deaf6 100644
--- a/tests/Ardalis.Result.UnitTests/ResultConstructor.cs
+++ b/tests/Ardalis.Result.UnitTests/ResultConstructor.cs
@@ -235,6 +235,34 @@ public void InitializesStatusToForbiddenGivenForbiddenFactoryCall()
Assert.Equal(ResultStatus.Forbidden, result.Status);
}
+ [Fact]
+ public void InitializesStatusToForbiddenGivenForbiddenFactoryCallWithString()
+ {
+ var errorMessage = "You are forbidden";
+ var result = Result