Skip to content

Commit 5105d13

Browse files
Merge branch 'main' into seo/73003-type-checking-type-casting-csharp
2 parents 991cfdd + a0e83b8 commit 5105d13

80 files changed

Lines changed: 1552 additions & 584 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎authorization-dotnet/DecodeJwt/App/App.csproj‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>
99
<ItemGroup>
10-
<PackageReference Include="IdentityModel" Version="6.2.0"/>
11-
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3"/>
10+
<PackageReference Include="Duende.IdentityModel" Version="8.1.0"/>
11+
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.23.0"/>
1212
</ItemGroup>
1313

1414
</Project>

‎authorization-dotnet/DecodeJwt/App/JwtUtils.cs‎

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
using System.IdentityModel.Tokens.Jwt;
2-
using IdentityModel.Client;
1+
using System.Buffers.Text;
2+
using System.Text;
3+
using Duende.IdentityModel.Client;
4+
using Microsoft.IdentityModel.JsonWebTokens;
35

46
namespace App;
57

@@ -20,25 +22,25 @@ public static class JwtUtils
2022
{ Address = discoveryDocument.TokenEndpoint, ClientId = "m2m", ClientSecret = "secret", Scope = "api" });
2123
}
2224

23-
if (tokenResponse.IsError)
25+
if (tokenResponse.IsError)
2426
{
2527
throw new Exception(tokenResponse.Error);
2628
}
27-
29+
2830
return tokenResponse.AccessToken;
2931
}
3032

31-
public static JwtSecurityToken ConvertJwtStringToJwtSecurityToken(string? jwt)
33+
public static JsonWebToken ConvertJwtStringToJsonWebToken(string jwt)
3234
{
33-
var handler = new JwtSecurityTokenHandler();
34-
var token = handler.ReadJwtToken(jwt);
35-
35+
var handler = new JsonWebTokenHandler();
36+
var token = handler.ReadJsonWebToken(jwt);
37+
3638
return token;
3739
}
3840

39-
public static DecodedToken DecodeJwt(JwtSecurityToken token)
41+
public static DecodedToken DecodeJwt(JsonWebToken token)
4042
{
41-
var keyId = token.Header.Kid;
43+
var keyId = token.Kid;
4244
var audience = token.Audiences.ToList();
4345
var claims = token.Claims.Select(claim => (claim.Type, claim.Value)).ToList();
4446

@@ -48,12 +50,21 @@ public static DecodedToken DecodeJwt(JwtSecurityToken token)
4850
audience,
4951
claims,
5052
token.ValidTo,
51-
token.SignatureAlgorithm,
52-
token.RawData,
53+
token.Alg,
54+
token.EncodedToken,
5355
token.Subject,
5456
token.ValidFrom,
5557
token.EncodedHeader,
5658
token.EncodedPayload
5759
);
5860
}
61+
62+
public static (string Header, string Payload) DecodeJwtWithoutLibrary(string jwt)
63+
{
64+
var parts = jwt.Split('.');
65+
var header = Encoding.UTF8.GetString(Base64Url.DecodeFromChars(parts[0]));
66+
var payload = Encoding.UTF8.GetString(Base64Url.DecodeFromChars(parts[1]));
67+
68+
return (header, payload);
69+
}
5970
}
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
using App;
22

3-
var accessToken = await JwtUtils.GetAccessTokenFromDuendeIdentityServerAsync();
3+
var accessToken = await JwtUtils.GetAccessTokenFromDuendeIdentityServerAsync()
4+
?? throw new InvalidOperationException("The token endpoint returned no access token.");
45
Console.WriteLine(accessToken);
5-
var jwt = JwtUtils.ConvertJwtStringToJwtSecurityToken(accessToken);
6+
var jwt = JwtUtils.ConvertJwtStringToJsonWebToken(accessToken);
67
Console.WriteLine(jwt);
78
var jwtData = JwtUtils.DecodeJwt(jwt);
89
Console.WriteLine(jwtData);
10+
var (header, payload) = JwtUtils.DecodeJwtWithoutLibrary(accessToken);
11+
Console.WriteLine(header);
12+
Console.WriteLine(payload);

‎authorization-dotnet/DecodeJwt/Tests/DecodeJwtTest.cs‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ namespace Tests;
33
public class DecodeJwtTest
44
{
55
[Fact]
6-
public async Task WhenJwtIsRetrievedFromServer_ThenItShouldNotBeNull()
6+
public async Task WhenJwtIsRetrievedFromServer_ThenItShouldNotBeNull_Live()
77
{
88
var jwt = await JwtUtils.GetAccessTokenFromDuendeIdentityServerAsync();
99

@@ -14,11 +14,21 @@ public async Task WhenJwtIsRetrievedFromServer_ThenItShouldNotBeNull()
1414
[ClassData(typeof(JwtTestData))]
1515
public void WhenJwtIsValid_ThenItShouldDecode(string token)
1616
{
17-
var jwt = JwtUtils.ConvertJwtStringToJwtSecurityToken(token);
17+
var jwt = JwtUtils.ConvertJwtStringToJsonWebToken(token);
1818
var jwtData = JwtUtils.DecodeJwt(jwt);
1919

2020
Assert.NotNull(jwtData.Issuer);
2121
Assert.NotEmpty(jwtData.Audience);
2222
Assert.NotEmpty(jwtData.Claims);
2323
}
24-
}
24+
25+
[Theory]
26+
[ClassData(typeof(JwtTestData))]
27+
public void WhenJwtIsDecodedWithoutLibrary_ThenHeaderAndPayloadAreJson(string token)
28+
{
29+
var (header, payload) = JwtUtils.DecodeJwtWithoutLibrary(token);
30+
31+
Assert.Contains("\"alg\":\"RS256\"", header);
32+
Assert.Contains("\"iss\":\"https://demo.duendesoftware.com\"", payload);
33+
}
34+
}

‎authorization-dotnet/DecodeJwt/Tests/Tests.csproj‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77

@@ -10,13 +10,13 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
14-
<PackageReference Include="xunit" Version="2.6.2"/>
15-
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.11.0"/>
14+
<PackageReference Include="xunit" Version="2.9.3"/>
15+
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.1">
1616
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1717
<PrivateAssets>all</PrivateAssets>
1818
</PackageReference>
19-
<PackageReference Include="coverlet.collector" Version="6.0.0">
19+
<PackageReference Include="coverlet.collector" Version="10.1.0">
2020
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2121
<PrivateAssets>all</PrivateAssets>
2222
</PackageReference>
Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
using BenchmarkDotNet.Attributes;
22
using PopulateArrayWithTheSameValue;
33

4-
namespace BenchmarkRunner
4+
namespace BenchmarkRunner;
5+
6+
[MemoryDiagnoser]
7+
public class ArrayPopulatorBenchmark
58
{
6-
public class ArrayPopulatorBenchmark
9+
private static readonly ArrayPopulator _arrayPopulator = new();
10+
private readonly Article[] _benchMarkArray = new Article[100_000];
11+
private readonly Article _benchmarkArticle = new()
712
{
8-
private static readonly ArrayPopulator _arrayPopulator = new();
9-
private readonly Article[] _benchMarkArray = new Article[1000 * 100];
10-
private readonly Article _benchmarkArticle = new()
11-
{
12-
Title = "How to Copy Array Elements to New Array in C#",
13-
LastUpdate = new DateTime(2022, 01, 31)
14-
};
13+
Title = "How to Copy Array Elements to New Array in C#",
14+
LastUpdate = new DateTime(2022, 01, 31)
15+
};
1516

16-
[Benchmark]
17-
public void FillArray()
18-
{
19-
_arrayPopulator.FillArray(_benchMarkArray, _benchmarkArticle);
20-
}
17+
[Benchmark]
18+
public void FillArray()
19+
{
20+
_arrayPopulator.FillArray(_benchMarkArray, _benchmarkArticle);
21+
}
2122

22-
[Benchmark]
23-
public void EnumerableRepeat()
24-
{
25-
_arrayPopulator.EnumerableRepeat(_benchmarkArticle, _benchMarkArray.Length);
26-
}
23+
[Benchmark]
24+
public void EnumerableRepeat()
25+
{
26+
_arrayPopulator.EnumerableRepeat(_benchmarkArticle, _benchMarkArray.Length);
27+
}
2728

28-
[Benchmark]
29-
public void ForStatement()
30-
{
31-
_arrayPopulator.ForStatement(_benchMarkArray, _benchmarkArticle);
32-
}
29+
[Benchmark]
30+
public void ForStatement()
31+
{
32+
_arrayPopulator.ForStatement(_benchMarkArray, _benchmarkArticle);
33+
}
3334

34-
[Benchmark]
35-
public void ForStatementShallowCopy()
36-
{
37-
_arrayPopulator.ForStatementShallowCopy(_benchMarkArray, _benchmarkArticle);
38-
}
35+
[Benchmark]
36+
public void ForStatementShallowCopy()
37+
{
38+
_arrayPopulator.ForStatementShallowCopy(_benchMarkArray, _benchmarkArticle);
3939
}
4040
}

‎collections-arrays/PopulateArrayWithTheSameValue/BenchmarkRunner/BenchmarkRunner.csproj‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
11+
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
1212
</ItemGroup>
1313

1414
<ItemGroup>
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
namespace BenchmarkRunner
1+
using BenchmarkDotNet.Running;
2+
3+
namespace BenchmarkRunner;
4+
5+
internal class Program
26
{
3-
internal class Program
7+
static void Main(string[] args)
48
{
5-
static void Main(string[] args)
6-
{
7-
BenchmarkDotNet.Running.BenchmarkRunner.Run<ArrayPopulatorBenchmark>();
8-
}
9+
BenchmarkDotNet.Running.BenchmarkRunner.Run<ArrayPopulatorBenchmark>(args: args);
910
}
10-
}
11+
}
Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,74 @@
1-
namespace PopulateArrayWithTheSameValue
1+
namespace PopulateArrayWithTheSameValue;
2+
3+
public class ArrayPopulator
24
{
3-
public class ArrayPopulator
5+
public Article[] InstantiateArrayManually()
46
{
5-
public Article[] InstantiateArrayManually()
6-
{
7-
return new Article[]
8-
{
9-
new Article { Title = "How to Copy Array Elements to New Array in C#", LastUpdate = new DateTime(2022, 01, 31)},
10-
new Article { Title = "How to Copy Array Elements to New Array in C#", LastUpdate = new DateTime(2022, 01, 31)},
11-
};
12-
}
7+
return
8+
[
9+
new() { Title = "How to Copy Array Elements to New Array in C#", LastUpdate = new DateTime(2022, 01, 31) },
10+
new() { Title = "How to Copy Array Elements to New Array in C#", LastUpdate = new DateTime(2022, 01, 31) }
11+
];
12+
}
1313

14-
public Article[] FillArray(Article[] array, Article value)
15-
{
16-
Array.Fill(array, value);
14+
public Article[] FillArray(Article[] array, Article value)
15+
{
16+
Array.Fill(array, value);
1717

18-
return array;
19-
}
20-
21-
public Article[] FillArrayWithAditionalParameter(Article[] array, Article value)
22-
{
23-
Array.Fill(array, value, 5, 2);
18+
return array;
19+
}
2420

25-
return array;
26-
}
21+
public Article[] FillArrayWithAditionalParameter(Article[] array, Article value)
22+
{
23+
Array.Fill(array, value, 5, 2);
2724

28-
public Article[] EnumerableRepeat(Article value, int count)
29-
{
30-
var articles = Enumerable.Repeat(value, count).ToArray();
25+
return array;
26+
}
3127

32-
return articles;
33-
}
28+
public Article[] FillWithSpan(Article article)
29+
{
30+
var articles = new Article[10];
31+
articles.AsSpan().Fill(article);
32+
articles.AsSpan(5, 2).Fill(article);
3433

35-
public Article[] ForStatement(Article[] articles, Article article)
34+
return articles;
35+
}
36+
37+
public Article[] FillRangeWithSpan(Article[] articles, Article article)
38+
{
39+
articles.AsSpan(5, 2).Fill(article);
40+
41+
return articles;
42+
}
43+
44+
public Article[] EnumerableRepeat(Article value, int count)
45+
{
46+
var articles = Enumerable.Repeat(value, count).ToArray();
47+
48+
return articles;
49+
}
50+
51+
public Article[] ForStatement(Article[] articles, Article article)
52+
{
53+
for (int index = 0; index < articles.Length; index++)
3654
{
37-
for (int index = 0; index < articles.Length; index++)
55+
articles[index] = new Article
3856
{
39-
articles[index] = new Article
40-
{
41-
Title = article.Title,
42-
LastUpdate = article.LastUpdate
43-
};
44-
}
45-
46-
return articles;
57+
Title = article.Title,
58+
LastUpdate = article.LastUpdate
59+
};
4760
}
4861

49-
public Article[] ForStatementShallowCopy(Article[] articles, Article article)
50-
{
51-
for (int index = 0; index < articles.Length; index++)
52-
{
53-
articles[index] = article;
54-
}
62+
return articles;
63+
}
5564

56-
return articles;
65+
public Article[] ForStatementShallowCopy(Article[] articles, Article article)
66+
{
67+
for (int index = 0; index < articles.Length; index++)
68+
{
69+
articles[index] = article;
5770
}
71+
72+
return articles;
5873
}
5974
}

‎collections-arrays/PopulateArrayWithTheSameValue/PopulateArrayWithTheSameValue/PopulateArrayWithTheSameValue.csproj‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
6-
<LangVersion>10</LangVersion>
5+
<TargetFramework>net10.0</TargetFramework>
76
<ImplicitUsings>enable</ImplicitUsings>
87
<Nullable>enable</Nullable>
98
</PropertyGroup>

0 commit comments

Comments
 (0)