Skip to content

Commit 6ce9636

Browse files
updates for C# 11 raw string literals, and nullability enhancements
1 parent 5b5bb0d commit 6ce9636

File tree

6 files changed

+70
-75
lines changed

6 files changed

+70
-75
lines changed

3_Web/ASPNETCore/WebSampleApp/Extensions/HtmlExtensions.cs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System.Text;
2-
3-
namespace WebSampleApp.Extensions;
1+
namespace WebSampleApp.Extensions;
42

53
public static class HtmlExtensions
64
{
@@ -25,14 +23,12 @@ public static string Ul(this string value) =>
2523
public static string HeadingX(this string value, int x) =>
2624
$"<h{x}>{value}</h{x}>";
2725

28-
public static string HtmlDocument(this string content, string title)
29-
{
30-
StringBuilder sb = new();
31-
sb.Append("<!DOCTYPE HTML>");
32-
sb.Append($"<head><meta charset=\"utf-8\"><title>{title}</title></head>");
33-
sb.Append("<body>");
34-
sb.Append(content);
35-
sb.Append("</body>");
36-
return sb.ToString();
37-
}
26+
public static string HtmlDocument(this string content, string title) =>
27+
$"""
28+
<!DOCTYPE HTML>
29+
<head><meta charset="utf-8"><title>{title}</title></head>
30+
<body>
31+
{content}
32+
</body>
33+
""";
3834
}

3_Web/ASPNETCore/WebSampleApp/Middleware/HeaderMiddleware.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
namespace WebSampleApp.Middleware;
22

3-
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
43
public class HeaderMiddleware
54
{
65
private readonly RequestDelegate _next;

3_Web/ASPNETCore/WebSampleApp/Program.cs

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
22
using Microsoft.Extensions.Diagnostics.HealthChecks;
33

4-
using System.Text;
5-
64
using WebSampleApp;
75
using WebSampleApp.Extensions;
86
using WebSampleApp.Middleware;
@@ -79,7 +77,7 @@
7977
endpoints.Map("sethealthy", async context =>
8078
{
8179
var changeHealthService = context.RequestServices.GetRequiredService<HealthSample>();
82-
string healthyValue = context.Request.Query["healthy"];
80+
string? healthyValue = context.Request.Query["healthy"];
8381
if (bool.TryParse(healthyValue, out bool healthy))
8482
{
8583
changeHealthService.SetHealthy(healthy);
@@ -96,7 +94,7 @@
9694
var service = context.RequestServices.GetRequiredService<RequestAndResponseSamples>();
9795
string? action = context.GetRouteValue("action")?.ToString();
9896
string method = context.Request.Method;
99-
string result = (action, method) switch
97+
string? result = (action, method) switch
10098
{
10199
(null, "GET") => service.GetRequestInformation(context.Request),
102100
("header", "GET") => service.GetHeaderInformation(context.Request),
@@ -108,6 +106,8 @@
108106
("json", "GET") => service.GetJson(context.Response),
109107
_ => string.Empty
110108
};
109+
// TODO: check with a newer compiler version if the previous variable can be declared non-nullable
110+
if (result is null) throw new InvalidOperationException("result should not be null with the previous operation");
111111

112112
if (action is "json")
113113
{
@@ -135,46 +135,39 @@
135135

136136
endpoints.MapGet("/", async context =>
137137
{
138-
string[] lines = new[]
139-
{
140-
@"<ul>",
141-
@"<li><a href=""/hello.html"">Static Files</a> - requires UseStaticFiles</li>",
142-
@"<li><a href=""/add/37/5"">Route Constraints</a></li>",
143-
@"<li>Request and Response",
144-
@"<ul>",
145-
@"<li><a href=""/randr"">Request and Response</a></li>",
146-
@"<li><a href=""/randr/header"">Request headers</a></li>",
147-
@"<li><a href=""/randr/add?x=38&y=4"">Add</a></li>",
148-
@"<li><a href=""/randr/content?data=sample"">Content</a></li>",
149-
@"<li><a href=""/randr/content?data=<h1>Heading 1</h1>"">HTML Content</a></li>",
150-
@"<li><a href=""/randr/content?data=<script>alert('hacker');</script>"">Bad Content</a></li>",
151-
@"<li><a href=""/randr/encoded?data=<h1>sample</h1>"">Encoded content</a></li>",
152-
@"<li><a href=""/randr/encoded?data=<script>alert('hacker');</script>"">Encoded bad Content</a></li>",
153-
@"<li><a href=""/randr/form"">Form</a></li>",
154-
@"<li><a href=""/randr/writecookie"">Write cookie</a></li>",
155-
@"<li><a href=""/randr/readcookie"">Read cookie</a></li>",
156-
@"<li><a href=""/randr/json"">JSON</a></li>",
157-
@"</ul>",
158-
@"</li>",
159-
@"<li><a href=""/session"">Session</a></li>",
160-
@"<li>Health check",
161-
@"<ul>",
162-
@"<li><a href=""/health/live"">live</a></li>",
163-
@"<li><a href=""/health/ready"">ready</a></li>",
164-
@"<li><a href=""/health/allchecks"">all checks</a></li>",
165-
@"<li><a href=""/sethealthy?healthy=true"">set healthy</a></li>",
166-
@"<li><a href=""/sethealthy?healthy=false"">set unhealthy</a></li>",
167-
@"</ul>",
168-
@"</li>",
169-
@"</ul>"
170-
};
171-
172-
StringBuilder sb = new();
173-
foreach (var line in lines)
174-
{
175-
sb.Append(line);
176-
}
177-
string html = sb.ToString().HtmlDocument("Web Sample App");
138+
string content = """
139+
<ul>
140+
<li><a href="/hello.html">Static Files</a> - requires UseStaticFiles</li>
141+
<li><a href="/add/37/5">Route Constraints</a></li>
142+
<li>Request and Response
143+
<ul>
144+
<li><a href="/randr">Request and Response</a></li>
145+
<li><a href="/randr/header">Request headers</a></li>
146+
<li><a href="/randr/add?x=38&y=4">Add</a></li>
147+
<li><a href="/randr/content?data=sample">Content</a></li>
148+
<li><a href="/randr/content?data=<h1>Heading 1</h1>">HTML Content</a></li>
149+
<li><a href="/randr/content?data=<script>alert('hacker');</script>">Bad Content</a></li>
150+
<li><a href="/randr/encoded?data=<h1>sample</h1>">Encoded content</a></li>
151+
<li><a href="/randr/encoded?data=<script>alert('hacker');</script>">Encoded bad Content</a></li>
152+
<li><a href="/randr/form">Form</a></li>
153+
<li><a href="/randr/writecookie">Write cookie</a></li>
154+
<li><a href="/randr/readcookie">Read cookie</a></li>
155+
<li><a href="/randr/json">JSON</a></li>
156+
</ul>
157+
</li>
158+
<li><a href="/session">Session</a></li>
159+
<li>Health check
160+
<ul>
161+
<li><a href="/health/live">live</a></li>
162+
<li><a href="/health/ready">ready</a></li>
163+
<li><a href="/health/allchecks">all checks</a></li>
164+
<li><a href="/sethealthy?healthy=true">set healthy</a></li>
165+
<li><a href="/sethealthy?healthy=false">set unhealthy</a></li>
166+
</ul>
167+
</li>
168+
</ul>
169+
""";
170+
string html = content.HtmlDocument("Web Sample App");
178171

179172
await context.Response.WriteAsync(html);
180173
});

3_Web/ASPNETCore/WebSampleApp/Services/RequestAndResponseSamples.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@ public string GetHeaderInformation(HttpRequest request)
2828
sb.Append("Request headers".HeadingX(2));
2929
foreach (var header in request.Headers)
3030
{
31-
sb.Append(header.Key.Div(string.Join("; ", header.Value)));
31+
string? value = header.Value;
32+
sb.Append(header.Key.Div(string.Join("; ", value)));
3233
}
3334
return sb.ToString();
3435
}
3536

3637
public string QueryParameters(HttpRequest request)
3738
{
38-
string xtext = request.Query["x"];
39-
string ytext = request.Query["y"];
39+
string? xtext = request.Query["x"];
40+
string? ytext = request.Query["y"];
4041

4142
if (xtext is null || ytext is null)
4243
{
@@ -55,7 +56,7 @@ public string QueryParameters(HttpRequest request)
5556
return $"{x} + {y} = {x + y}".Div();
5657
}
5758

58-
public string Content(HttpRequest request) =>
59+
public string? Content(HttpRequest request) =>
5960
request.Query["data"];
6061

6162
public string Form(HttpRequest request) =>
@@ -67,10 +68,12 @@ public string Form(HttpRequest request) =>
6768
};
6869

6970
private static string GetForm() =>
70-
"<form method=\"post\" action=\"/randr/form\">" +
71-
"<input type=\"text\" name=\"text1\" />" +
72-
"<input type=\"submit\" value=\"Submit\" />" +
73-
"</form>";
71+
"""
72+
<form method="post" action="/randr/form">
73+
<input type="text" name="text1" />
74+
<input type="submit" value="Submit" />
75+
</form>
76+
""";
7477

7578
private static string ShowForm(HttpRequest request)
7679
{
@@ -80,7 +83,9 @@ private static string ShowForm(HttpRequest request)
8083
IFormCollection coll = request.Form;
8184
foreach (var key in coll.Keys)
8285
{
83-
sb.Append(key.Div(HtmlEncoder.Default.Encode(coll[key])));
86+
string? value = coll[key];
87+
if (value == null) continue;
88+
sb.Append(key.Div(HtmlEncoder.Default.Encode(value)));
8489
}
8590
return sb.ToString();
8691
}

3_Web/ASPNETCore/WebSampleApp/Services/SessionSample.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ public class SessionSample
1010
public async Task SessionAsync(HttpContext context)
1111
{
1212
int visits = context.Session.GetInt32(SessionVisits) ?? 0;
13-
string timeCreated = context.Session.GetString(SessionTimeCreated) ??
14-
string.Empty;
13+
string timeCreated = context.Session.GetString(SessionTimeCreated) ?? string.Empty;
1514
if (string.IsNullOrEmpty(timeCreated))
1615
{
1716
timeCreated = DateTime.Now.ToString("t", CultureInfo.InvariantCulture);
@@ -20,8 +19,10 @@ public async Task SessionAsync(HttpContext context)
2019
DateTime timeCreated2 = DateTime.Parse(timeCreated);
2120
context.Session.SetInt32(SessionVisits, ++visits);
2221
await context.Response.WriteAsync(
23-
$"Number of visits within this session: {visits} " +
24-
$"that was created at {timeCreated2:T}; " +
25-
$"current time: {DateTime.Now:T}");
22+
$"""
23+
Number of visits within this session: {visits}
24+
that was created at {timeCreated2:T};
25+
current time: {DateTime.Now:T}
26+
""");
2627
}
2728
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
<Project Sdk="Microsoft.NET.Sdk.Web">
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net7.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
7+
<LangVersion>preview</LangVersion>
78
<UserSecretsId>40a5736e-ee26-4fcf-948f-a72ac8cf0997</UserSecretsId>
89
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
910
<DockerfileContext>.</DockerfileContext>
1011
</PropertyGroup>
1112

1213
<ItemGroup>
13-
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.13" />
14+
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
1415
</ItemGroup>
1516

1617
</Project>

0 commit comments

Comments
 (0)