Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions razor-slices/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ This is a vendored fork of [DamianEdwards/RazorSlices](https://github.com/Damian

The upstream project is copyright Damian Edwards and licensed under the [Apache 2.0 license](../LICENSE). See [ThirdPartyNotices.txt](ThirdPartyNotices.txt) for the full attribution.

## Upstream sync point

Last synced to upstream commit [`c286ca0`](https://github.com/DamianEdwards/RazorSlices/commit/c286ca021b05345e74785364c4a14515b082c90b) (2026-09-19, `main` after DamianEdwards/RazorSlices#146). When re-syncing, copy upstream `src/`, `tests/`, and `samples/` source files, then apply the transformations listed below.

## Differences from upstream

- Package ID, assembly name, and root namespace changed from `RazorSlices` to `Duende.RazorSlices`
- Source generator package renamed from `RazorSlices.SourceGenerator` to `Duende.RazorSlices.SourceGenerator`
- The source generator's model-type resolver matches the `Duende.RazorSlices` namespace when walking slice base types
- Samples keep the upstream `RazorSlices.Samples.*` namespace and add explicit `using Duende.RazorSlices;` directives where needed
- Duende license headers, LF line endings, and `dotnet format` applied
- Target framework updated to `net10.0`
- Strong-naming disabled (not required for vendored use)
3 changes: 3 additions & 0 deletions razor-slices/samples/PagesAndSlices/Pages/Index.cshtml.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@using RazorSlices.Samples.PagesAndSlices.Pages
@using RazorSlices.Samples.PagesAndSlices.Pages
4 changes: 4 additions & 0 deletions razor-slices/samples/PagesAndSlices/PagesAndSlices.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
<EnableDefaultRazorSlices>false</EnableDefaultRazorSlices>
</PropertyGroup>

<PropertyGroup>
<RazorSliceProxiesAsRecords>true</RazorSliceProxiesAsRecords>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\RazorSlices\RazorSlices.csproj" />
<ProjectReference Include="..\..\src\SourceGenerator\SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
Expand Down
3 changes: 3 additions & 0 deletions razor-slices/samples/PagesAndSlices/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using RazorSlices.Samples.PagesAndSlices.Slices;

var builder = WebApplication.CreateBuilder(args);
Expand Down
2 changes: 1 addition & 1 deletion razor-slices/samples/PagesAndSlices/Slices/_Layout.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
</div>
</main>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
@using RazorSlices.Samples.PagesAndSlices.Slices

@tagHelperPrefix __disable_tagHelpers__:
@removeTagHelper *, Microsoft.AspNetCore.Mvc.Razor
@removeTagHelper *, Microsoft.AspNetCore.Mvc.Razor
3 changes: 3 additions & 0 deletions razor-slices/samples/RazorClassLibrary/MarkerClass.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.RazorClassLibrary;

internal class MarkerClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@
</div>
</footer>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using Duende.RazorSlices;

namespace RazorSlices.Samples.RazorClassLibrary.Slices;
Expand Down
2 changes: 1 addition & 1 deletion razor-slices/samples/RazorClassLibrary/_ViewImports.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
@using RazorSlices.Samples.RazorClassLibrary;

@tagHelperPrefix __disable_tagHelpers__:
@removeTagHelper *, Microsoft.AspNetCore.Mvc.Razor
@removeTagHelper *, Microsoft.AspNetCore.Mvc.Razor
9 changes: 9 additions & 0 deletions razor-slices/samples/WebApp/Alternate/Lorem/LoremExtra.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp.Alternate.Lorem;

public static class LoremExtra
{
public const string AdditionalContent = "<div>Additional content</div>";
}
3 changes: 3 additions & 0 deletions razor-slices/samples/WebApp/AppJsonContext.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using System.Text.Json.Serialization;

namespace RazorSlices.Samples.WebApp;
Expand Down
3 changes: 3 additions & 0 deletions razor-slices/samples/WebApp/HtmlContentParams.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp;

public struct HtmlContentParams
Expand Down
3 changes: 3 additions & 0 deletions razor-slices/samples/WebApp/LoremParams.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp;
public struct LoremParams
{
Expand Down
13 changes: 12 additions & 1 deletion razor-slices/samples/WebApp/MapSlices.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using Duende.RazorSlices;
using LibrarySlices = RazorSlices.Samples.RazorClassLibrary.Slices;
using Microsoft.AspNetCore.Http.HttpResults;
Expand Down Expand Up @@ -31,6 +34,9 @@ public static IEndpointRouteBuilder MapSlices(this IEndpointRouteBuilder endpoin
await slice.RenderAsync(httpResponse.Body);
});
endpoints.MapGet("/encoding", () => Results.RazorSlice<Slices.Encoding>());
endpoints.MapGet("/attribute-rendering", () => Results.RazorSlice<Slices.AttributeRendering>());
endpoints.MapGet("/streaming", () => Results.RazorSlice<Slices.Streaming>())
.DisableResponseBuffering();
endpoints.MapGet("/unicode", () => Results.RazorSlice<Slices.Unicode>());
endpoints.MapGet("/templated", (bool async = false) => Results.RazorSlice<Slices.Templated, bool>(async));
endpoints.MapGet("/library", () => Results.RazorSlice<LibrarySlices.FromLibrary>());
Expand All @@ -49,6 +55,7 @@ public static IEndpointRouteBuilder MapSlices(this IEndpointRouteBuilder endpoin
return Results.Ok(new ResultDto(stringBuilder.ToString()));
});

endpoints.MapGet("/nested", () => Results.RazorSlice<Slices.Nested, Models.Todo.Nested>(new Models.Todo.Nested { Extra = "Test" }));
endpoints.MapGet("/", () => Results.RazorSlice<Slices.Todos, Models.Todo[]>(Models.Todos.AllTodos));
endpoints.MapGet("/{id:int}", Results<RazorSlice, NotFound> (int id) =>
{
Expand All @@ -58,7 +65,8 @@ public static IEndpointRouteBuilder MapSlices(this IEndpointRouteBuilder endpoin
: TypedResults.NotFound();
});
#else
endpoints.MapGet("/lorem-static", () => Results.Extensions.RazorSlice<Slices.Lorem.LoremStatic>());
endpoints.MapGet("/nested", () => Results.Extensions.RazorSlice<Slices.Nested, Models.Todo.Nested>(new Models.Todo.Nested { Extra = "Test" }));
endpoints.MapGet("/lorem-static",() => Results.Extensions.RazorSlice<Slices.Lorem.LoremStatic>());
endpoints.MapGet("/lorem-dynamic", (int? paraCount, int? paraLength) =>
Results.Extensions.RazorSlice<Slices.Lorem.LoremDynamic, LoremParams>(new LoremParams(paraCount, paraLength)));
endpoints.MapGet("/lorem-formattable", (int? paraCount, int? paraLength) =>
Expand All @@ -76,6 +84,9 @@ public static IEndpointRouteBuilder MapSlices(this IEndpointRouteBuilder endpoin
await slice.RenderAsync(httpResponse.Body);
});
endpoints.MapGet("/encoding", () => Results.Extensions.RazorSlice<Slices.Encoding>());
endpoints.MapGet("/attribute-rendering", () => Results.Extensions.RazorSlice<Slices.AttributeRendering>());
endpoints.MapGet("/streaming", () => Results.Extensions.RazorSlice<Slices.Streaming>())
.DisableResponseBuffering();
endpoints.MapGet("/unicode", () => Results.Extensions.RazorSlice<Slices.Unicode>());
endpoints.MapGet("/templated", (bool async = false) => Results.Extensions.RazorSlice<Slices.Templated, bool>(async));
endpoints.MapGet("/library", () => Results.Extensions.RazorSlice<LibrarySlices.FromLibrary>());
Expand Down
10 changes: 9 additions & 1 deletion razor-slices/samples/WebApp/Models/Todo.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using System.Text;

namespace RazorSlices.Samples.WebApp.Models;

public class Todo
{
public class Nested
{
public string? Extra { get; set; }
}

public int Id { get; set; }

private byte[] _titleUtf8 = [];
Expand Down Expand Up @@ -43,4 +51,4 @@ internal static class Todos
new() { Id = 4, TitleUtf8 = "Walk the kangaroo."u8.ToArray(), DueBy = DateOnly.FromDateTime(DateTime.Now.AddDays(1)), IsComplete = false },
new() { Id = 5, TitleUtf8 = "Call Grandma."u8.ToArray(), DueBy = DateOnly.FromDateTime(DateTime.Now.AddDays(1)), IsComplete = false },
];
}
}
3 changes: 3 additions & 0 deletions razor-slices/samples/WebApp/Program.Testing.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp;

public partial class Program
Expand Down
6 changes: 5 additions & 1 deletion razor-slices/samples/WebApp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using System.Runtime.CompilerServices;
using RazorSlices.Samples.WebApp;
using RazorSlices.Samples.WebApp.Services;
Expand All @@ -22,11 +25,12 @@

app.UseStatusCodePages();
app.UseStaticFiles();
app.UseRouting();

if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
if (Environment.GetEnvironmentVariable("ENABLE_RESPONSE_BUFFERING") == "true")
if (builder.Configuration["ENABLE_RESPONSE_BUFFERING"] == "true")
{
// Enable response buffering middleware to allow for response interception during local development
app.UseResponseBuffering();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp;

public static class ResponseBufferingEndpointConventionBuilderExtensions
{
public static TBuilder DisableResponseBuffering<TBuilder>(this TBuilder builder)
where TBuilder : IEndpointConventionBuilder
{
ArgumentNullException.ThrowIfNull(builder);
return builder.WithMetadata(new DisableResponseBufferingAttribute());
}
}
13 changes: 13 additions & 0 deletions razor-slices/samples/WebApp/ResponseBufferingMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp;

public interface IDisableResponseBufferingMetadata
{
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class DisableResponseBufferingAttribute : Attribute, IDisableResponseBufferingMetadata
{
}
12 changes: 10 additions & 2 deletions razor-slices/samples/WebApp/ResponseBufferingMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp;

using System.IO;
Expand All @@ -9,6 +12,12 @@ internal sealed class ResponseBufferingMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(HttpContext context)
{
if (context.GetEndpoint()?.Metadata.GetMetadata<IDisableResponseBufferingMetadata>() is not null)
{
await next(context);
return;
}

// Save the original response body stream
var originalBodyStream = context.Response.Body;

Expand Down Expand Up @@ -42,11 +51,10 @@ public async Task InvokeAsync(HttpContext context)
}
}

internal static class ResponseBufferingMiddlewareExtensions
public static class ResponseBufferingMiddlewareExtensions
{
public static IApplicationBuilder UseResponseBuffering(this IApplicationBuilder app)
{
return app.UseMiddleware<ResponseBufferingMiddleware>();
}
}

3 changes: 3 additions & 0 deletions razor-slices/samples/WebApp/ResultDtos.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp;

record ResultDto(string HtmlString);
3 changes: 3 additions & 0 deletions razor-slices/samples/WebApp/Services/LoremService.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using RazorSlices.Samples.WebApp.Slices.Lorem;
using System.Text;

Expand Down
17 changes: 17 additions & 0 deletions razor-slices/samples/WebApp/Slices/AttributeRendering.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@inherits RazorSlice
@implements IUsesLayout<_Layout, LayoutModel>

<h1 class="mt-5">Attribute rendering</h1>

<div class="@false">False</div>
<div class="@null">Null</div>
<div class="@("")">Empty</div>
<div class="@("false")">False String</div>
<div class="@("active")">String</div>
<input type="checkbox" checked="@true" name="true" />
<input type="checkbox" checked="@false" name="false" />
<input type="checkbox" checked="@null" name="null" />

@functions {
public LayoutModel LayoutModel => new() { Title = "Attribute rendering" };
}
2 changes: 1 addition & 1 deletion razor-slices/samples/WebApp/Slices/Encoding.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Encoded:<br />

@functions {
public LayoutModel LayoutModel => new() { Title = "Encoding" };
}
}
3 changes: 3 additions & 0 deletions razor-slices/samples/WebApp/Slices/LayoutModel.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp.Slices;

public class LayoutModel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@namespace RazorSlices.Samples.WebApp.Alternate.Lorem
@using System.IO
@using System.Text.Encodings.Web

Expand Down Expand Up @@ -32,10 +33,12 @@
if (HtmlEncode)
{
writer.Write(encoder.Encode(PageContent.Html));
writer.Write(encoder.Encode(LoremExtra.AdditionalContent));
}
else
{
writer.Write(PageContent.Html);
writer.Write(LoremExtra.AdditionalContent);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@namespace RazorSlices.Samples.WebApp.Slices.Lorem
@inherits RazorSlice<LoremParams>
@implements IUsesLayout<_LoremLayout, LayoutModel>

Expand All @@ -22,4 +23,4 @@

return Task.CompletedTask;
}
}
}
3 changes: 3 additions & 0 deletions razor-slices/samples/WebApp/Slices/Lorem/PageContent.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

namespace RazorSlices.Samples.WebApp.Slices.Lorem;

public static class PageContent
Expand Down
2 changes: 1 addition & 1 deletion razor-slices/samples/WebApp/Slices/Lorem/_LoremMenu.cshtml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- _LoremMenu.cshtml -->
@inherits RazorSlice
@inherits Duende.RazorSlices.RazorSlice

<ul class="nav">
<li class="nav-item">
Expand Down
2 changes: 2 additions & 0 deletions razor-slices/samples/WebApp/Slices/Lorem/_ViewImports.cshtml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@inherits RazorSlice

@namespace RazorSlices.Samples.WebApp.Slices.Lorem

@using RazorSlices.Samples.WebApp.Services
@using RazorSlices.Samples.WebApp.Slices.Lorem
5 changes: 5 additions & 0 deletions razor-slices/samples/WebApp/Slices/Nested.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@inherits RazorSlice<Models.Todo.Nested>

<div>
Nested : @Model.Extra
</div>
13 changes: 13 additions & 0 deletions razor-slices/samples/WebApp/Slices/SliceBaseClasses.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Duende Software. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using Duende.RazorSlices;
using Models = RazorSlices.Samples.WebApp.Models;

namespace RazorSlices.Samples.WebApp.Slices;

public abstract class TodoSliceBase : RazorSlice<Models.Todo>;

public abstract class GenericTodosSliceBase<TModel> : RazorSlice<TModel>;

public abstract class DeepGenericTodosSliceBase<TModel> : GenericTodosSliceBase<TModel>;
Loading
Loading