-
Notifications
You must be signed in to change notification settings - Fork 10.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding ProblemDetailsService (#42384)
* MVC Changes * ExceptionHandler changes * Routing changes * Http.Extensions changes * Minimal APi draft changes * HttpResults changes * New ProblemDetails project * Using ProblemDetailsOptions in mvc * ProblemDetails project simplification * Using metadata * Using metadata * Latest version * Removing changes * Initial cleanup * Clean up * Public api clean up * Updating public API * More clean ups * Adding initial unit tests * Updating unit tests * Adding more unit tests * Cleanup * Clean up * clean up * clean up * Removing nullable * Simplifying public api * API Review feedback * API review feedback * Clean up * Clean up * clean up * Reusing Endpoint & EndpointMetadataCollection * Fix build issues * Updates based on docs/Trimming.md * Adding Functional tests * Fix unittest * Seal context * Seal ProblemMetadata * PR Feeback * API Review * Clean up * Fixing publicapi warnings * Clean up * PR Feedback * Fixing build * Fix unit test * Fix unit tests * PR review * Fixing JsonSerializationContext issues * Adding statuscode 405 * Update src/Http/Http.Extensions/src/ProblemDetailsDefaultWriter.cs Co-authored-by: Brennan <brecon@microsoft.com> * PR review * Apply suggestions from code review Co-authored-by: Stephen Halter <halter73@gmail.com> * Fixing bad merge * Fix bad merge * Adding analysis.NextMiddlewareName * PR review * Changing to CanWrite/WriteAsync Co-authored-by: Brennan <brecon@microsoft.com> Co-authored-by: Stephen Halter <halter73@gmail.com>
- Loading branch information
1 parent
ca77aff
commit ac67d32
Showing
69 changed files
with
1,968 additions
and
514 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
23 changes: 23 additions & 0 deletions
23
src/Http/Http.Abstractions/src/ProblemDetails/IProblemDetailsService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace Microsoft.AspNetCore.Http; | ||
|
||
/// <summary> | ||
/// Defines a type that provide functionality to | ||
/// create a <see cref="Mvc.ProblemDetails"/> response. | ||
/// </summary> | ||
public interface IProblemDetailsService | ||
{ | ||
/// <summary> | ||
/// Try to write a <see cref="Mvc.ProblemDetails"/> response to the current context, | ||
/// using the registered <see cref="IProblemDetailsWriter"/> services. | ||
/// </summary> | ||
/// <param name="context">The <see cref="ProblemDetailsContext"/> associated with the current request/response.</param> | ||
/// <remarks>The <see cref="IProblemDetailsWriter"/> registered services | ||
/// are processed in sequence and the processing is completed when: | ||
/// <list type="bullet">One of them reports that the response was written successfully, or.</list> | ||
/// <list type="bullet">All <see cref="IProblemDetailsWriter"/> were executed and none of them was able to write the response successfully.</list> | ||
/// </remarks> | ||
ValueTask WriteAsync(ProblemDetailsContext context); | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Http/Http.Abstractions/src/ProblemDetails/IProblemDetailsWriter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace Microsoft.AspNetCore.Http; | ||
|
||
/// <summary> | ||
/// Defines a type that write a <see cref="Mvc.ProblemDetails"/> | ||
/// payload to the current <see cref="HttpContext.Response"/>. | ||
/// </summary> | ||
public interface IProblemDetailsWriter | ||
{ | ||
/// <summary> | ||
/// Write a <see cref="Mvc.ProblemDetails"/> response to the current context | ||
/// </summary> | ||
/// <param name="context">The <see cref="ProblemDetailsContext"/> associated with the current request/response.</param> | ||
ValueTask WriteAsync(ProblemDetailsContext context); | ||
|
||
/// <summary> | ||
/// Determines whether this instance can write a <see cref="Mvc.ProblemDetails"/> to the current context. | ||
/// </summary> | ||
/// <param name="context">The <see cref="ProblemDetailsContext"/> associated with the current request/response.</param> | ||
/// <returns>Flag that indicates if that the writer can write to the current <see cref="ProblemDetailsContext"/>.</returns> | ||
bool CanWrite(ProblemDetailsContext context); | ||
} |
File renamed without changes.
34 changes: 34 additions & 0 deletions
34
src/Http/Http.Abstractions/src/ProblemDetails/ProblemDetailsContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace Microsoft.AspNetCore.Http; | ||
|
||
/// <summary> | ||
/// Represent the current problem details context for the request. | ||
/// </summary> | ||
public sealed class ProblemDetailsContext | ||
{ | ||
private ProblemDetails? _problemDetails; | ||
|
||
/// <summary> | ||
/// The <see cref="HttpContext"/> associated with the current request being processed by the filter. | ||
/// </summary> | ||
public required HttpContext HttpContext { get; init; } | ||
|
||
/// <summary> | ||
/// A collection of additional arbitrary metadata associated with the current request endpoint. | ||
/// </summary> | ||
public EndpointMetadataCollection? AdditionalMetadata { get; init; } | ||
|
||
/// <summary> | ||
/// An instance of <see cref="ProblemDetails"/> that will be | ||
/// used during the response payload generation. | ||
/// </summary> | ||
public ProblemDetails ProblemDetails | ||
{ | ||
get => _problemDetails ??= new ProblemDetails(); | ||
init => _problemDetails = value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
src/Http/Http.Extensions/src/DefaultProblemDetailsWriter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
using System.Text.Json.Serialization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.Extensions.Options; | ||
using Microsoft.Net.Http.Headers; | ||
|
||
namespace Microsoft.AspNetCore.Http; | ||
|
||
internal sealed partial class DefaultProblemDetailsWriter : IProblemDetailsWriter | ||
{ | ||
private static readonly MediaTypeHeaderValue _jsonMediaType = new("application/json"); | ||
private static readonly MediaTypeHeaderValue _problemDetailsJsonMediaType = new("application/problem+json"); | ||
private readonly ProblemDetailsOptions _options; | ||
|
||
public DefaultProblemDetailsWriter(IOptions<ProblemDetailsOptions> options) | ||
{ | ||
_options = options.Value; | ||
} | ||
|
||
public bool CanWrite(ProblemDetailsContext context) | ||
{ | ||
var httpContext = context.HttpContext; | ||
var acceptHeader = httpContext.Request.Headers.Accept.GetList<MediaTypeHeaderValue>(); | ||
|
||
if (acceptHeader?.Any(h => _jsonMediaType.IsSubsetOf(h) || _problemDetailsJsonMediaType.IsSubsetOf(h)) == true) | ||
{ | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
[UnconditionalSuppressMessage("Trimming", "IL2026", | ||
Justification = "JSON serialization of ProblemDetails.Extensions might require types that cannot be statically analyzed and we need to fallback" + | ||
"to reflection-based. The ProblemDetailsConverter is marked as RequiresUnreferencedCode already.")] | ||
public ValueTask WriteAsync(ProblemDetailsContext context) | ||
{ | ||
var httpContext = context.HttpContext; | ||
ProblemDetailsDefaults.Apply(context.ProblemDetails, httpContext.Response.StatusCode); | ||
_options.CustomizeProblemDetails?.Invoke(context); | ||
|
||
if (context.ProblemDetails.Extensions is { Count: 0 }) | ||
{ | ||
// We can use the source generation in this case | ||
return new ValueTask(httpContext.Response.WriteAsJsonAsync( | ||
context.ProblemDetails, | ||
ProblemDetailsJsonContext.Default.ProblemDetails, | ||
contentType: "application/problem+json")); | ||
} | ||
|
||
return new ValueTask(httpContext.Response.WriteAsJsonAsync( | ||
context.ProblemDetails, | ||
options: null, | ||
contentType: "application/problem+json")); | ||
} | ||
|
||
[JsonSerializable(typeof(ProblemDetails))] | ||
internal sealed partial class ProblemDetailsJsonContext : JsonSerializerContext | ||
{ } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace Microsoft.AspNetCore.Http; | ||
|
||
/// <summary> | ||
/// Options for controlling the behavior of <see cref="IProblemDetailsService.WriteAsync(ProblemDetailsContext)"/> | ||
/// and similar methods. | ||
/// </summary> | ||
public class ProblemDetailsOptions | ||
{ | ||
/// <summary> | ||
/// The operation that customizes the current <see cref="Mvc.ProblemDetails"/> instance. | ||
/// </summary> | ||
public Action<ProblemDetailsContext>? CustomizeProblemDetails { get; set; } | ||
} |
Oops, something went wrong.