-
Notifications
You must be signed in to change notification settings - Fork 241
Update to latest Razor Slices #2038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
03cdcbe
f88ae31
c370e52
1843477
b275bbf
26ea1f5
23cc21a
2e71883
6799bb7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Logging.Console; | ||
|
||
namespace Server | ||
{ | ||
|
@@ -84,7 +85,10 @@ public static IHostBuilder CreateHostBuilder(string[] args) | |
if (Enum.TryParse<LogLevel>(config["LogLevel"], out var logLevel)) | ||
{ | ||
Console.WriteLine($"Console Logging enabled with level '{logLevel}'"); | ||
loggerFactory.AddConsole(o => o.TimestampFormat = "ss.ffff ").SetMinimumLevel(logLevel); | ||
loggerFactory | ||
.AddConsole() | ||
.AddConsoleFormatter<ConsoleFormatter, ConsoleFormatterOptions>(o => o.TimestampFormat = "ss.ffff") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change was done to resolve an obsolete warning. |
||
.SetMinimumLevel(logLevel); | ||
} | ||
}) | ||
.UseDefaultServiceProvider((context, options) => | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ | |
|
||
<ItemGroup> | ||
<PackageReference Include="Grpc.AspNetCore" Version="2.27.0" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Grpc.HttpApi" Version="0.1.0-alpha.20121.1" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Grpc.HttpApi" Version="0.1.0-alpha.20179.2" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was done to quiet a NuGet warning about the previous stated version being unresolvable. |
||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
<PropertyGroup> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<OutputType>Exe</OutputType> | ||
</PropertyGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<TargetFramework>net8.0</TargetFramework> | ||
</PropertyGroup> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ | |
<PackageReference Include="Npgsql" Version="$(NpgsqlVersion80)" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup Condition="$([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '9.0'))"> | ||
<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible($(TargetFramework), 'net9.0'))"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This fixes a build error that occurs when building the project without specifying a target framework, e.g. when building from VS 😄 |
||
<PackageReference Include="Npgsql" Version="$(NpgsqlVersion90)" /> | ||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="$(NpgsqlEntityFrameworkCorePostgreSQLVersion90)" /> | ||
</ItemGroup> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
using Minimal; | ||
using Minimal.Database; | ||
using Minimal.Models; | ||
using Minimal.Templates; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
|
@@ -37,12 +38,11 @@ | |
|
||
app.MapGet("/db/result", async (Db db) => Results.Json(await db.LoadSingleQueryRow())); | ||
|
||
var createFortunesTemplate = RazorSlice.ResolveSliceFactory<List<Fortune>>("/Templates/Fortunes.cshtml"); | ||
var htmlEncoder = CreateHtmlEncoder(); | ||
|
||
app.MapGet("/fortunes", async (HttpContext context, Db db) => { | ||
var fortunes = await db.LoadFortunesRows(); | ||
var template = (RazorSliceHttpResult<List<Fortune>>)createFortunesTemplate(fortunes); | ||
var template = (RazorSliceHttpResult<List<Fortune>>)Fortunes.Create(fortunes); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Razor Slices generates these template factory classes now. |
||
template.HtmlEncoder = htmlEncoder; | ||
return template; | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,81 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.IO.Pipelines; | ||
using System.Runtime.CompilerServices; | ||
using System.Threading.Tasks; | ||
using RazorSlices; | ||
|
||
namespace PlatformBenchmarks | ||
namespace PlatformBenchmarks; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to file-scoped namespace declaration on this file. |
||
|
||
public sealed partial class BenchmarkApplication | ||
{ | ||
public partial class BenchmarkApplication | ||
{ | ||
#if DATABASE | ||
private async Task FortunesRaw(PipeWriter pipeWriter) | ||
{ | ||
await OutputFortunes( | ||
pipeWriter, | ||
await RawDb.LoadFortunesRows(), | ||
// To isolate template rendering from DB access, comment out the line above and uncomment the line below | ||
//await RawDb.LoadFortunesRowsNoDb(), | ||
FortunesTemplateFactory); | ||
} | ||
|
||
private async Task FortunesDapper(PipeWriter pipeWriter) | ||
{ | ||
await OutputFortunes(pipeWriter, await DapperDb.LoadFortunesRows(), FortunesDapperTemplateFactory); | ||
} | ||
|
||
private async Task FortunesEf(PipeWriter pipeWriter) | ||
{ | ||
await OutputFortunes(pipeWriter, await EfDb.LoadFortunesRows(), FortunesEfTemplateFactory); | ||
} | ||
private async Task FortunesRaw(PipeWriter pipeWriter) | ||
{ | ||
await OutputFortunes( | ||
pipeWriter, | ||
await RawDb.LoadFortunesRows(), | ||
// To isolate template rendering from DB access, comment out the line above and uncomment the line below | ||
//await RawDb.LoadFortunesRowsNoDb(), | ||
Templates.FortunesUtf8.Create); | ||
} | ||
|
||
private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, SliceFactory<TModel> templateFactory) | ||
{ | ||
// Render headers | ||
var preamble = """ | ||
HTTP/1.1 200 OK | ||
Server: K | ||
Content-Type: text/html; charset=utf-8 | ||
Transfer-Encoding: chunked | ||
"""u8; | ||
var headersLength = preamble.Length + DateHeader.HeaderBytes.Length; | ||
var headersSpan = pipeWriter.GetSpan(headersLength); | ||
preamble.CopyTo(headersSpan); | ||
DateHeader.HeaderBytes.CopyTo(headersSpan[preamble.Length..]); | ||
pipeWriter.Advance(headersLength); | ||
private async Task FortunesDapper(PipeWriter pipeWriter) | ||
{ | ||
await OutputFortunes(pipeWriter, await DapperDb.LoadFortunesRows(), Templates.FortunesUtf8.Create); | ||
} | ||
|
||
// Render body | ||
var template = templateFactory(model); | ||
// Kestrel PipeWriter span size is 4K, headers above already written to first span & template output is ~1350 bytes, | ||
// so 2K chunk size should result in only a single span and chunk being used. | ||
var chunkedWriter = GetChunkedWriter(pipeWriter, chunkSizeHint: 2048); | ||
var renderTask = template.RenderAsync(chunkedWriter, null, HtmlEncoder); | ||
private async Task FortunesEf(PipeWriter pipeWriter) | ||
{ | ||
await OutputFortunes(pipeWriter, await EfDb.LoadFortunesRows(), Templates.FortunesEf.Create); | ||
} | ||
|
||
if (renderTask.IsCompletedSuccessfully) | ||
{ | ||
renderTask.GetAwaiter().GetResult(); | ||
EndTemplateRendering(chunkedWriter, template); | ||
return ValueTask.CompletedTask; | ||
} | ||
private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, Func<TModel, RazorSlice> templateFactory) | ||
{ | ||
// Render headers | ||
var preamble = """ | ||
HTTP/1.1 200 OK | ||
Server: K | ||
Content-Type: text/html; charset=utf-8 | ||
Transfer-Encoding: chunked | ||
"""u8; | ||
var headersLength = preamble.Length + DateHeader.HeaderBytes.Length; | ||
var headersSpan = pipeWriter.GetSpan(headersLength); | ||
preamble.CopyTo(headersSpan); | ||
DateHeader.HeaderBytes.CopyTo(headersSpan[preamble.Length..]); | ||
pipeWriter.Advance(headersLength); | ||
|
||
return AwaitTemplateRenderTask(renderTask, chunkedWriter, template); | ||
} | ||
// Render body | ||
var template = templateFactory(model); | ||
// Kestrel PipeWriter span size is 4K, headers above already written to first span & template output is ~1350 bytes, | ||
// so 2K chunk size should result in only a single span and chunk being used. | ||
var chunkedWriter = GetChunkedWriter(pipeWriter, chunkSizeHint: 2048); | ||
var renderTask = template.RenderAsync(chunkedWriter, HtmlEncoder); | ||
|
||
private static async ValueTask AwaitTemplateRenderTask(ValueTask renderTask, ChunkedBufferWriter<WriterAdapter> chunkedWriter, RazorSlice template) | ||
if (renderTask.IsCompletedSuccessfully) | ||
{ | ||
await renderTask; | ||
renderTask.GetAwaiter().GetResult(); | ||
EndTemplateRendering(chunkedWriter, template); | ||
return ValueTask.CompletedTask; | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static void EndTemplateRendering(ChunkedBufferWriter<WriterAdapter> chunkedWriter, RazorSlice template) | ||
{ | ||
chunkedWriter.End(); | ||
ReturnChunkedWriter(chunkedWriter); | ||
template.Dispose(); | ||
} | ||
#endif | ||
return AwaitTemplateRenderTask(renderTask, chunkedWriter, template); | ||
} | ||
|
||
private static async ValueTask AwaitTemplateRenderTask(ValueTask renderTask, ChunkedPipeWriter chunkedWriter, RazorSlice template) | ||
{ | ||
await renderTask; | ||
EndTemplateRendering(chunkedWriter, template); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
private static void EndTemplateRendering(ChunkedPipeWriter chunkedWriter, RazorSlice template) | ||
{ | ||
chunkedWriter.Complete(); | ||
ReturnChunkedWriter(chunkedWriter); | ||
template.Dispose(); | ||
} | ||
#endif | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems this was a typo/copy-pasta that was causing a NuGet warning as the versions didn't line up.