96 lines
2.5 KiB
C#
96 lines
2.5 KiB
C#
namespace MyOffice.Web.Infrastructure;
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
public class CustomProblemDetailsFactory : ProblemDetailsFactory
|
|
{
|
|
private readonly ApiBehaviorOptions options;
|
|
private readonly JsonOptions jsonOptions;
|
|
|
|
public CustomProblemDetailsFactory(IOptions<ApiBehaviorOptions> options, IOptions<JsonOptions> jsonOptions)
|
|
{
|
|
this.options = options?.Value ?? throw new ArgumentNullException(nameof(options));
|
|
this.jsonOptions = jsonOptions?.Value ?? throw new ArgumentNullException(nameof(jsonOptions));
|
|
}
|
|
|
|
public override ProblemDetails CreateProblemDetails(
|
|
HttpContext httpContext,
|
|
int? statusCode = null,
|
|
string? title = null,
|
|
string? type = null,
|
|
string? detail = null,
|
|
string? instance = null)
|
|
{
|
|
statusCode ??= 500;
|
|
|
|
var problemDetails = new ProblemDetails
|
|
{
|
|
Status = statusCode,
|
|
Title = title,
|
|
Type = type,
|
|
Detail = detail,
|
|
Instance = instance,
|
|
};
|
|
|
|
ApplyProblemDetailsDefaults(httpContext, problemDetails, statusCode.Value);
|
|
|
|
return problemDetails;
|
|
}
|
|
|
|
public override ValidationProblemDetails CreateValidationProblemDetails(
|
|
HttpContext httpContext,
|
|
ModelStateDictionary modelStateDictionary,
|
|
int? statusCode = null,
|
|
string? title = null,
|
|
string? type = null,
|
|
string? detail = null,
|
|
string? instance = null)
|
|
{
|
|
if (modelStateDictionary == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(modelStateDictionary));
|
|
}
|
|
|
|
statusCode ??= 400;
|
|
|
|
var errors = modelStateDictionary
|
|
.Where(x => x.Value?.Errors.Any() == true)
|
|
.ToDictionary(
|
|
kvp => jsonOptions?.JsonSerializerOptions?.PropertyNamingPolicy?.ConvertName(kvp.Key) ?? kvp.Key,
|
|
kvp => kvp.Value!.Errors.Select(x => x.ErrorMessage).ToArray()
|
|
);
|
|
|
|
var problemDetails = new ValidationProblemDetails(errors)
|
|
{
|
|
Status = statusCode,
|
|
Type = type,
|
|
Detail = detail,
|
|
Instance = instance,
|
|
};
|
|
|
|
if (title != null)
|
|
{
|
|
// For validation problem details, don't overwrite the default title with null.
|
|
problemDetails.Title = title;
|
|
}
|
|
|
|
ApplyProblemDetailsDefaults(httpContext, problemDetails, statusCode.Value);
|
|
|
|
return problemDetails;
|
|
}
|
|
|
|
private void ApplyProblemDetailsDefaults(HttpContext httpContext, ProblemDetails problemDetails, int statusCode)
|
|
{
|
|
problemDetails.Status ??= statusCode;
|
|
|
|
if (options.ClientErrorMapping.TryGetValue(statusCode, out var clientErrorData))
|
|
{
|
|
problemDetails.Title ??= clientErrorData.Title;
|
|
problemDetails.Type ??= clientErrorData.Link;
|
|
}
|
|
}
|
|
}
|