Skip to content

Commit c4f0846

Browse files
committed
Fixed ErrorObjectWriter
1 parent e662012 commit c4f0846

File tree

2 files changed

+123
-114
lines changed

2 files changed

+123
-114
lines changed

src/AspNetCore/WebApi/src/Asp.Versioning.Http/ErrorObjectWriter.cs

Lines changed: 110 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@ public virtual ValueTask WriteAsync( ProblemDetailsContext context )
3939
var obj = new ErrorObject( context.ProblemDetails );
4040

4141
OnBeforeWrite( context, ref obj );
42-
43-
return new( response.WriteAsJsonAsync( obj ) );
42+
#if NET8_0_OR_GREATER
43+
return new( response.WriteAsJsonAsync( obj, SourceGenerationContext.Default.ErrorObject ) );
44+
#else
45+
return new( response.WriteAsJsonAsync( obj);
46+
#endif
4447
}
4548

4649
/// <summary>
@@ -52,140 +55,133 @@ public virtual ValueTask WriteAsync( ProblemDetailsContext context )
5255
protected virtual void OnBeforeWrite( ProblemDetailsContext context, ref ErrorObject errorObject )
5356
{
5457
}
58+
}
5559

5660
#pragma warning disable CA1815 // Override equals and operator equals on value types
5761

62+
/// <summary>
63+
/// Represents an error object.
64+
/// </summary>
65+
public readonly struct ErrorObject
66+
{
67+
internal ErrorObject( ProblemDetails problemDetails ) =>
68+
Error = new( problemDetails );
69+
5870
/// <summary>
59-
/// Represents an error object.
71+
/// Gets the top-level error.
6072
/// </summary>
61-
protected readonly struct ErrorObject
73+
/// <value>The top-level error.</value>
74+
[JsonPropertyName( "error" )]
75+
public ErrorDetail Error { get; }
76+
}
77+
78+
/// <summary>
79+
/// Represents the error detail.
80+
/// </summary>
81+
public readonly struct ErrorDetail
82+
{
83+
private readonly ProblemDetails problemDetails;
84+
private readonly InnerError? innerError;
85+
private readonly Dictionary<string, object> extensions = [];
86+
87+
internal ErrorDetail( ProblemDetails problemDetails )
6288
{
63-
internal ErrorObject( ProblemDetails problemDetails ) =>
64-
Error = new( problemDetails );
65-
66-
/// <summary>
67-
/// Gets the top-level error.
68-
/// </summary>
69-
/// <value>The top-level error.</value>
70-
[JsonPropertyName( "error" )]
71-
public ErrorDetail Error { get; }
89+
this.problemDetails = problemDetails;
90+
innerError = string.IsNullOrEmpty( problemDetails.Detail ) ? default : new InnerError( problemDetails );
7291
}
7392

7493
/// <summary>
75-
/// Represents the error detail.
94+
/// Gets or sets one of a server-defined set of error codes.
7695
/// </summary>
77-
protected readonly struct ErrorDetail
96+
/// <value>A server-defined error code.</value>
97+
[JsonPropertyName( "code" )]
98+
[JsonIgnore( Condition = WhenWritingNull )]
99+
public string? Code
78100
{
79-
private readonly ProblemDetails problemDetails;
80-
private readonly InnerError? innerError;
81-
private readonly Dictionary<string, object> extensions = [];
82-
83-
internal ErrorDetail( ProblemDetails problemDetails )
84-
{
85-
this.problemDetails = problemDetails;
86-
innerError = string.IsNullOrEmpty( problemDetails.Detail ) ? default : new InnerError( problemDetails );
87-
}
88-
89-
/// <summary>
90-
/// Gets or sets one of a server-defined set of error codes.
91-
/// </summary>
92-
/// <value>A server-defined error code.</value>
93-
[JsonPropertyName( "code" )]
94-
[JsonIgnore( Condition = WhenWritingNull )]
95-
public string? Code
101+
get => problemDetails.Extensions.TryGetValue( "code", out var value ) &&
102+
value is string code ?
103+
code :
104+
default;
105+
set
96106
{
97-
get => problemDetails.Extensions.TryGetValue( "code", out var value ) &&
98-
value is string code ?
99-
code :
100-
default;
101-
set
107+
if ( value is null )
102108
{
103-
if ( value is null )
104-
{
105-
problemDetails.Extensions.Remove( "code" );
106-
}
107-
else
108-
{
109-
problemDetails.Extensions["code"] = value;
110-
}
109+
problemDetails.Extensions.Remove( "code" );
110+
}
111+
else
112+
{
113+
problemDetails.Extensions["code"] = value;
111114
}
112115
}
113-
114-
/// <summary>
115-
/// Gets or sets the error message.
116-
/// </summary>
117-
/// <value>A human-readable representation of the error.</value>
118-
[JsonPropertyName( "message" )]
119-
[JsonIgnore( Condition = WhenWritingNull )]
120-
public string? Message
121-
{
122-
get => problemDetails.Title;
123-
set => problemDetails.Title = value;
124-
}
125-
126-
/// <summary>
127-
/// Gets or sets the target of the error.
128-
/// </summary>
129-
/// <value>The error target of the error.</value>
130-
[JsonPropertyName( "target" )]
131-
[JsonIgnore( Condition = WhenWritingNull )]
132-
public string? Target
133-
{
134-
get => problemDetails.Title;
135-
set => problemDetails.Title = value;
136-
}
137-
138-
/// <summary>
139-
/// Gets an object containing more specific information than the current object about the error, if any.
140-
/// </summary>
141-
/// <value>The inner error or <c>null</c>.</value>
142-
[JsonPropertyName( "innerError" )]
143-
[JsonIgnore( Condition = WhenWritingNull )]
144-
public InnerError? InnerError => innerError;
145-
146-
/// <summary>
147-
/// Gets a collection of extension key/value pair members.
148-
/// </summary>
149-
/// <value>A collection of extension key/value pair members.</value>
150-
[JsonExtensionData]
151-
public IDictionary<string, object> Extensions => extensions;
152116
}
153117

154118
/// <summary>
155-
/// Represents an inner error.
119+
/// Gets or sets the error message.
156120
/// </summary>
157-
protected readonly struct InnerError
121+
/// <value>A human-readable representation of the error.</value>
122+
[JsonPropertyName( "message" )]
123+
[JsonIgnore( Condition = WhenWritingNull )]
124+
public string? Message
158125
{
159-
private readonly ProblemDetails problemDetails;
160-
private readonly Dictionary<string, object> extensions = [];
161-
162-
internal InnerError( ProblemDetails problemDetails ) =>
163-
this.problemDetails = problemDetails;
164-
165-
/// <summary>
166-
/// Gets or sets the inner error message.
167-
/// </summary>
168-
/// <value>The inner error message.</value>
169-
[JsonPropertyName( "message" )]
170-
[JsonIgnore( Condition = WhenWritingNull )]
171-
public string? Message
172-
{
173-
get => problemDetails.Detail;
174-
set => problemDetails.Detail = value;
175-
}
126+
get => problemDetails.Title;
127+
set => problemDetails.Title = value;
128+
}
176129

177-
/// <summary>
178-
/// Gets a collection of extension key/value pair members.
179-
/// </summary>
180-
/// <value>A collection of extension key/value pair members.</value>
181-
[JsonExtensionData]
182-
public IDictionary<string, object> Extensions => extensions;
130+
/// <summary>
131+
/// Gets or sets the target of the error.
132+
/// </summary>
133+
/// <value>The error target of the error.</value>
134+
[JsonPropertyName( "target" )]
135+
[JsonIgnore( Condition = WhenWritingNull )]
136+
public string? Target
137+
{
138+
get => problemDetails.Title;
139+
set => problemDetails.Title = value;
183140
}
141+
142+
/// <summary>
143+
/// Gets an object containing more specific information than the current object about the error, if any.
144+
/// </summary>
145+
/// <value>The inner error or <c>null</c>.</value>
146+
[JsonPropertyName( "innerError" )]
147+
[JsonIgnore( Condition = WhenWritingNull )]
148+
public InnerError? InnerError => innerError;
149+
150+
/// <summary>
151+
/// Gets a collection of extension key/value pair members.
152+
/// </summary>
153+
/// <value>A collection of extension key/value pair members.</value>
154+
[JsonExtensionData]
155+
public IDictionary<string, object> Extensions => extensions;
184156
}
185157

186-
#if NET8_0_OR_GREATER
187-
[JsonSerializable( typeof( ErrorObjectWriter.ErrorObject ) )]
188-
internal partial class SourceGenerationContext : JsonSerializerContext
158+
/// <summary>
159+
/// Represents an inner error.
160+
/// </summary>
161+
public struct InnerError
189162
{
190-
}
191-
#endif
163+
private readonly ProblemDetails problemDetails;
164+
private readonly Dictionary<string, object> extensions = [];
165+
166+
internal InnerError( ProblemDetails problemDetails ) =>
167+
this.problemDetails = problemDetails;
168+
169+
/// <summary>
170+
/// Gets or sets the inner error message.
171+
/// </summary>
172+
/// <value>The inner error message.</value>
173+
[JsonPropertyName( "message" )]
174+
[JsonIgnore( Condition = WhenWritingNull )]
175+
public string? Message
176+
{
177+
get => problemDetails.Detail;
178+
set => problemDetails.Detail = value;
179+
}
180+
181+
/// <summary>
182+
/// Gets a collection of extension key/value pair members.
183+
/// </summary>
184+
/// <value>A collection of extension key/value pair members.</value>
185+
[JsonExtensionData]
186+
public IDictionary<string, object> Extensions => extensions;
187+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
3+
namespace Asp.Versioning;
4+
using System.Text.Json.Serialization;
5+
#if NET8_0_OR_GREATER
6+
[JsonSerializable( typeof( ErrorObject ) )]
7+
[JsonSerializable( typeof( ErrorDetail ) )]
8+
[JsonSerializable( typeof( InnerError ) )]
9+
internal sealed partial class SourceGenerationContext : JsonSerializerContext
10+
{
11+
}
12+
13+
#endif

0 commit comments

Comments
 (0)