Skip to content

Commit

Permalink
ASP.NET Core dotnet 7 #146
Browse files Browse the repository at this point in the history
  • Loading branch information
christiannagel committed Nov 15, 2022
1 parent 3a8f52f commit f3cf6b9
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 92 deletions.
2 changes: 2 additions & 0 deletions 3_Web/ASPNETCore/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Building this sample starts with an empty ASP.NET Core Web project, and adds man

For deploying a docker image to Microsoft Azure, you need an Azure subscription and Docker Desktop. See chapter 1 for more information.

[.NET 7 Updates](../../Dotnet7Updates.md) with the *WebSampleApp* using **raw string literals**.

[See the commands to create an Azure App Service, Azure Container Registry, and push a docker image to the registry](createappservice.sh)

For code comments and issues please check [Professional C#'s GitHub Repository](https://github.com/ProfessionalCSharp/ProfessionalCSharp2021)
Expand Down
2 changes: 1 addition & 1 deletion 3_Web/ASPNETCore/SimpleHost/SimpleHost.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Expand Down
170 changes: 82 additions & 88 deletions 3_Web/ASPNETCore/WebSampleApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,108 +34,103 @@

app.UseHeaderMiddleware();

app.UseRouting();

app.UseEndpoints(endpoints =>
app.MapHealthChecks("/health/allchecks");
app.MapHealthChecks("/health/live", new HealthCheckOptions()
{
endpoints.MapHealthChecks("/health/allchecks");
endpoints.MapHealthChecks("/health/live", new HealthCheckOptions()
{
Predicate = reg => reg.Tags.Contains("liveness"),
ResultStatusCodes = new Dictionary<HealthStatus, int>()
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
},
});
endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions
{
Predicate = reg => reg.Tags.Contains("readiness"),
ResponseWriter = async (context, writer) =>
{
context.Response.StatusCode = writer.Status switch
{
HealthStatus.Healthy => StatusCodes.Status200OK,
HealthStatus.Degraded => StatusCodes.Status503ServiceUnavailable,
HealthStatus.Unhealthy => StatusCodes.Status503ServiceUnavailable,
_ => StatusCodes.Status503ServiceUnavailable
};

if (writer.Status == HealthStatus.Healthy)
{
await context.Response.WriteAsync("ready");
}
else
{
await context.Response.WriteAsync(writer.Status.ToString());
await context.Response.WriteAsync($"duration: {writer.TotalDuration}");
}
}
});

endpoints.Map("sethealthy", async context =>
Predicate = reg => reg.Tags.Contains("liveness"),
ResultStatusCodes = new Dictionary<HealthStatus, int>()
{
var changeHealthService = context.RequestServices.GetRequiredService<HealthSample>();
string? healthyValue = context.Request.Query["healthy"];
if (bool.TryParse(healthyValue, out bool healthy))
{
changeHealthService.SetHealthy(healthy);
}
else
{
await context.Response.WriteAsync("Missing healthy query parameter");
}

});
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
},
});

endpoints.Map("/randr/{action?}", async context =>
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
Predicate = reg => reg.Tags.Contains("readiness"),
ResponseWriter = async (context, writer) =>
{
var service = context.RequestServices.GetRequiredService<RequestAndResponseSamples>();
string? action = context.GetRouteValue("action")?.ToString();
string method = context.Request.Method;
string? result = (action, method) switch
context.Response.StatusCode = writer.Status switch
{
(null, "GET") => service.GetRequestInformation(context.Request),
("header", "GET") => service.GetHeaderInformation(context.Request),
("add", "GET") => service.QueryParameters(context.Request),
("content", "GET") => service.Content(context.Request),
("form", "GET" or "POST") => service.Form(context.Request),
("writecookie", "GET") => service.WriteCookie(context.Response),
("readcookie", "GET") => service.ReadCookie(context.Request),
("json", "GET") => service.GetJson(context.Response),
_ => string.Empty
HealthStatus.Healthy => StatusCodes.Status200OK,
HealthStatus.Degraded => StatusCodes.Status503ServiceUnavailable,
HealthStatus.Unhealthy => StatusCodes.Status503ServiceUnavailable,
_ => StatusCodes.Status503ServiceUnavailable
};
// TODO: check with a newer compiler version if the previous variable can be declared non-nullable
if (result is null) throw new InvalidOperationException("result should not be null with the previous operation");

if (action is "json")
if (writer.Status == HealthStatus.Healthy)
{
await context.Response.WriteAsync(result);
await context.Response.WriteAsync("ready");
}
else
{
var doc = result.HtmlDocument("Request and Response Samples");
await context.Response.WriteAsync(doc);
await context.Response.WriteAsync(writer.Status.ToString());
await context.Response.WriteAsync($"duration: {writer.TotalDuration}");
}
});
}
});

endpoints.Map("/add/{x:int}/{y:int}", async context =>
app.Map("sethealthy", async context =>
{
var changeHealthService = context.RequestServices.GetRequiredService<HealthSample>();
string? healthyValue = context.Request.Query["healthy"];
if (bool.TryParse(healthyValue, out bool healthy))
{
int x = int.Parse(context.GetRouteValue("x")?.ToString() ?? "0");
int y = int.Parse(context.GetRouteValue("y")?.ToString() ?? "0");
await context.Response.WriteAsync($"The result of {x} + {y} is {x + y}");
});

endpoints.Map("/session", async context =>
changeHealthService.SetHealthy(healthy);
}
else
{
var service = context.RequestServices.GetRequiredService<SessionSample>();
await service.SessionAsync(context);
});
await context.Response.WriteAsync("Missing healthy query parameter");
}

});

endpoints.MapGet("/", async context =>
app.Map("/randr/{action?}", async context =>
{
var service = context.RequestServices.GetRequiredService<RequestAndResponseSamples>();
string? action = context.GetRouteValue("action")?.ToString();
string method = context.Request.Method;
string result = (action, method) switch
{
(null, "GET") => service.GetRequestInformation(context.Request),
("header", "GET") => service.GetHeaderInformation(context.Request),
("add", "GET") => service.QueryParameters(context.Request),
("content", "GET") => service.Content(context.Request),
("form", "GET" or "POST") => service.Form(context.Request),
("writecookie", "GET") => service.WriteCookie(context.Response),
("readcookie", "GET") => service.ReadCookie(context.Request),
("json", "GET") => service.GetJson(context.Response),
_ => string.Empty
};

if (action is "json")
{
string content = """
await context.Response.WriteAsync(result);
}
else
{
var doc = result.HtmlDocument("Request and Response Samples");
await context.Response.WriteAsync(doc);
}
});

app.Map("/add/{x:int}/{y:int}", async context =>
{
int x = int.Parse(context.GetRouteValue("x")?.ToString() ?? "0");
int y = int.Parse(context.GetRouteValue("y")?.ToString() ?? "0");
await context.Response.WriteAsync($"The result of {x} + {y} is {x + y}");
});

app.Map("/session", async context =>
{
var service = context.RequestServices.GetRequiredService<SessionSample>();
await service.SessionAsync(context);
});

app.MapGet("/", async context =>
{
string content = """
<ul>
<li><a href="/hello.html">Static Files</a> - requires UseStaticFiles</li>
<li><a href="/add/37/5">Route Constraints</a></li>
Expand Down Expand Up @@ -167,10 +162,9 @@
</li>
</ul>
""";
string html = content.HtmlDocument("Web Sample App");
string html = content.HtmlDocument("Web Sample App");

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

app.Run();
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Text;
using Microsoft.Extensions.Primitives;

using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;

Expand Down Expand Up @@ -56,8 +58,17 @@ public string QueryParameters(HttpRequest request)
return $"{x} + {y} = {x + y}".Div();
}

public string? Content(HttpRequest request) =>
request.Query["data"];
public string Content(HttpRequest request)
{
if (request.Query.TryGetValue("data", out var value))
{
return value;
}
else
{
return "no `data` value";
}
}

public string Form(HttpRequest request) =>
request.Method switch
Expand Down
4 changes: 4 additions & 0 deletions Dotnet7Updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Chapter 19, Networking, page 545

The *HttpServer* code sample is changed to use C# 11 **raw string literals**.

Chapter 24, ASP.NET Core

The sample *WebSampleApp* makes use of **raw string literals** in *Program.cs*.

## Platform Invoke

Chapter 13, Managed and unmanaged Memory, Page 368
Expand Down

0 comments on commit f3cf6b9

Please sign in to comment.