Skip to content

Commit d01fb45

Browse files
QRCoder: .NET 10, QRCoder 1.8.0, SVG renderer, thread-safe QrCodesDb
Retarget both projects to net10.0 and bump QRCoder to 1.8.0 and the test packages. GeneratePng renders black on white again; the coloured call moves to GeneratePngBranded. Add GenerateQRCodeSvg with SvgQRCode. QrCodesDb uses ConcurrentDictionary with TryAdd. Drop the stray semicolon on @model, switch to MapStaticAssets, and add PNG and SVG output tests.
1 parent 2d403b5 commit d01fb45

7 files changed

Lines changed: 90 additions & 26 deletions

File tree

‎dotnet-client-libraries/QRCoder/QRCodeGeneratorWebSample/Controllers/HomeController.cs‎

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ public IActionResult Index()
1414
var qrCodes = new Dictionary<string, string>
1515
{
1616
{ "Basic String", GenerateQRCodeString() },
17+
{ "SVG", GenerateQRCodeSvg() },
1718
{ "URL", GenerateQRCodeURL() },
1819
{ "Phone Number", GenerateQRCodePhoneNumber() },
19-
{ "Custom", GenerateQRCodeCustom() }
20+
{ "Custom", GenerateQRCodeCustom() },
21+
{ "Branded", GenerateQRCodeBranded() }
2022
};
2123

2224
var model = new HomeModel(qrCodes);
@@ -25,7 +27,7 @@ public IActionResult Index()
2527
}
2628

2729
private string GenerateQRCodeCustom()
28-
{
30+
{
2931
const string key = "Custom";
3032

3133
var raw = db.Get(key);
@@ -46,6 +48,15 @@ private string GenerateQRCodeString()
4648
return GeneratePng(qrCodeData);
4749
}
4850

51+
private string GenerateQRCodeSvg()
52+
{
53+
var qrCodeData = qrGenerator.CreateQrCode("Hello CodeMaze readers", QRCodeGenerator.ECCLevel.Q);
54+
using var qrCode = new SvgQRCode(qrCodeData);
55+
var svg = qrCode.GetGraphic(20);
56+
57+
return $"data:image/svg+xml,{Uri.EscapeDataString(svg)}";
58+
}
59+
4960
private string GenerateQRCodeURL()
5061
{
5162
var qrCodeData = qrGenerator.CreateQrCode(new Url("https://www.code-maze.com"));
@@ -60,7 +71,22 @@ private string GenerateQRCodePhoneNumber()
6071
return GeneratePng(qrCodeData);
6172
}
6273

74+
private string GenerateQRCodeBranded()
75+
{
76+
var qrCodeData = qrGenerator.CreateQrCode("Hello CodeMaze readers", QRCodeGenerator.ECCLevel.Q);
77+
78+
return GeneratePngBranded(qrCodeData);
79+
}
80+
6381
private static string GeneratePng(QRCodeData data)
82+
{
83+
using var qrCode = new PngByteQRCode(data);
84+
var qrCodeImage = qrCode.GetGraphic(20);
85+
86+
return $"data:image/png;base64,{Convert.ToBase64String(qrCodeImage)}";
87+
}
88+
89+
private static string GeneratePngBranded(QRCodeData data)
6490
{
6591
using var qrCode = new PngByteQRCode(data);
6692
var qrCodeImage = qrCode.GetGraphic(20, [255, 0, 0], [0, 0, 139]);

‎dotnet-client-libraries/QRCoder/QRCodeGeneratorWebSample/Program.cs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313
{
1414
app.UseExceptionHandler("/Home/Error");
1515
}
16-
app.UseStaticFiles();
1716

1817
app.UseRouting();
1918

2019
app.UseAuthorization();
2120

21+
app.MapStaticAssets();
22+
2223
app.MapControllerRoute(
2324
name: "default",
24-
pattern: "{controller=Home}/{action=Index}/{id?}");
25+
pattern: "{controller=Home}/{action=Index}/{id?}")
26+
.WithStaticAssets();
2527

2628
app.Run();
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

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

99
<ItemGroup>
10-
<PackageReference Include="QRCoder" Version="1.4.1" />
10+
<PackageReference Include="QRCoder" Version="1.8.0" />
1111
</ItemGroup>
1212

1313
</Project>

‎dotnet-client-libraries/QRCoder/QRCodeGeneratorWebSample/QrCodesDb.cs‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
using QRCoder;
1+
using System.Collections.Concurrent;
2+
using QRCoder;
23

34
namespace QRCodeGeneratorWebSample;
45

56
public class QrCodesDb
67
{
7-
private readonly Dictionary<string, byte[]> _qrCodes = [];
8+
private readonly ConcurrentDictionary<string, byte[]> _qrCodes = new();
89

910
public void Add(string key, QRCodeData data)
1011
{
11-
if (!_qrCodes.ContainsKey(key))
12-
{
13-
_qrCodes.Add(key, data.GetRawData(QRCodeData.Compression.Uncompressed));
14-
}
12+
_qrCodes.TryAdd(key, data.GetRawData(QRCodeData.Compression.Uncompressed));
1513
}
1614

1715
public byte[]? Get(string key)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
@model HomeModel;
1+
@model HomeModel
22

33
<div class="text-center">
44
@foreach (var qr in Model.QRCodes)
55
{
66
<hr/>
77
<h2>@qr.Key</h2>
88
<img width="250px" src="@qr.Value" />
9-
}
9+
}
1010
</div>

‎dotnet-client-libraries/QRCoder/Tests/QRCodeGeneratorWebSampleUnitTest.cs‎

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,65 @@
66
namespace Tests;
77
public class QRCodeGeneratorWebSampleUnitTest
88
{
9-
[Fact]
10-
public void GivenARequest_WhenCallingIndex_ThenTheControllerRendersAViewWithQrCodes()
9+
private static HomeModel RenderIndex()
1110
{
12-
// Arrange.
1311
var db = new QrCodesDb();
1412
var controller = new HomeController(db);
1513

16-
// Act.
1714
var viewResult = controller.Index() as ViewResult;
1815

19-
// Assert.
2016
Assert.NotNull(viewResult);
2117
var model = viewResult.Model as HomeModel;
2218
Assert.NotNull(model);
19+
20+
return model;
21+
}
22+
23+
[Fact]
24+
public void GivenARequest_WhenCallingIndex_ThenTheControllerRendersAViewWithQrCodes()
25+
{
26+
// Act.
27+
var model = RenderIndex();
28+
29+
// Assert.
2330
Assert.NotNull(model.QRCodes);
2431
Assert.NotEmpty(model.QRCodes);
25-
foreach (var qrCode in from expectedKey in new[] { "Basic String", "URL", "Phone Number", "Custom" }
32+
foreach (var qrCode in from expectedKey in new[] { "Basic String", "SVG", "URL", "Phone Number", "Custom", "Branded" }
2633
let qrCode = model.QRCodes[expectedKey]
2734
select qrCode)
2835
{
2936
Assert.NotNull(qrCode);
3037
}
3138
}
32-
}
39+
40+
[Fact]
41+
public void GivenARequest_WhenCallingIndex_ThenThePngRendererProducesARealPng()
42+
{
43+
// Arrange.
44+
const string prefix = "data:image/png;base64,";
45+
46+
// Act.
47+
var dataUri = RenderIndex().QRCodes["Basic String"];
48+
49+
// Assert.
50+
Assert.StartsWith(prefix, dataUri);
51+
var bytes = Convert.FromBase64String(dataUri[prefix.Length..]);
52+
Assert.Equal(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, bytes[..8]);
53+
}
54+
55+
[Fact]
56+
public void GivenARequest_WhenCallingIndex_ThenTheSvgRendererProducesAnSvgDocument()
57+
{
58+
// Arrange.
59+
const string prefix = "data:image/svg+xml,";
60+
61+
// Act.
62+
var dataUri = RenderIndex().QRCodes["SVG"];
63+
64+
// Assert.
65+
Assert.StartsWith(prefix, dataUri);
66+
var svg = Uri.UnescapeDataString(dataUri[prefix.Length..]);
67+
Assert.Contains("<svg", svg);
68+
Assert.Contains("</svg>", svg);
69+
}
70+
}

‎dotnet-client-libraries/QRCoder/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,10 +10,10 @@
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="coverlet.collector" Version="6.0.0" />
14-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
15-
<PackageReference Include="xunit" Version="2.5.3" />
16-
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
13+
<PackageReference Include="coverlet.collector" Version="10.1.0" />
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
15+
<PackageReference Include="xunit" Version="2.9.3" />
16+
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.1" />
1717
</ItemGroup>
1818

1919
<ItemGroup>

0 commit comments

Comments
 (0)