| | | 1 | | using Microsoft.Extensions.Primitives; |
| | | 2 | | using Microsoft.Net.Http.Headers; |
| | | 3 | | |
| | | 4 | | namespace ProjectTemplate.Web.ErrorHandling; |
| | | 5 | | |
| | | 6 | | /// <summary> |
| | | 7 | | /// Provides methods for determining whether a request should be classified for Problem Details response formatting. |
| | | 8 | | /// </summary> |
| | | 9 | | /// <remarks>This class contains logic to identify requests that are likely to expect Problem Details responses, |
| | | 10 | | /// such as API requests or AJAX calls. It is intended for internal use within the application pipeline.</remarks> |
| | | 11 | | internal static class ProblemDetailsRequestClassifier |
| | | 12 | | { |
| | | 13 | | /// <summary> |
| | | 14 | | /// Determines whether a Problem Details response should be written for the specified HTTP context. |
| | | 15 | | /// </summary> |
| | | 16 | | /// <remarks>A Problem Details response is written if the request targets an API endpoint (path starts |
| | | 17 | | /// with '/api'), is an XMLHttpRequest (AJAX), or explicitly accepts a JSON response. HEAD requests are |
| | | 18 | | /// excluded.</remarks> |
| | | 19 | | /// <param name="httpContext">The HTTP context for the current request. Cannot be null.</param> |
| | | 20 | | /// <returns>true if a Problem Details response should be written for the request; otherwise, false.</returns> |
| | | 21 | | public static bool ShouldWriteProblemDetails(HttpContext httpContext) |
| | | 22 | | { |
| | 224 | 23 | | ArgumentNullException.ThrowIfNull(httpContext); |
| | | 24 | | |
| | 224 | 25 | | if (HttpMethods.IsHead(httpContext.Request.Method)) |
| | | 26 | | { |
| | 0 | 27 | | return false; |
| | | 28 | | } |
| | | 29 | | |
| | 224 | 30 | | if (httpContext.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase)) |
| | | 31 | | { |
| | 38 | 32 | | return true; |
| | | 33 | | } |
| | | 34 | | |
| | 186 | 35 | | if (httpContext.Request.Headers.TryGetValue(HeaderNames.XRequestedWith, out StringValues requestedWith) && |
| | 186 | 36 | | string.Equals(requestedWith, "XMLHttpRequest", StringComparison.OrdinalIgnoreCase)) |
| | | 37 | | { |
| | 0 | 38 | | return true; |
| | | 39 | | } |
| | | 40 | | |
| | 186 | 41 | | IList<MediaTypeHeaderValue>? acceptHeaders = httpContext.Request.GetTypedHeaders().Accept; |
| | | 42 | | |
| | 186 | 43 | | return acceptHeaders is not null && acceptHeaders.Count != 0 && acceptHeaders.Any(header => |
| | 186 | 44 | | header.MediaType.Value?.Contains("json", StringComparison.OrdinalIgnoreCase) == true); |
| | | 45 | | } |
| | | 46 | | } |