1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
+ using System . Diagnostics ;
4
5
using System . Text . Json ;
6
+ using System . Text . Json . Serialization ;
7
+ using System . Text . Json . Serialization . Metadata ;
5
8
using Microsoft . AspNetCore . Mvc ;
6
9
using Microsoft . Extensions . DependencyInjection ;
7
- using Microsoft . Extensions . Logging . Abstractions ;
8
10
using Microsoft . Extensions . Logging ;
11
+ using Microsoft . Extensions . Logging . Abstractions ;
9
12
using Microsoft . Extensions . Options ;
10
- using System . Text . Json . Serialization . Metadata ;
11
- using Microsoft . AspNetCore . Http . Json ;
12
- using System . Text . Json . Serialization ;
13
- using Microsoft . CodeAnalysis ;
14
13
using JsonOptions = Microsoft . AspNetCore . Http . Json . JsonOptions ;
15
14
16
15
namespace Microsoft . AspNetCore . Http . Extensions . Tests ;
@@ -26,6 +25,8 @@ public async Task WriteAsync_Works()
26
25
var writer = GetWriter ( ) ;
27
26
var stream = new MemoryStream ( ) ;
28
27
var context = CreateContext ( stream ) ;
28
+
29
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
29
30
var expectedProblem = new ProblemDetails ( )
30
31
{
31
32
Detail = "Custom Bad Request" ,
@@ -52,6 +53,7 @@ public async Task WriteAsync_Works()
52
53
Assert . Equal ( expectedProblem . Title , problemDetails . Title ) ;
53
54
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
54
55
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
56
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
55
57
}
56
58
57
59
[ Fact ]
@@ -61,6 +63,7 @@ public async Task WriteAsync_Works_ProperCasing()
61
63
var writer = GetWriter ( ) ;
62
64
var stream = new MemoryStream ( ) ;
63
65
var context = CreateContext ( stream ) ;
66
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
64
67
var expectedProblem = new ProblemDetails ( )
65
68
{
66
69
Detail = "Custom Bad Request" ,
@@ -82,7 +85,7 @@ public async Task WriteAsync_Works_ProperCasing()
82
85
//Assert
83
86
stream . Position = 0 ;
84
87
var result = await JsonSerializer . DeserializeAsync < Dictionary < string , object > > ( stream , JsonSerializerOptions . Default ) ;
85
- Assert . Equal ( result . Keys , new ( new ( ) { { "type" , 0 } , { "title" , 1 } , { "status" , 2 } , { "detail" , 3 } , { "instance" , 4 } , { "extensionKey" , 5 } } ) ) ;
88
+ Assert . Equal ( result . Keys , new ( new ( ) { { "type" , 0 } , { "title" , 1 } , { "status" , 2 } , { "detail" , 3 } , { "instance" , 4 } , { "extensionKey" , 5 } , { "traceId" , expectedTraceId } } ) ) ;
86
89
}
87
90
88
91
[ Fact ]
@@ -92,6 +95,7 @@ public async Task WriteAsync_Works_ProperCasing_ValidationProblemDetails()
92
95
var writer = GetWriter ( ) ;
93
96
var stream = new MemoryStream ( ) ;
94
97
var context = CreateContext ( stream ) ;
98
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
95
99
var expectedProblem = new ValidationProblemDetails ( )
96
100
{
97
101
Detail = "Custom Bad Request" ,
@@ -113,7 +117,7 @@ public async Task WriteAsync_Works_ProperCasing_ValidationProblemDetails()
113
117
//Assert
114
118
stream . Position = 0 ;
115
119
var result = await JsonSerializer . DeserializeAsync < Dictionary < string , object > > ( stream , JsonSerializerOptions . Default ) ;
116
- Assert . Equal ( result . Keys , new ( new ( ) { { "type" , 0 } , { "title" , 1 } , { "status" , 2 } , { "detail" , 3 } , { "instance" , 4 } , { "errors" , 5 } } ) ) ;
120
+ Assert . Equal ( result . Keys , new ( new ( ) { { "type" , 0 } , { "title" , 1 } , { "status" , 2 } , { "detail" , 3 } , { "instance" , 4 } , { "errors" , 5 } , { "traceId" , expectedTraceId } } ) ) ;
117
121
}
118
122
119
123
[ Fact ]
@@ -125,6 +129,7 @@ public async Task WriteAsync_Works_WhenReplacingProblemDetailsUsingSetter()
125
129
var context = CreateContext ( stream ) ;
126
130
var originalProblemDetails = new ProblemDetails ( ) ;
127
131
132
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
128
133
var expectedProblem = new ProblemDetails ( )
129
134
{
130
135
Detail = "Custom Bad Request" ,
@@ -153,6 +158,7 @@ public async Task WriteAsync_Works_WhenReplacingProblemDetailsUsingSetter()
153
158
Assert . Equal ( expectedProblem . Title , problemDetails . Title ) ;
154
159
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
155
160
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
161
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
156
162
}
157
163
158
164
[ Fact ]
@@ -165,6 +171,7 @@ public async Task WriteAsync_Works_WithJsonContext()
165
171
var writer = GetWriter ( jsonOptions : options ) ;
166
172
var stream = new MemoryStream ( ) ;
167
173
var context = CreateContext ( stream ) ;
174
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
168
175
var expectedProblem = new ProblemDetails ( )
169
176
{
170
177
Detail = "Custom Bad Request" ,
@@ -191,6 +198,7 @@ public async Task WriteAsync_Works_WithJsonContext()
191
198
Assert . Equal ( expectedProblem . Title , problemDetails . Title ) ;
192
199
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
193
200
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
201
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
194
202
}
195
203
196
204
[ Fact ]
@@ -203,6 +211,7 @@ public async Task WriteAsync_Works_WithMultipleJsonContext()
203
211
var writer = GetWriter ( jsonOptions : options ) ;
204
212
var stream = new MemoryStream ( ) ;
205
213
var context = CreateContext ( stream ) ;
214
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
206
215
var expectedProblem = new ProblemDetails ( )
207
216
{
208
217
Detail = "Custom Bad Request" ,
@@ -229,6 +238,7 @@ public async Task WriteAsync_Works_WithMultipleJsonContext()
229
238
Assert . Equal ( expectedProblem . Title , problemDetails . Title ) ;
230
239
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
231
240
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
241
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
232
242
}
233
243
234
244
[ Fact ]
@@ -238,6 +248,7 @@ public async Task WriteAsync_Works_WithHttpValidationProblemDetails()
238
248
var writer = GetWriter ( ) ;
239
249
var stream = new MemoryStream ( ) ;
240
250
var context = CreateContext ( stream ) ;
251
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
241
252
var expectedProblem = new HttpValidationProblemDetails ( )
242
253
{
243
254
Detail = "Custom Bad Request" ,
@@ -267,6 +278,7 @@ public async Task WriteAsync_Works_WithHttpValidationProblemDetails()
267
278
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
268
279
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
269
280
Assert . Equal ( expectedProblem . Errors , problemDetails . Errors ) ;
281
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
270
282
}
271
283
272
284
[ Fact ]
@@ -279,6 +291,7 @@ public async Task WriteAsync_Works_WithHttpValidationProblemDetails_AndJsonConte
279
291
var writer = GetWriter ( jsonOptions : options ) ;
280
292
var stream = new MemoryStream ( ) ;
281
293
var context = CreateContext ( stream ) ;
294
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
282
295
var expectedProblem = new HttpValidationProblemDetails ( )
283
296
{
284
297
Detail = "Custom Bad Request" ,
@@ -308,6 +321,7 @@ public async Task WriteAsync_Works_WithHttpValidationProblemDetails_AndJsonConte
308
321
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
309
322
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
310
323
Assert . Equal ( expectedProblem . Errors , problemDetails . Errors ) ;
324
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
311
325
}
312
326
313
327
[ Fact ]
@@ -320,6 +334,7 @@ public async Task WriteAsync_Works_WithCustomDerivedProblemDetails()
320
334
var writer = GetWriter ( jsonOptions : options ) ;
321
335
var stream = new MemoryStream ( ) ;
322
336
var context = CreateContext ( stream ) ;
337
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
323
338
var expectedProblem = new CustomProblemDetails ( )
324
339
{
325
340
Detail = "Custom Bad Request" ,
@@ -349,6 +364,7 @@ public async Task WriteAsync_Works_WithCustomDerivedProblemDetails()
349
364
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
350
365
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
351
366
Assert . Equal ( expectedProblem . ExtraProperty , problemDetails . ExtraProperty ) ;
367
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
352
368
}
353
369
354
370
[ Fact ]
@@ -361,6 +377,7 @@ public async Task WriteAsync_Works_WithCustomDerivedProblemDetails_AndJsonContex
361
377
var writer = GetWriter ( jsonOptions : options ) ;
362
378
var stream = new MemoryStream ( ) ;
363
379
var context = CreateContext ( stream ) ;
380
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
364
381
var expectedProblem = new CustomProblemDetails ( )
365
382
{
366
383
Detail = "Custom Bad Request" ,
@@ -390,6 +407,7 @@ public async Task WriteAsync_Works_WithCustomDerivedProblemDetails_AndJsonContex
390
407
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
391
408
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
392
409
Assert . Equal ( expectedProblem . ExtraProperty , problemDetails . ExtraProperty ) ;
410
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
393
411
}
394
412
395
413
[ Fact ]
@@ -402,6 +420,7 @@ public async Task WriteAsync_Works_WithCustomDerivedProblemDetails_AndMultipleJs
402
420
var writer = GetWriter ( jsonOptions : options ) ;
403
421
var stream = new MemoryStream ( ) ;
404
422
var context = CreateContext ( stream ) ;
423
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
405
424
var expectedProblem = new CustomProblemDetails ( )
406
425
{
407
426
Detail = "Custom Bad Request" ,
@@ -431,6 +450,7 @@ public async Task WriteAsync_Works_WithCustomDerivedProblemDetails_AndMultipleJs
431
450
Assert . Equal ( expectedProblem . Detail , problemDetails . Detail ) ;
432
451
Assert . Equal ( expectedProblem . Instance , problemDetails . Instance ) ;
433
452
Assert . Equal ( expectedProblem . ExtraProperty , problemDetails . ExtraProperty ) ;
453
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
434
454
}
435
455
436
456
[ Fact ]
@@ -441,6 +461,7 @@ public async Task WriteAsync_AddExtensions()
441
461
var stream = new MemoryStream ( ) ;
442
462
var context = CreateContext ( stream ) ;
443
463
var expectedProblem = new ProblemDetails ( ) ;
464
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
444
465
expectedProblem . Extensions [ "Extension1" ] = "Extension1-Value" ;
445
466
expectedProblem . Extensions [ "Extension2" ] = "Extension2-Value" ;
446
467
@@ -467,6 +488,11 @@ public async Task WriteAsync_AddExtensions()
467
488
{
468
489
Assert . Equal ( "Extension2" , extension . Key ) ;
469
490
Assert . Equal ( "Extension2-Value" , extension . Value . ToString ( ) ) ;
491
+ } ,
492
+ ( extension ) =>
493
+ {
494
+ Assert . Equal ( "traceId" , extension . Key ) ;
495
+ Assert . Equal ( expectedTraceId , extension . Value . ToString ( ) ) ;
470
496
} ) ;
471
497
}
472
498
@@ -482,6 +508,7 @@ public async Task WriteAsync_AddExtensions_WithJsonContext()
482
508
var context = CreateContext ( stream ) ;
483
509
var expectedProblem = new ProblemDetails ( ) ;
484
510
var customExtensionData = new CustomExtensionData ( "test" ) ;
511
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
485
512
expectedProblem . Extensions [ "Extension" ] = customExtensionData ;
486
513
487
514
var problemDetailsContext = new ProblemDetailsContext ( )
@@ -507,6 +534,11 @@ public async Task WriteAsync_AddExtensions_WithJsonContext()
507
534
var value = Assert . IsType < JsonElement > ( extension . Value ) ;
508
535
509
536
Assert . Equal ( expectedExtension . GetProperty ( "data" ) . GetString ( ) , value . GetProperty ( "data" ) . GetString ( ) ) ;
537
+ } ,
538
+ ( extension ) =>
539
+ {
540
+ Assert . Equal ( "traceId" , extension . Key ) ;
541
+ Assert . Equal ( expectedTraceId , extension . Value . ToString ( ) ) ;
510
542
} ) ;
511
543
}
512
544
@@ -517,6 +549,7 @@ public async Task WriteAsync_Applies_Defaults()
517
549
var writer = GetWriter ( ) ;
518
550
var stream = new MemoryStream ( ) ;
519
551
var context = CreateContext ( stream , StatusCodes . Status500InternalServerError ) ;
552
+ var expectedTraceId = Activity . Current ? . Id ?? context . TraceIdentifier ;
520
553
521
554
//Act
522
555
await writer . WriteAsync ( new ProblemDetailsContext ( ) { HttpContext = context } ) ;
@@ -528,19 +561,22 @@ public async Task WriteAsync_Applies_Defaults()
528
561
Assert . Equal ( StatusCodes . Status500InternalServerError , problemDetails . Status ) ;
529
562
Assert . Equal ( "https://tools.ietf.org/html/rfc9110#section-15.6.1" , problemDetails . Type ) ;
530
563
Assert . Equal ( "An error occurred while processing your request." , problemDetails . Title ) ;
564
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
531
565
}
532
566
533
567
[ Fact ]
534
568
public async Task WriteAsync_Applies_CustomConfiguration ( )
535
569
{
536
570
// Arrange
571
+ const string expectedTraceId = "new-traceId-Value" ;
537
572
var options = new ProblemDetailsOptions ( )
538
573
{
539
574
CustomizeProblemDetails = ( context ) =>
540
575
{
541
576
context . ProblemDetails . Status = StatusCodes . Status406NotAcceptable ;
542
577
context . ProblemDetails . Title = "Custom Title" ;
543
578
context . ProblemDetails . Extensions [ "new-extension" ] = new { TraceId = Guid . NewGuid ( ) } ;
579
+ context . ProblemDetails . Extensions [ "traceId" ] = expectedTraceId ;
544
580
}
545
581
} ;
546
582
var writer = GetWriter ( options ) ;
@@ -562,6 +598,7 @@ await writer.WriteAsync(new ProblemDetailsContext()
562
598
Assert . Equal ( "https://tools.ietf.org/html/rfc9110#section-15.5.1" , problemDetails . Type ) ;
563
599
Assert . Equal ( "Custom Title" , problemDetails . Title ) ;
564
600
Assert . Contains ( "new-extension" , problemDetails . Extensions ) ;
601
+ Assert . Equal ( expectedTraceId , problemDetails . Extensions [ "traceId" ] . ToString ( ) ) ;
565
602
}
566
603
567
604
[ Theory ]
0 commit comments