I want to do the following
I´m on Blazor Web App (server/client)
I need information on what steps are needed to create a new LeptonX Theme for Blazor Hybrid app.
Secondary questions
I´m hoping the AI can answer these super simple questions that I feel the documentation does not answer at all!
I have been battling with this issue for two days now and I need assitance.
Antiforgery token validation failed. Validation of the provided antiforgery token failed. The cookie token and the request token were swapped. Identity.Application was not authenticated. Failure message: Unprotect ticket failed| Item | Details |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| ABP version | 9.2.2 (Commercial) |
| Template | Blazor Hybrid (Account Public + Admin Pro + LeptonX) |
| Elsa Studio | v3 – integrated as standalone WASM under /elsa/… |
| Hosting | Azure Container Apps (ACA) – single container, Linux |
| Ingress | external=true, targetPort=8080, transport=auto |
| Probes | /health (liveness) & /health/ready (readiness/startup) |
| Data Protection | Keys persisted to Azure Blob Storage via Azure.Extensions.AspNetCore.DataProtection.Blobs, user‑assigned managed identity |
| Forwarded Headers | Middleware added first: app.UseForwardedHeaders(); options include XForwardedProto, XForwardedFor, XForwardedHost |
| Antiforgery | HeaderName = "X-XSRF-TOKEN", Cookie.Name = "XSRF-TOKEN", SecurePolicy = Always, SameSite = None |
| DataProtection code | .SetApplicationName("YourSite") + .PersistKeysToAzureBlobStorage(blobClient) |
| Cookies | Application cookie unchanged; antiforgery cookie now present |
HttpOverrides trace shows Scheme=https and correct host!
This is the code I have in my BlazorModule.cs file
ConfigureServices()
// 1️⃣ Forwarded‑Header options (ACA IPs change frequently)
services.Configure<ForwardedHeadersOptions>(o =>
{
o.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost;
o.KnownNetworks.Clear(); // allow any ingress IP
o.KnownProxies.Clear();
o.ForwardLimit = null; // unlimited hops
});
// 2️⃣ Data‑Protection keys → Azure Blob
var blobClient = new BlobClient(new Uri(cfg["DataProtection:BlobUri"]),
new DefaultAzureCredential(new DefaultAzureCredentialOptions {
ManagedIdentityClientId = cfg["DataProtection:ManagedIdentityClientId"]
}));
services.AddDataProtection()
.SetApplicationName("YourSite")
.PersistKeysToAzureBlobStorage(blobClient);
// 3️⃣ Antiforgery settings
services.AddAntiforgery(o =>
{
o.HeaderName = "X-XSRF-TOKEN";
o.Cookie.Name = "XSRF-TOKEN";
o.Cookie.SameSite = SameSiteMode.None;
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
// 4️⃣ Pin discriminator after all modules
services.PostConfigure<DataProtectionOptions>(o =>
{
o.ApplicationDiscriminator = "YourSite";
});
OnApplicationInitialization (first lines)
var app = context.GetApplicationBuilder();
// 1️⃣ MUST be first – handle X‑Forwarded‑* from ACA
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost,
KnownNetworks = { }, KnownProxies = { }, ForwardLimit = null
});
// 2️⃣ Ensure HTTPS inside cluster
app.Use(async (ctx, next) =>
{
if (!ctx.Request.IsHttps)
{
ctx.Response.Redirect($"https://{ctx.Request.Host}{ctx.Request.Path}{ctx.Request.QueryString}", false);
return;
}
await next();
});
app.UseHttpsRedirection();
// … ABP default pipeline continues …
| Attempt | Outcome |
| --------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Persist keys + SetApplicationName | ✅ Key‑ring loads without “key not found”. |
| PostConfigure<DataProtectionOptions> last | ✅ Logs show application isolator: YourSite. |
| UseForwardedHeaders first | ✅ Trace says Request IsHttps = True. |
| Antiforgery header & secure cookie config | ❌ Still get 400 & “cookie token and request token were swapped”. |
| Temporarily set CookieSecurePolicy = None | Browser blocks cookie (SameSite=None requires Secure) – still 400. |
| Confirmed via DevTools: request sends no XSRF‑TOKEN cookie; only the form header. | |
UseForwardedHeaders, causing the browser to miss it?XSRF‑TOKEN cookie?_Host.cshtml) under Elsa interfere with antiforgery for Account routes?I have few questions regarding the CSM.
I want to to pre-create different pages for tenants based on their needs. They will be offered a UI selections and then we will create the pages they need. I also want them to be able to create and edit these pages afterwards.
Question summary:
Same questions in more detail
Q1 Can I create complex pages like the image here below? And are the pages responsive?
Q2 Can I add dynamic widgets into these pre-made pages? I´m pretty sure it is but want to ask.
Q3 Can I intercept the "create page" button and offer my own popup UI for selecting a template? When clicking "+ New page" I want to intercept that and offer another UI showing a selection of different type of pages e.g. "Landing page", "Meet the team", "The product" etc..
Q4 Can you edit the dynamic widget from the page its on by clicking on the widget on the page its self? I would not want to go the the menu for it and I don´t want manual editing of text.
I have followed the migration guide on this but am totally unable to fix it..
Any change there is something missing I need to do? This happens so early starting up I can´t get any more detailed information about where it could be happening. I even tried removing everything Icelandic (is or is-IS) and just have 'en' but still an issue..
[12:54:37 DBG] HealthReportCollector - health report execution history saved.
[12:54:37 DBG] HealthReport history already exists and is in the same state, updating the values.
[12:54:37 DBG] HealthReportCollector has completed.
[12:54:37 DBG] HealthCheck collector HostedService executed successfully.
[12:54:41 DBG] Starting HttpMessageHandler cleanup cycle with 3 items
[12:54:41 DBG] Ending HttpMessageHandler cleanup cycle after 0.0553ms - processed: 0 items - remaining: 3 items
[12:54:41 INF] Request starting HTTP/2 GET https://localhost:44307/api/abp/application-configuration?IncludeLocalizationResources=False - null null
[12:54:41 ERR] An unhandled exception has occurred while executing the request.
System.Globalization.CultureNotFoundException: Culture is not supported. (Parameter 'name')
Icelandic is an invalid culture identifier.
at System.Linq.Enumerable.SelectEnumerableIterator`2.ToArray()
at Microsoft.AspNetCore.RequestLocalization.DefaultAbpRequestLocalizationOptionsProvider.GetLocalizationOptionsAsync()
at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
[12:54:41 DBG] Response markup is scheduled to include Browser Link script injection.
[12:54:41 DBG] Response markup is scheduled to include browser refresh script injection.
[12:54:41 DBG] Response markup was updated to include Browser Link script injection.
[12:54:41 DBG] Response markup was updated to include browser refresh script injection.
[12:54:41 INF] Request finished HTTP/2 GET https://localhost:44307/api/abp/application-configuration?IncludeLocalizationResources=False - 500 null text/html; charset=utf-8 11.4419ms
[12:54:41 INF] Request starting HTTP/2 GET https://localhost:44307/_vs/browserLink - null null
[12:54:41 INF] Request starting HTTP/2 GET https://localhost:44307/_framework/aspnetcore-browser-refresh.js - null null
[12:54:41 INF] Request finished HTTP/2 GET https://localhost:44307/_framework/aspnetcore-browser-refresh.js - 200 13770 application/javascript; charset=utf-8 1.4353ms
[12:54:41 INF] Request finished HTTP/2 GET https://localhost:44307/_vs/browserLink - 200 null text/javascript; charset=UTF-8 15.2492ms
[12:54:41 INF] Request starting HTTP/2 GET https://localhost:44307/favicon.ico - null null
I you try to create db from these entites https://ufile.io/ajc1x5q2 (that were just created out of Suite) then there are lots of things wrong
I don´t know if it matters but I´m creating this inside a module.
Jobs being master and JobFiles being child.
Here are the rest of the errors
I create a Blazor Web App using Suite and then created a module for it and noting else.. just vanilla and no configurations..
What I get is this strange menu.. firstly the Administration menu is there with nothing under it and then the ContractWorkModule page comes above this folder.
On top of this everything is performing super super slow (in debug mode..). I see that for every refresh there is a 39.97 MB download.. is the auto part not working? Should WASM not be an opt-in and not a default?
There are more things wrong here.. like I created a Test page that is not shown but I can navigate to it etc.
Update I´m confused! According to your documentation you have you have updated server and wasm projects to use this new .net 8.0 thing
But why have you then also added this Blazor Web App option in Suite?

I thought that, that was the new thing so I started using it but I should have just created a new Blazor server project instead (where I can then opt into WASM also if I really want that)! Right or what?
I´m trying to figure out how to use the CancellationTokenProvider insted of adding CancellationToken to all my ApplicationService methods and then passing CancellationToken to them in my UI.
I might be misunderstanding how this is supposed to work but the documentation on this is serverly lacking
When navigating from the page should cancel the reqest and make IsCancellationRequested == true or do I have to do something in the UI?
Here is my code where I added a Task.Delay to the repository method to be able to then quickly navigate from that page.

Could this be related to Blazor Server? IF it doesn´t work with BS then it would be great to add that to the documentation.
UPDATE: I was also unsuccesfull passing token manually into the methods (something I was hoping I didn´t need to do)
Blazor
@inject INavigationInterception NavigationInterception
private CancellationTokenSource _cts = new();
protected override async Task OnInitializedAsync()
{
await NavigationInterception.EnableNavigationInterceptionAsync();
NavigationManager.LocationChanged += HandleLocationChanged;
}
private async Task OpenEditBookModalAsync(BookDto input)
{
var book = await BooksAppService.GetAsync(input.Id, _cts.Token); // Pass CancellationToken
EditingBookId = book.Id;
EditingBook = ObjectMapper.Map<BookDto, BookUpdateDto>(book);
await EditingBookValidations.ClearAll();
await EditBookModal.Show();
}
private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
{
_cts.Cancel(); // Cancel the current operations
}
public async ValueTask DisposeAsync()
{
NavigationManager.LocationChanged -= HandleLocationChanged;
_cts?.Cancel();
_cts?.Dispose();
}
public virtual async Task<PagedResultDto<BookDto>> GetListAsync(GetBooksInput input, CancellationToken cancellationToken)
{
var totalCount = await _bookRepository.GetCountAsync(input.FilterText, input.Name, input.Email, cancellationToken);
var items = await _bookRepository.GetListAsync(input.FilterText,
input.Name,
input.Email,
input.Sorting,
input.MaxResultCount,
input.SkipCount,
cancellationToken);
return new PagedResultDto<BookDto>
{
TotalCount = totalCount,
Items = ObjectMapper.Map<List<Book>, List<BookDto>>(items)
};
}
Repository
public abstract class EfCoreBookRepositoryBase : EfCoreRepository<CasaDbContext, Book, Guid>
{
public EfCoreBookRepositoryBase(IDbContextProvider<CasaDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<List<Book>> GetListAsync(
string? filterText = null,
string? name = null,
string? email = null,
string? sorting = null,
int maxResultCount = int.MaxValue,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
Task.Delay(10000).Wait();
var query = ApplyFilter((await GetQueryableAsync()), filterText, name, email);
query = query.OrderBy(string.IsNullOrWhiteSpace(sorting) ? BookConsts.GetDefaultSorting(false) : sorting);
return await query.PageBy(skipCount, maxResultCount).ToListAsync(cancellationToken);
}
}
How should this work? 🤷♂️🤨
Is it possible to have one running application that has
Something like:
and view it like this on the same application, not having to have another application instance (public web)?

It is cheaper and easier to have it all in one solution.
p.s I tried this in Blazor Server.. is that maybe not supported? And if so are there any other restrictions or limitations for Blazor?
e.s I tried this also with MVC and had some different strangeness https://support.abp.io/QA/Questions/6711/Bugs--Issues-v81x#answer-3a115a09-806f-bf69-6f41-319509df51ef
Abp.io Blazor Server 8.0.5