<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://aeleftheriadis.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://aeleftheriadis.github.io/" rel="alternate" type="text/html" /><updated>2026-09-13T12:42:30+00:00</updated><id>https://aeleftheriadis.github.io/feed.xml</id><title type="html">Aeleftheriadis</title><subtitle>Web Developer&apos;s Blog</subtitle><entry><title type="html">Comprehensive Guide: .NET 11 Automatic CSRF Protection Across All Blazor Render Modes</title><link href="https://aeleftheriadis.github.io/Blazor_NET11_Auto_CSRF_Comprehensive_Guide/" rel="alternate" type="text/html" title="Comprehensive Guide: .NET 11 Automatic CSRF Protection Across All Blazor Render Modes" /><published>2026-09-13T00:00:00+00:00</published><updated>2026-09-13T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/Blazor_NET11_Auto_CSRF_Comprehensive_Guide</id><content type="html" xml:base="https://aeleftheriadis.github.io/Blazor_NET11_Auto_CSRF_Comprehensive_Guide/"><![CDATA[<h1 id="comprehensive-guide-net-11-automatic-csrf-protection-across-all-blazor-render-modes">Comprehensive Guide: .NET 11 Automatic CSRF Protection Across All Blazor Render Modes</h1>

<p>.NET 11 introduces a <strong>Fetch Metadata-based automatic CSRF protection mechanism</strong> built directly into ASP.NET Core pipelines. Replacing traditional cryptographic synchronizer tokens (<code class="language-plaintext highlighter-rouge">__RequestVerificationToken</code>) and heavy server-side Data Protection validation, the new <code class="language-plaintext highlighter-rouge">CsrfProtectionMiddleware</code> automatically validates browser-managed headers (<code class="language-plaintext highlighter-rouge">Sec-Fetch-Site</code>, <code class="language-plaintext highlighter-rouge">Sec-Fetch-Mode</code>, and <code class="language-plaintext highlighter-rouge">Origin</code>) across all Blazor project templates.</p>

<hr />

<h2 id="1-core-architectural-shift">1. Core Architectural Shift</h2>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Architectural Aspect</th>
      <th style="text-align: left">Traditional Token Model (.NET 8/9/10)</th>
      <th style="text-align: left">.NET 11 Automatic CSRF</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><strong>Validation Mechanism</strong></td>
      <td style="text-align: left">Cryptographic token matching in form payload/cookies</td>
      <td style="text-align: left">Browser-managed Fetch Metadata header evaluation</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>State &amp; Cryptography</strong></td>
      <td style="text-align: left">Requires Data Protection keys, server state, per-request encryption</td>
      <td style="text-align: left">Zero cryptographic overhead (pure header evaluation)</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Multi-Tab Reliability</strong></td>
      <td style="text-align: left">Prone to token race conditions and invalidations across tabs</td>
      <td style="text-align: left">Seamless execution across multiple tabs</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Middleware Pipeline</strong></td>
      <td style="text-align: left">Required explicit <code class="language-plaintext highlighter-rouge">app.UseAntiforgery()</code> and component attributes</td>
      <td style="text-align: left">Enabled automatically via <code class="language-plaintext highlighter-rouge">WebApplication.CreateBuilder</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Non-Browser Callers</strong></td>
      <td style="text-align: left">Required token suppression or custom validation rules</td>
      <td style="text-align: left">Automatically allowed (missing Fetch Metadata headers)</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="2-the-5-rule-evaluation-algorithm">2. The 5-Rule Evaluation Algorithm</h2>

<p>The <code class="language-plaintext highlighter-rouge">CsrfProtectionMiddleware</code> evaluates incoming requests early in the pipeline using a deterministic, 5-step decision hierarchy:</p>

<ol>
  <li><strong>Safe HTTP Verbs:</strong> <code class="language-plaintext highlighter-rouge">GET</code>, <code class="language-plaintext highlighter-rouge">HEAD</code>, <code class="language-plaintext highlighter-rouge">OPTIONS</code>, and <code class="language-plaintext highlighter-rouge">TRACE</code> are permitted unconditionally (RFC 9110 §9.2.1).</li>
  <li><strong>Same-Origin &amp; Direct Navigations:</strong> Requests where <code class="language-plaintext highlighter-rouge">Sec-Fetch-Site</code> is <code class="language-plaintext highlighter-rouge">same-origin</code> or <code class="language-plaintext highlighter-rouge">none</code> (user typed URL, clicked bookmark, or navigated same-site) are allowed.</li>
  <li><strong>CORS-Approved Origins:</strong> Cross-origin requests with an <code class="language-plaintext highlighter-rouge">Origin</code> header matching the endpoint’s configured CORS policy are allowed.</li>
  <li><strong>Non-Browser Clients:</strong> Requests lacking both <code class="language-plaintext highlighter-rouge">Sec-Fetch-Site</code> and <code class="language-plaintext highlighter-rouge">Origin</code> headers (e.g., cURL, Postman, mobile native SDKs, server-to-server callers) pass through, as CSRF is strictly a browser-based attack vector.</li>
  <li><strong>Unsafe Cross-Site Requests:</strong> Any remaining request (e.g., cross-site <code class="language-plaintext highlighter-rouge">POST</code>, <code class="language-plaintext highlighter-rouge">PUT</code>, <code class="language-plaintext highlighter-rouge">DELETE</code>, <code class="language-plaintext highlighter-rouge">PATCH</code> missing explicit CORS approval) is marked invalid and rejected with an <strong>HTTP 400 Bad Request</strong>.</li>
</ol>

<hr />

<h2 id="3-impact-across-all-blazor-render-modes">3. Impact Across All Blazor Render Modes</h2>

<h3 id="static-server-side-rendering-static-ssr">Static Server-Side Rendering (Static SSR)</h3>
<ul>
  <li><strong>Standard Forms:</strong> Plain HTML <code class="language-plaintext highlighter-rouge">&lt;form action="..." method="post"&gt;</code> submissions within static components no longer require hidden token fields or <code class="language-plaintext highlighter-rouge">@attribute [RequireAntiforgeryToken]</code>.</li>
  <li><strong>Automatic Form Validation:</strong> The form mapping infrastructure checks <code class="language-plaintext highlighter-rouge">IAntiforgeryValidationFeature</code> deferred state. Same-origin form posts succeed automatically.</li>
</ul>

<h3 id="interactive-server-signalr">Interactive Server (SignalR)</h3>
<ul>
  <li><strong>Initial Connection Handshake:</strong> The initial HTTP negotiation request (<code class="language-plaintext highlighter-rouge">/blazor/negotiate</code>) is evaluated by the CSRF middleware. Because it originates from the app’s same origin, it passes automatically.</li>
  <li><strong>WebSocket Upgrade:</strong> Once established, WebSocket frames transmit state directly without additional CSRF overhead.</li>
</ul>

<h3 id="interactive-webassembly-blazor-wasm">Interactive WebAssembly (Blazor WASM)</h3>
<ul>
  <li><strong>Hosted WASM (Same-Origin):</strong> When hosted ASP.NET Core apps serve the Blazor WASM client on the same domain/port, all <code class="language-plaintext highlighter-rouge">HttpClient</code> calls send <code class="language-plaintext highlighter-rouge">Sec-Fetch-Site: same-origin</code> and require zero special configuration.</li>
  <li><strong>Standalone WASM (Cross-Origin APIs):</strong> If the client runs on <code class="language-plaintext highlighter-rouge">https://app.example.com</code> and communicates with <code class="language-plaintext highlighter-rouge">https://api.example.com</code>:
    <ul>
      <li>Cross-origin <code class="language-plaintext highlighter-rouge">POST</code>/<code class="language-plaintext highlighter-rouge">PUT</code>/<code class="language-plaintext highlighter-rouge">DELETE</code> calls will be blocked by default.</li>
      <li><strong>Solution:</strong> Configure a default CORS policy on the API backend to trust the client origin, or adopt a <strong>Backend-for-Frontend (BFF)</strong> reverse proxy pattern.</li>
    </ul>
  </li>
</ul>

<h3 id="interactive-auto-mode-ssr--webassemblyserver">Interactive Auto Mode (SSR + WebAssembly/Server)</h3>
<ul>
  <li><strong>Pre-rendering to Interactivity Transition:</strong> Handles state transition without token mismatch errors. Whether the request is an initial SSR form submit or a client-side fetch, same-origin Fetch Metadata headers guarantee validation.</li>
</ul>

<h3 id="blazor-hybrid-maui--desktop-webviews">Blazor Hybrid (MAUI &amp; Desktop WebViews)</h3>
<ul>
  <li><strong>WebView Behavior:</strong> Native WebViews (MAUI Blazor, Capacitor) may emit <code class="language-plaintext highlighter-rouge">Sec-Fetch-Site: none</code> or omit headers entirely depending on the OS platform.</li>
  <li><strong>Validation outcome:</strong> Missing headers pass through under Rule 4 (Non-Browser), ensuring native desktop and mobile hybrid apps continue working cleanly.</li>
</ul>

<hr />

<h2 id="4-endpoints--exemption-strategies">4. Endpoints &amp; Exemption Strategies</h2>

<h3 id="exempting-third-party-callbacks--webhooks">Exempting Third-Party Callbacks &amp; Webhooks</h3>
<p>Third-party providers (e.g., Stripe webhooks, Entra ID / OAuth <code class="language-plaintext highlighter-rouge">form_post</code> logins) send cross-origin <code class="language-plaintext highlighter-rouge">POST</code> requests to your app without CORS headers. These specific endpoints must opt out of CSRF protection:</p>

<h4 id="minimal-api-endpoints">Minimal API Endpoints:</h4>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">app</span><span class="p">.</span><span class="nf">MapPost</span><span class="p">(</span><span class="s">"/api/webhooks/stripe"</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="n">Results</span><span class="p">.</span><span class="nf">Ok</span><span class="p">())</span>
   <span class="p">.</span><span class="nf">DisableAntiforgery</span><span class="p">();</span>
</code></pre></div></div>

<h4 id="razor-components--controller-actions">Razor Components &amp; Controller Actions:</h4>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@attribute</span> <span class="p">[</span><span class="n">IgnoreAntiforgeryToken</span><span class="p">]</span>
</code></pre></div></div>

<h3 id="cors-trust-configuration-for-spas--wasm">CORS Trust Configuration for SPAs &amp; WASM</h3>
<p>To permit cross-origin requests from trusted frontends without disabling CSRF globally:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">builder</span><span class="p">.</span><span class="n">Services</span><span class="p">.</span><span class="nf">AddCors</span><span class="p">(</span><span class="n">options</span> <span class="p">=&gt;</span>
<span class="p">{</span>
    <span class="n">options</span><span class="p">.</span><span class="nf">AddDefaultPolicy</span><span class="p">(</span><span class="n">policy</span> <span class="p">=&gt;</span>
    <span class="p">{</span>
        <span class="n">policy</span><span class="p">.</span><span class="nf">WithOrigins</span><span class="p">(</span><span class="s">"https://my-blazor-wasm-app.com"</span><span class="p">)</span>
              <span class="p">.</span><span class="nf">AllowAnyHeader</span><span class="p">()</span>
              <span class="p">.</span><span class="nf">AllowAnyMethod</span><span class="p">();</span>
    <span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>

<hr />

<h2 id="5-development--testing-recommendations">5. Development &amp; Testing Recommendations</h2>

<ol>
  <li><strong>Avoid <code class="language-plaintext highlighter-rouge">HttpClient</code> Only Tests for Security Automation:</strong> Automated integration tests using raw <code class="language-plaintext highlighter-rouge">HttpClient</code> do not emit browser <code class="language-plaintext highlighter-rouge">Sec-Fetch-Site</code> headers and will pass through Rule 4. Test browser authentication flows using Playwright or Selenium.</li>
  <li><strong>Dev Server Proxying:</strong> In multi-project solutions where the WASM client dev server runs on <code class="language-plaintext highlighter-rouge">localhost:5001</code> and the API on <code class="language-plaintext highlighter-rouge">localhost:7001</code>, configure launch settings or reverse proxies to avoid cross-origin dev breakage.</li>
  <li><strong>Diagnostic Opt-Out:</strong> If unexpected 400 errors occur during migration, set <code class="language-plaintext highlighter-rouge">DisableCsrfProtection</code> in app configuration as a temporary diagnostic step to isolate whether CSRF middleware is the cause.</li>
</ol>]]></content><author><name></name></author><category term="net11" /><category term="core" /><category term="net" /><category term="blazor" /><category term="crrf" /><category term="security" /><category term="owasp" /><category term="blazor" /><category term="core" /><category term="net" /><category term="net11" /><category term="crrf" /><category term="security" /><category term="owasp" /><summary type="html"><![CDATA[Comprehensive Guide: .NET 11 Automatic CSRF Protection Across All Blazor Render Modes]]></summary></entry><entry><title type="html">Blazor SSR and C# 11: Feature Adoption Guide</title><link href="https://aeleftheriadis.github.io/Blazor_SSR_CSharp11_Guide/" rel="alternate" type="text/html" title="Blazor SSR and C# 11: Feature Adoption Guide" /><published>2026-09-13T00:00:00+00:00</published><updated>2026-09-13T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/Blazor_SSR_CSharp11_Guide</id><content type="html" xml:base="https://aeleftheriadis.github.io/Blazor_SSR_CSharp11_Guide/"><![CDATA[<h1 id="blazor-ssr-and-c-11-feature-adoption-guide">Blazor SSR and C# 11: Feature Adoption Guide</h1>

<p>This document outlines how we are adopting <strong>C# 11 features</strong> to improve our Server-Side Rendered (SSR) Blazor components. By leveraging these modern language features, we can reduce boilerplate, improve component safety, and make our markup and code-behind much cleaner.</p>

<hr />

<h2 id="1-enforcing-component-parameters-with-required">1. Enforcing Component Parameters with <code class="language-plaintext highlighter-rouge">required</code></h2>

<p>Previously, ensuring that a consumer provided a necessary <code class="language-plaintext highlighter-rouge">[Parameter]</code> to a Blazor component required runtime checks, <code class="language-plaintext highlighter-rouge">OnInitialized</code> validation, or editor-only nullable warnings. C# 11 introduces the <code class="language-plaintext highlighter-rouge">required</code> modifier, which enforces initialization at compile time.</p>

<p><strong>Old Approach (Pre-C# 11):</strong></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@code</span> <span class="p">{</span>
    <span class="p">[</span><span class="n">Parameter</span><span class="p">]</span>
    <span class="k">public</span> <span class="kt">string</span> <span class="n">Title</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span> <span class="p">=</span> <span class="k">default</span><span class="p">!;</span> <span class="c1">// Relies on runtime checks or nullable suppression</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>New SSR Approach (C# 11):</strong></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@code</span> <span class="p">{</span>
    <span class="p">[</span><span class="n">Parameter</span><span class="p">]</span>
    <span class="k">public</span> <span class="n">required</span> <span class="kt">string</span> <span class="n">Title</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p><em>Benefit:</em> The compiler will now guarantee that <code class="language-plaintext highlighter-rouge">Title</code> is provided when the component is instantiated, leading to safer SSR components and fewer null reference exceptions during the render tree construction.</p>

<hr />

<h2 id="2-cleaner-inline-scripts-and-styles-with-raw-string-literals">2. Cleaner Inline Scripts and Styles with Raw String Literals</h2>

<p>When writing SSR components, you sometimes need to output small chunks of inline JavaScript or CSS from the <code class="language-plaintext highlighter-rouge">@code</code> block. Previously, this meant dealing with messy escape characters, especially for quotes and curly braces. C# 11’s raw string literals (<code class="language-plaintext highlighter-rouge">\"\"\"</code>) solve this beautifully.</p>

<p><strong>Old Approach:</strong></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@code</span> <span class="p">{</span>
    <span class="k">private</span> <span class="kt">string</span> <span class="nf">GetInlineScript</span><span class="p">()</span> <span class="p">=&gt;</span> 
        <span class="s">"&lt;script&gt;console.log(\"Hello from SSR Component\"); function log(obj) { console.log(obj); }&lt;/script&gt;"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>New SSR Approach (C# 11):</strong></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@code</span> <span class="p">{</span>
    <span class="k">private</span> <span class="kt">string</span> <span class="nf">GetInlineScript</span><span class="p">()</span> <span class="p">=&gt;</span> <span class="err">\</span><span class="s">"\"\"
</span>        <span class="p">&lt;</span><span class="n">script</span><span class="p">&gt;</span>
            <span class="n">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s">"Hello from SSR Component"</span><span class="p">);</span>
            <span class="n">function</span> <span class="nf">log</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="n">obj</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">&lt;/</span><span class="n">script</span><span class="p">&gt;</span>
        <span class="err">\</span><span class="s">"\"\";
</span><span class="p">}</span>
</code></pre></div></div>
<p><em>Benefit:</em> You can paste raw HTML, JS, or CSS directly into your C# variables without altering quotes or manually escaping brackets. String interpolation can also be customized by adding more <code class="language-plaintext highlighter-rouge">$</code> signs.</p>

<hr />

<h2 id="3-cleaner-component-metadata-via-generic-attributes">3. Cleaner Component Metadata via Generic Attributes</h2>

<p>Blazor relies heavily on attributes for routing (<code class="language-plaintext highlighter-rouge">[Route]</code>), cascading values, and authorization (<code class="language-plaintext highlighter-rouge">[Authorize]</code>). If you have custom attributes for your SSR components (e.g., for metadata, layout specification, or custom SSR caching rules), C# 11 generic attributes make them strongly typed.</p>

<p><strong>New SSR Approach (C# 11):</strong></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Definition</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">RequireServiceAttribute</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">Attribute</span> <span class="k">where</span> <span class="n">T</span> <span class="p">:</span> <span class="k">class</span> <span class="err">{</span> <span class="err">}</span>

<span class="c1">// Usage in Blazor component</span>
<span class="nc">@attribute</span> <span class="p">[</span><span class="n">RequireService</span><span class="p">&lt;</span><span class="n">IWeatherForecastService</span><span class="p">&gt;]</span>

<span class="n">@code</span> <span class="p">{</span>
    <span class="c1">// Component logic</span>
<span class="p">}</span>
</code></pre></div></div>
<p><em>Benefit:</em> Avoids <code class="language-plaintext highlighter-rouge">typeof()</code> calls in attributes, making the code more readable and compile-time safe.</p>

<hr />

<h2 id="4-simplified-pattern-matching-with-list-patterns">4. Simplified Pattern Matching with List Patterns</h2>

<p>When processing route data, breadcrumbs, or hierarchical data in SSR components, you often need to parse arrays or lists. C# 11 List Patterns allow you to match sequences cleanly directly inside the <code class="language-plaintext highlighter-rouge">@code</code> block.</p>

<p><strong>New SSR Approach (C# 11):</strong></p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@code</span> <span class="p">{</span>
    <span class="p">[</span><span class="n">Parameter</span><span class="p">]</span> <span class="k">public</span> <span class="n">required</span> <span class="kt">string</span><span class="p">[]</span> <span class="n">RouteSegments</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnParametersSet</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="kt">var</span> <span class="n">pageType</span> <span class="p">=</span> <span class="n">RouteSegments</span> <span class="k">switch</span>
        <span class="p">{</span>
            <span class="p">[</span><span class="s">"users"</span><span class="p">,</span> <span class="kt">var</span> <span class="n">userId</span><span class="p">]</span> <span class="p">=&gt;</span> <span class="s">$"User Profile: </span><span class="p">{</span><span class="n">userId</span><span class="p">}</span><span class="s">"</span><span class="p">,</span>
            <span class="p">[</span><span class="s">"users"</span><span class="p">,</span> <span class="kt">var</span> <span class="n">userId</span><span class="p">,</span> <span class="s">"settings"</span><span class="p">]</span> <span class="p">=&gt;</span> <span class="s">$"Settings for </span><span class="p">{</span><span class="n">userId</span><span class="p">}</span><span class="s">"</span><span class="p">,</span>
            <span class="p">[</span><span class="s">"admin"</span><span class="p">,</span> <span class="p">..]</span> <span class="p">=&gt;</span> <span class="s">"Admin Section"</span><span class="p">,</span>
            <span class="n">_</span> <span class="p">=&gt;</span> <span class="s">"Unknown Route"</span>
        <span class="p">};</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p><em>Benefit:</em> Greatly simplifies complex routing or hierarchical rendering logic without writing verbose <code class="language-plaintext highlighter-rouge">if/else</code> checks.</p>

<hr />

<h2 id="5-file-scoped-types-for-component-helpers">5. File-Scoped Types for Component Helpers</h2>

<p>Sometimes a Blazor SSR component needs a small helper DTO or class that shouldn’t be exposed to the rest of the assembly. C# 11 allows <code class="language-plaintext highlighter-rouge">file</code> scoped types, which are perfect for component-specific helper structures.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">@code</span> <span class="p">{</span>
    <span class="c1">// This class is only visible within this specific .razor file's generated class context </span>
    <span class="c1">// (when using partial classes or code-behind files).</span>
    <span class="n">file</span> <span class="k">class</span> <span class="nc">ComponentState</span>
    <span class="p">{</span>
        <span class="k">public</span> <span class="kt">bool</span> <span class="n">IsLoading</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
        <span class="k">public</span> <span class="n">required</span> <span class="kt">string</span> <span class="n">ErrorMessage</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<hr />

<h2 id="summary-of-guidelines-for-the-team">Summary of Guidelines for the Team</h2>

<ol>
  <li><strong>Always</strong> use <code class="language-plaintext highlighter-rouge">required</code> for mandatory <code class="language-plaintext highlighter-rouge">[Parameter]</code> properties.</li>
  <li><strong>Use</strong> raw string literals (<code class="language-plaintext highlighter-rouge">\"\"\"</code>) for any HTML/JS/CSS embedded in C# code-behind.</li>
  <li><strong>Refactor</strong> old <code class="language-plaintext highlighter-rouge">typeof(T)</code> attributes to use Generic Attributes where custom attributes are used.</li>
  <li><strong>Leverage</strong> list patterns for complex array/list data manipulation before the SSR render pass.</li>
</ol>]]></content><author><name></name></author><category term="net11" /><category term="core" /><category term="net" /><category term="blazor" /><category term="ssr" /><category term="blazor" /><category term="core" /><category term="net" /><category term="net11" /><category term="ssr" /><summary type="html"><![CDATA[Blazor SSR and C# 11: Feature Adoption Guide]]></summary></entry><entry><title type="html">A Deep Dive into the Future of ASP.NET Core &amp;amp; Blazor in .NET 11</title><link href="https://aeleftheriadis.github.io/dotnet_11_aspnet_blazor_future-v2/" rel="alternate" type="text/html" title="A Deep Dive into the Future of ASP.NET Core &amp;amp; Blazor in .NET 11" /><published>2026-09-13T00:00:00+00:00</published><updated>2026-09-13T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/dotnet_11_aspnet_blazor_future-v2</id><content type="html" xml:base="https://aeleftheriadis.github.io/dotnet_11_aspnet_blazor_future-v2/"><![CDATA[<h1 id="a-deep-dive-into-the-future-of-aspnet-core--blazor-in-net-11">A Deep Dive into the Future of ASP.NET Core &amp; Blazor in .NET 11</h1>

<h2 id="introduction">Introduction</h2>

<p>As web development continues to evolve at a rapid pace, Microsoft’s .NET ecosystem remains at the forefront of modern application architecture [cite: 1]. Following major evolutionary shifts in previous releases—most notably the full-stack unification introduced in .NET 8—.NET 11 focuses heavily on filling developer pain points, bridging architectural gaps, enhancing full-stack capabilities, and optimizing for modern AI-assisted engineering [cite: 1].</p>

<p>This highly detailed guide delivers an exhaustive breakdown of everything discussed regarding the future of ASP.NET Core and Blazor in .NET 11. It draws from engineering roadmap updates, preview releases, and community discussions, and concludes with an actionable migration guide for existing applications [cite: 1].</p>

<hr />

<h2 id="1-core-architectural-themes-for-net-11">1. Core Architectural Themes for .NET 11</h2>

<p>The overarching goals for ASP.NET Core and Blazor in .NET 11 target fundamental developer needs:</p>

<ul>
  <li><strong>Developer Productivity &amp; Ergonomics:</strong> Eliminating repetitive boilerplate code such as manual environment checks or custom base href configurations [cite: 1]. The goal is to make the framework do the heavy lifting.</li>
  <li><strong>WebAssembly Runtime Consolidation &amp; Parity:</strong> Bringing advanced runtime features and background processing capabilities to browser-based applications [cite: 1]. This ensures that WASM apps behave closer to server-native applications.</li>
  <li><strong>Enhanced Server-Side Rendering (SSR):</strong> Refining full-stack integration, routing flexibility, and state handling (such as TempData support) for static rendering scenarios [cite: 1].</li>
  <li><strong>Ecosystem Integration:</strong> Deepening ties with <strong>Microsoft Aspire</strong> for distributed cloud-native applications and introducing better tooling for AI-driven development and agentic UI paradigms [cite: 1].</li>
</ul>

<hr />

<h2 id="2-key-blazor-enhancements--new-components">2. Key Blazor Enhancements &amp; New Components</h2>

<h3 id="21-the-new-environmentboundary-component">2.1 The New <code class="language-plaintext highlighter-rouge">EnvironmentBoundary</code> Component</h3>
<p>In previous versions, handling environment-specific rendering—such as showing diagnostic panels only in development or specific cloud regions—required explicit C# code checks or passing cascading parameters down the component tree [cite: 1].</p>

<ul>
  <li><strong>What’s New:</strong> The new <code class="language-plaintext highlighter-rouge">EnvironmentBoundary</code> component allows developers to conditionally render markup based on the current hosting environment natively within Razor [cite: 1].</li>
  <li><strong>Features:</strong> It accepts explicit <code class="language-plaintext highlighter-rouge">Include</code> and <code class="language-plaintext highlighter-rouge">Exclude</code> parameters (e.g., <code class="language-plaintext highlighter-rouge">&lt;EnvironmentBoundary Include="Development"&gt;...&lt;/EnvironmentBoundary&gt;</code>) [cite: 1]. It operates consistently across both Blazor Server and Blazor WebAssembly, ensuring uniform behavior across render modes [cite: 1].</li>
</ul>

<h3 id="22-form-upgrades-label-and-displayname-components">2.2 Form Upgrades: <code class="language-plaintext highlighter-rouge">Label</code> and <code class="language-plaintext highlighter-rouge">DisplayName</code> Components</h3>
<p>A long-standing request from the community has been streamlined form labelling tied directly to data annotations [cite: 1]. Forms in Blazor are receiving a major ergonomic and accessibility boost.</p>

<ul>
  <li><strong><code class="language-plaintext highlighter-rouge">Label</code> Component:</strong> Automatically renders accessible HTML <code class="language-plaintext highlighter-rouge">&lt;label&gt;</code> tags with automatic association to input controls [cite: 1]. This supports both nested and non-nested HTML patterns natively [cite: 1].</li>
  <li><strong><code class="language-plaintext highlighter-rouge">DisplayName</code> Component:</strong> Functions similarly to traditional MVC <code class="language-plaintext highlighter-rouge">@Html.DisplayNameFor()</code> helpers [cite: 1]. It extracts display names from model attributes (like <code class="language-plaintext highlighter-rouge">[Display(Name = "...")]</code> or <code class="language-plaintext highlighter-rouge">[DisplayName(...)]</code>) [cite: 1]. Crucially, it features full localization support via resource types, making multi-language form generation trivial [cite: 1].</li>
</ul>

<h3 id="23-quickgrid-enhancements">2.3 QuickGrid Enhancements</h3>
<p>The native lightweight <code class="language-plaintext highlighter-rouge">QuickGrid</code> component receives a crucial interactive upgrade with the addition of the <strong><code class="language-plaintext highlighter-rouge">OnRowClick</code></strong> event parameter [cite: 1].</p>

<ul>
  <li>Configuring this automatically handles row-click behaviors without needing complex DOM event wiring [cite: 1].</li>
  <li>It updates cursor styling to a pointer contextually [cite: 1].</li>
  <li>It passes the targeted data item straight to the callback method, vastly simplifying master-detail views [cite: 1].</li>
</ul>

<h3 id="24-navigation--routing-improvements">2.4 Navigation &amp; Routing Improvements</h3>
<p>Routing robustness is a major theme in .NET 11.</p>

<ul>
  <li><strong><code class="language-plaintext highlighter-rouge">RelativeToCurrentUri</code> Parameter:</strong> Both <code class="language-plaintext highlighter-rouge">NavigationManager.NavigateTo()</code> and the <code class="language-plaintext highlighter-rouge">NavLink</code> component now accept a <code class="language-plaintext highlighter-rouge">RelativeToCurrentUri</code> parameter [cite: 1]. When enabled, relative path transitions resolve against the active path in nested directory trees instead of reverting to the application base URI root, fixing a common routing annoyance [cite: 1].</li>
  <li><strong><code class="language-plaintext highlighter-rouge">GetUriWithHash()</code>:</strong> A new high-performance, zero-allocation extension method for appending hash fragments to URI strings, useful for anchor linking [cite: 1].</li>
  <li><strong><code class="language-plaintext highlighter-rouge">BasePath</code> Component:</strong> Automatically renders the required app base path HTML elements (like <code class="language-plaintext highlighter-rouge">&lt;base href="..." /&gt;</code>), removing manual script configuration overhead [cite: 1].</li>
</ul>

<hr />

<h2 id="3-blazor-webassembly--performance-evolution">3. Blazor WebAssembly &amp; Performance Evolution</h2>

<h3 id="31-background-processing-with-ihostedservice">3.1 Background Processing with <code class="language-plaintext highlighter-rouge">IHostedService</code></h3>
<p>Historically, scheduling recurring tasks, background polling, or caching inside a browser-based Blazor WebAssembly application required awkward component-lifecycle timers or custom singleton wrappers [cite: 1].</p>

<ul>
  <li><strong>What’s New:</strong> .NET 11 brings <code class="language-plaintext highlighter-rouge">IHostedService</code> and <code class="language-plaintext highlighter-rouge">BackgroundService</code> support directly to Blazor WebAssembly [cite: 1].</li>
  <li><strong>Impact:</strong> This achieves feature parity with Blazor Server and backend ASP.NET Core apps [cite: 1]. Services launch natively with the application startup and execute independently of individual component navigations, ideal for background data syncing [cite: 1].</li>
</ul>

<h3 id="32-multithreading-via-the-web-worker-template">3.2 Multithreading via The Web Worker Template</h3>
<p>Because WebAssembly runs on a single-threaded execution model in the browser, intensive CPU operations (such as heavy math computations, cryptography, image processing, or data sorting) can freeze the UI [cite: 1].</p>

<ul>
  <li><strong>What’s New:</strong> .NET 11 introduces the <code class="language-plaintext highlighter-rouge">dotnet new webworker</code> template to address this fundamental limitation [cite: 1].</li>
  <li><strong>Architecture:</strong> It scaffolds a Razor class library packed with the JavaScript interop plumbing necessary to run .NET code inside a dedicated browser Web Worker thread [cite: 1].</li>
  <li><strong>Usage:</strong> Utilizing a <code class="language-plaintext highlighter-rouge">WebWorkerClient</code> factory pattern and <code class="language-plaintext highlighter-rouge">[JSExport]</code> attributes, developers can offload heavy processing entirely off the main UI thread, keeping applications fluid and responsive [cite: 1].</li>
</ul>

<h3 id="33-runtime-configuration">3.3 Runtime Configuration</h3>
<p>Blazor WebAssembly apps can now read environment variables directly through standard <code class="language-plaintext highlighter-rouge">IConfiguration</code> mechanisms at runtime [cite: 1]. This removes rigid compile-time constraints, allowing deployments across multiple environments without needing to rebuild the WASM binaries [cite: 1].</p>

<hr />

<h2 id="4-aspnet-core-backend-and-infrastructure-updates">4. ASP.NET Core Backend and Infrastructure Updates</h2>

<h3 id="41-tempdata-support-in-static-ssr">4.1 TempData Support in Static SSR</h3>
<p>Static Server-Side Rendering (SSR) models gain native <strong>TempData</strong> integration [cite: 1].</p>
<ul>
  <li><strong>Implementation:</strong> It is accessible directly as a cascading parameter (<code class="language-plaintext highlighter-rouge">[CascadingParameter] public ITempData? TempData { get; set; }</code>) [cite: 1].</li>
  <li><strong>Impact:</strong> This dramatically simplifies post-redirect flash messaging (e.g., “Item saved successfully”) and workflow state management without requiring manual session plumbing or client-side interop [cite: 1].</li>
</ul>

<h3 id="42-security-and-project-template-adjustments">4.2 Security and Project Template Adjustments</h3>
<ul>
  <li><strong>CSP Compliance in NavMenu:</strong> Inline JavaScript event handlers previously used to toggle navigation bars in default project templates have been entirely removed [cite: 1]. Templates now leverage collocated JavaScript modules, drastically improving Content Security Policy (CSP) compliance out of the box and promoting better security practices [cite: 1].</li>
  <li><strong>Development Certificates:</strong> Automatic trust support for development certificates within WSL (Windows Subsystem for Linux) environments has been introduced, smoothing local cross-platform setup workflows [cite: 1].</li>
  <li><strong>OpenAPI &amp; Caching:</strong> The release brings improved OpenAPI schema support for binary file responses and introduces the <code class="language-plaintext highlighter-rouge">IOutputCachePolicyProvider</code> interface for highly granular caching control [cite: 1].</li>
</ul>

<hr />

<h2 id="5-cloud-native--ai-assisted-horizons-net-aspire--agentic-ui">5. Cloud-Native &amp; AI-Assisted Horizons (.NET Aspire &amp; Agentic UI)</h2>

<p>Beyond standard web features, the .NET 11 roadmap emphasizes distributed app design and next-gen engineering patterns:</p>

<ul>
  <li><strong>Blazor ❤️s Aspire:</strong> Tightening integration with <strong>Microsoft Aspire</strong> makes orchestration, telemetry, and distributed microservice monitoring seamless for Blazor-centric architectures [cite: 1].</li>
  <li><strong>Blazor Gateway:</strong> Microsoft is exploring unified routing and gateway topologies specifically designed for modern distributed frontends [cite: 1].</li>
  <li><strong>Agentic UI &amp; AI Development:</strong> The framework is engineering internal support for AI-assisted development workflows, dynamic component generation, and intelligent UI patterns designed for autonomous coding agents [cite: 1].</li>
</ul>

<hr />

<h2 id="6-migration-guide-upgrading-existing-apps-to-net-11-features">6. Migration Guide: Upgrading Existing Apps to .NET 11 Features</h2>

<p>When preparing to move an existing ASP.NET Core or Blazor application to .NET 11, consider making the following architectural and code-level updates to take full advantage of the new capabilities.</p>

<h3 id="step-1-update-csp-and-navigation-layouts">Step 1: Update CSP and Navigation Layouts</h3>
<p>If your app originated from an older Blazor template, your <code class="language-plaintext highlighter-rouge">NavMenu.razor</code> likely relies on inline <code class="language-plaintext highlighter-rouge">onclick</code> handlers for toggling the mobile menu.</p>
<ul>
  <li><strong>Action:</strong> Remove inline Javascript (<code class="language-plaintext highlighter-rouge">onclick="toggleNavMenu"</code>). Move the toggling logic to a collocated Javascript file (e.g., <code class="language-plaintext highlighter-rouge">NavMenu.razor.js</code>) [cite: 1]. This allows you to enforce strict Content Security Policies (CSP) [cite: 1].</li>
</ul>

<h3 id="step-2-simplify-environment-checks">Step 2: Simplify Environment Checks</h3>
<p>Review your codebase for manual environment checks (<code class="language-plaintext highlighter-rouge">if (Environment.IsDevelopment())</code>).</p>
<ul>
  <li><strong>Action:</strong> Replace conditional HTML wrappers in your <code class="language-plaintext highlighter-rouge">.razor</code> files with the new <code class="language-plaintext highlighter-rouge">&lt;EnvironmentBoundary&gt;</code> component [cite: 1].</li>
  <li><strong>Example:</strong> Wrap your debug tools or Swagger links in <code class="language-plaintext highlighter-rouge">&lt;EnvironmentBoundary Include="Development"&gt; ... &lt;/EnvironmentBoundary&gt;</code> [cite: 1].</li>
</ul>

<h3 id="step-3-refactor-forms-for-better-validation-and-accessibility">Step 3: Refactor Forms for Better Validation and Accessibility</h3>
<p>Look at your <code class="language-plaintext highlighter-rouge">EditForm</code> implementations.</p>
<ul>
  <li><strong>Action:</strong> Replace hardcoded HTML <code class="language-plaintext highlighter-rouge">&lt;label&gt;</code> elements with the new <code class="language-plaintext highlighter-rouge">&lt;Label&gt;</code> and <code class="language-plaintext highlighter-rouge">&lt;DisplayName&gt;</code> components [cite: 1].</li>
  <li><strong>Benefit:</strong> This automatically links labels to inputs and pulls text directly from your Model’s <code class="language-plaintext highlighter-rouge">[Display(Name="...")]</code> attributes, ensuring uniform localization and accessibility [cite: 1].</li>
</ul>

<h3 id="step-4-adopt-tempdata-for-static-ssr">Step 4: Adopt TempData for Static SSR</h3>
<p>If you are utilizing Static Server-Side Rendering (SSR) and struggling with state retention after form submissions.</p>
<ul>
  <li><strong>Action:</strong> Inject <code class="language-plaintext highlighter-rouge">[CascadingParameter] public ITempData? TempData { get; set; }</code> into your target component [cite: 1]. Use this to store and read flash messages post-redirect without relying on URL query strings or custom session state [cite: 1].</li>
</ul>

<h3 id="step-5-offload-blocking-code-to-web-workers">Step 5: Offload Blocking Code to Web Workers</h3>
<p>Identify areas in your Blazor WebAssembly app that cause the UI to freeze (e.g., heavy client-side filtering, file parsing, or complex math).</p>
<ul>
  <li><strong>Action:</strong> Use the new <code class="language-plaintext highlighter-rouge">dotnet new webworker</code> template to create a separate project for these tasks [cite: 1]. Move the heavy computation to this project and use the <code class="language-plaintext highlighter-rouge">WebWorkerClient</code> interop to invoke these methods asynchronously [cite: 1].</li>
</ul>

<hr />

<h2 id="conclusion">Conclusion</h2>

<p>The evolution of ASP.NET Core and Blazor in .NET 11 represents a mature, pragmatic leap forward [cite: 1]. Rather than introducing disruptive breaking paradigms, Microsoft is actively listening to developer feedback—closing feature gaps (like form labelling and background services), enhancing WebAssembly concurrency via Web Workers, and solidifying full-stack ergonomics [cite: 1].</p>

<p>Whether building internal enterprise portals or high-performance consumer web applications, .NET 11 equips C# developers with a faster, safer, and deeply unified web development platform [cite: 1].</p>]]></content><author><name></name></author><category term="net11" /><category term="core" /><category term="net" /><category term="blazor" /><category term="blazor" /><category term="core" /><category term="net" /><category term="net11" /><summary type="html"><![CDATA[A Deep Dive into the Future of ASP.NET Core & Blazor in .NET 11]]></summary></entry><entry><title type="html">Copilot Resources</title><link href="https://aeleftheriadis.github.io/copilot/" rel="alternate" type="text/html" title="Copilot Resources" /><published>2026-03-29T00:00:00+00:00</published><updated>2026-03-29T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/copilot</id><content type="html" xml:base="https://aeleftheriadis.github.io/copilot/"><![CDATA[<h1 id="copilot-resources">Copilot Resources</h1>

<ul>
  <li><a href="https://devblogs.microsoft.com/dotnet/prompt-files-and-instructions-files-explained/">Prompt Files and Instructions Files Explained</a></li>
  <li><a href="https://github.blog/ai-and-ml/github-copilot/a-cheat-sheet-to-slash-commands-in-github-copilot-cli/">A cheat sheet to slash commands in GitHub Copilot CLI</a></li>
  <li><a href="https://github.blog/ai-and-ml/github-copilot/power-agentic-workflows-in-your-terminal-with-github-copilot-cli/">Power agentic workflows in your terminal with GitHub Copilot CLI</a></li>
</ul>

<h1 id="copilot-skills">Copilot Skills</h1>

<ul>
  <li><a href="https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-skills#creating-and-adding-a-skill">Creating and adding skills</a></li>
  <li><a href="https://devblogs.microsoft.com/dotnet/extend-your-coding-agent-with-dotnet-skills/">Extend your coding agent with .NET Skills</a></li>
  <li><a href="https://developer.microsoft.com/blog/get-started-with-github-copilot-cli-a-free-hands-on-course">Get started with GitHub Copilot CLI: A free, hands-on course</a></li>
</ul>

<h1 id="copilot-testing">Copilot Testing</h1>
<ul>
  <li><a href="https://devblogs.microsoft.com/dotnet/github-copilot-testing-for-dotnet-available-in-visual-studio/">GitHub Copilot Testing for .NET Brings AI-powered Unit Tests to Visual Studio 2026</a></li>
</ul>]]></content><author><name></name></author><category term="copilot" /><category term="net" /><category term="testing" /><category term="copilot" /><category term="net" /><category term="testing" /><summary type="html"><![CDATA[Copilot Resources]]></summary></entry><entry><title type="html">EF Core Best Practices Resources</title><link href="https://aeleftheriadis.github.io/ef-core/" rel="alternate" type="text/html" title="EF Core Best Practices Resources" /><published>2026-03-29T00:00:00+00:00</published><updated>2026-03-29T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/ef-core</id><content type="html" xml:base="https://aeleftheriadis.github.io/ef-core/"><![CDATA[<h1 id="ef-core-best-practices-resources">EF Core Best Practices Resources</h1>

<p><a href="https://codewithmukesh.com/blog/pagination-sorting-searching-aspnet-core-webapi">Pagination, Sorting &amp; Searching in ASP.NET Core Web API</a></p>]]></content><author><name></name></author><category term="efcore" /><category term="core" /><category term="net" /><category term="pagination" /><category term="efcore" /><category term="core" /><category term="net" /><category term="paggination" /><summary type="html"><![CDATA[EF Core Best Practices Resources]]></summary></entry><entry><title type="html">Gen AI Resources</title><link href="https://aeleftheriadis.github.io/gen-ai/" rel="alternate" type="text/html" title="Gen AI Resources" /><published>2026-03-29T00:00:00+00:00</published><updated>2026-03-29T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/gen-ai</id><content type="html" xml:base="https://aeleftheriadis.github.io/gen-ai/"><![CDATA[<h1 id="gen-ai-resources">Gen AI Resources</h1>

<p><a href="https://devblogs.microsoft.com/dotnet/generative-ai-for-beginners-dotnet-version-2-on-dotnet-10/">Generative AI for Beginners .NET: Version 2 on .NET 10</a></p>]]></content><author><name></name></author><category term="generative-ai" /><category term="generative-ai" /><summary type="html"><![CDATA[Gen AI Resources]]></summary></entry><entry><title type="html">Microsoft Agent Framework Resources</title><link href="https://aeleftheriadis.github.io/microsoft-agent-framework/" rel="alternate" type="text/html" title="Microsoft Agent Framework Resources" /><published>2026-03-29T00:00:00+00:00</published><updated>2026-03-29T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/microsoft-agent-framework</id><content type="html" xml:base="https://aeleftheriadis.github.io/microsoft-agent-framework/"><![CDATA[<h1 id="microsoft-agent-framework-resources">Microsoft Agent Framework Resources</h1>

<p><a href="https://developer.microsoft.com/blog/build-a-real-world-example-with-microsoft-agent-framework-microsoft-foundry-mcp-and-aspire">Build a real-world example with Microsoft Agent Framework, Microsoft Foundry, MCP and Aspire</a></p>]]></content><author><name></name></author><category term="microsoft-agent-framework" /><category term="mcp" /><category term="net" /><category term="microsoft-agent-framework" /><category term="mcp" /><category term="net" /><summary type="html"><![CDATA[Microsoft Agent Framework Resources]]></summary></entry><entry><title type="html">Pass Keys Resources</title><link href="https://aeleftheriadis.github.io/passkeys/" rel="alternate" type="text/html" title="Pass Keys Resources" /><published>2026-03-29T00:00:00+00:00</published><updated>2026-03-29T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/passkeys</id><content type="html" xml:base="https://aeleftheriadis.github.io/passkeys/"><![CDATA[<h1 id="security-pass-keys">Security Pass Keys</h1>

<ul>
  <li><a href="https://duendesoftware.com/blog/20251007-passkeys-in-dotnet-10-blazor-apps-with-aspnet-identity">Passkeys in .NET 10 Blazor Apps with ASP.NET Identity</a></li>
</ul>]]></content><author><name></name></author><category term="security" /><category term="core" /><category term="net" /><category term="passkeys" /><category term="security" /><category term="core" /><category term="net" /><category term="passkeys" /><summary type="html"><![CDATA[Pass Keys Resources]]></summary></entry><entry><title type="html">Server Send Events Resources</title><link href="https://aeleftheriadis.github.io/sse/" rel="alternate" type="text/html" title="Server Send Events Resources" /><published>2026-03-29T00:00:00+00:00</published><updated>2026-03-29T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/sse</id><content type="html" xml:base="https://aeleftheriadis.github.io/sse/"><![CDATA[<h1 id="server-send-events">Server Send Events</h1>

<p><a href="https://thecodeman.net/posts/server-sent-event-in-dotnet">Server-Sent Events in .NET 10 - Real-Time Streaming in .NET</a></p>]]></content><author><name></name></author><category term="sse" /><category term="core" /><category term="net" /><category term="sse" /><category term="core" /><category term="net" /><summary type="html"><![CDATA[Server Send Events Resources]]></summary></entry><entry><title type="html">YARP Resources</title><link href="https://aeleftheriadis.github.io/yarp/" rel="alternate" type="text/html" title="YARP Resources" /><published>2026-03-15T00:00:00+00:00</published><updated>2026-03-15T00:00:00+00:00</updated><id>https://aeleftheriadis.github.io/yarp</id><content type="html" xml:base="https://aeleftheriadis.github.io/yarp/"><![CDATA[<h1 id="yarp-resources">YARP Resources</h1>

<ul>
  <li><a href="https://antondevtips.com/blog/yarp-as-api-gateway-in-dotnet">YARP as API Gateway in .NET: 7 Real-World Scenarios You Should Know</a></li>
</ul>]]></content><author><name></name></author><category term="yarp" /><category term="core" /><category term="net" /><category term="yarp" /><category term="core" /><category term="net" /><summary type="html"><![CDATA[YARP Resources]]></summary></entry></feed>