This commit is contained in:
2026-05-03 23:35:42 +05:00
commit 7778a94cf5
14 changed files with 410 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
using System.Text.Json.Serialization;
namespace Htmx.ApiDemo;
[JsonSerializable(typeof(string))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
+33
View File
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<PublishAot>true</PublishAot>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>obj/Generated</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<CompilerVisibleProperty Include="RootNamespace" />
<CompilerVisibleProperty Include="MSBuildProjectDirectory" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="**/*.htmx" />
<None Remove="**/*.htmx" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Immediate.Apis" Version="4.2.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.7" />
<ProjectReference Include="..\Htmx.SourceGenerator\Htmx.SourceGenerator.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Htmx.SourceGenerator\Htmx.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
</Project>
+11
View File
@@ -0,0 +1,11 @@
@Htmx.ApiDemo_HostAddress = http://localhost:5120
GET {{Htmx.ApiDemo_HostAddress}}/todos/
Accept: application/json
###
GET {{Htmx.ApiDemo_HostAddress}}/todos/1
Accept: application/json
###
+24
View File
@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Htmx.ApiDemo", "Htmx.ApiDemo.csproj", "{38A5EDEF-D21B-8D4E-D1F2-DDFE0335BD22}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{38A5EDEF-D21B-8D4E-D1F2-DDFE0335BD22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38A5EDEF-D21B-8D4E-D1F2-DDFE0335BD22}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38A5EDEF-D21B-8D4E-D1F2-DDFE0335BD22}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38A5EDEF-D21B-8D4E-D1F2-DDFE0335BD22}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B66FEAA2-59A2-4489-9AEB-ED875EEE5D3E}
EndGlobalSection
EndGlobal
+28
View File
@@ -0,0 +1,28 @@
using System.Text.Json.Serialization;
using Htmx.ApiDemo.Templates;
using Microsoft.AspNetCore.Http.HttpResults;
using Immediate.Apis;
using Immediate.Apis.Shared;
using Immediate.Handlers.Shared;
using Htmx.ApiDemo;
var builder = WebApplication.CreateSlimBuilder(args);
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
builder.Services.AddHttpContextAccessor();
builder.Services
.AddHtmxApiDemoBehaviors()
.AddHtmxApiDemoHandlers();
builder.Services.AddOpenApi();
var app = builder.Build();
if (app.Environment.IsDevelopment())
app.MapOpenApi();
app.MapHtmxApiDemoEndpoints();
app.Run();
@@ -0,0 +1,15 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "todos",
"applicationUrl": "http://localhost:5120",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
+4
View File
@@ -0,0 +1,4 @@
<div class="greeting">
<h1>Hello, $$User$$!</h1>
<p>Welcome to high-performance htmx rendering.</p>
</div>
+37
View File
@@ -0,0 +1,37 @@
using Htmx.ApiDemo;
using Immediate.Apis;
using Immediate.Apis.Shared;
using Immediate.Handlers.Shared;
namespace Htmx.ApiDemo.Templates;
public class Greeting : GreetingBase
{
private byte[] _userData = [];
public required string Username { init => _userData = value.ToUtf8Bytes(); }
protected override void RenderUser(HtmxRenderContext context) => context.Writer.WriteUtf8(_userData);
}
[Handler]
[MapGet("/greet/{username}")]
public static partial class GetGreetingHandler
{
public record Query(string Username);
private static ValueTask HandleAsync(
Query query,
IHttpContextAccessor httpContextAccessor,
CancellationToken token)
{
var context = httpContextAccessor.HttpContext;
if(context is null)
throw new InvalidOperationException("HttpContext is not available.");
var template = new Greeting { Username = query.Username };
context.Response.ContentType = "text/html; charset=utf-8";
context.Response.BodyWriter.WriteHtmx(template);
return ValueTask.CompletedTask;
}
}
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
+9
View File
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}