| File: ValidationProblem.cs | Web Access |
| Project: src\aspnetcore\src\Http\Http.Results\src\Microsoft.AspNetCore.Http.Results.csproj (Microsoft.AspNetCore.Http.Results) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Http.HttpResults; /// <summary> /// An <see cref="IResult"/> that on execution will write Problem Details /// HTTP API responses based on https://tools.ietf.org/html/rfc7807 /// </summary> public sealed class ValidationProblem : IResult, IEndpointMetadataProvider, IStatusCodeHttpResult, IContentTypeHttpResult, IValueHttpResult, IValueHttpResult<HttpValidationProblemDetails> { internal ValidationProblem(HttpValidationProblemDetails problemDetails) { ArgumentNullException.ThrowIfNull(problemDetails); if (problemDetails is { Status: not null and not StatusCodes.Status400BadRequest }) { throw new ArgumentException($"{nameof(ValidationProblem)} only supports a 400 Bad Request response status code.", nameof(problemDetails)); } ProblemDetails = problemDetails; ProblemDetailsDefaults.Apply(ProblemDetails, statusCode: StatusCodes.Status400BadRequest); } /// <summary> /// Gets the <see cref="HttpValidationProblemDetails"/> instance. /// </summary> public HttpValidationProblemDetails ProblemDetails { get; } object? IValueHttpResult.Value => ProblemDetails; HttpValidationProblemDetails? IValueHttpResult<HttpValidationProblemDetails>.Value => ProblemDetails; /// <summary> /// Gets the value for the <c>Content-Type</c> header: <c>application/problem+json</c>. /// </summary> public string ContentType => ContentTypeConstants.ProblemDetailsContentType; /// <summary> /// Gets the HTTP status code: <see cref="StatusCodes.Status400BadRequest"/> /// </summary> public int StatusCode => StatusCodes.Status400BadRequest; int? IStatusCodeHttpResult.StatusCode => StatusCode; /// <inheritdoc/> public async Task ExecuteAsync(HttpContext httpContext) { ArgumentNullException.ThrowIfNull(httpContext); var loggerFactory = httpContext.RequestServices.GetRequiredService<ILoggerFactory>(); var logger = loggerFactory.CreateLogger(typeof(ValidationProblem)); var problemDetailsService = httpContext.RequestServices.GetService<IProblemDetailsService>(); HttpResultsHelper.Log.WritingResultAsStatusCode(logger, StatusCode); httpContext.Response.StatusCode = StatusCode; if (problemDetailsService is null || !await problemDetailsService.TryWriteAsync(new() { HttpContext = httpContext, ProblemDetails = ProblemDetails })) { await HttpResultsHelper.WriteResultAsJsonAsync( httpContext, logger, value: ProblemDetails, ContentType); } } /// <inheritdoc/> static void IEndpointMetadataProvider.PopulateMetadata(MethodInfo method, EndpointBuilder builder) { ArgumentNullException.ThrowIfNull(method); ArgumentNullException.ThrowIfNull(builder); builder.Metadata.Add(ProducesResponseTypeMetadata.CreateUnvalidated(typeof(HttpValidationProblemDetails), StatusCodes.Status400BadRequest, ContentTypeConstants.ProblemDetailsContentTypes)); builder.Metadata.Add(DisableCookieRedirectMetadata.Instance); } }