Blazor
55 TopicsDynamic form generation from dictionary
ASP.NET Blazor app brand spanking new to the stuff here. Trying a move from Apache PHP. Trying to create a dynamic form from a dictionary generated from a separate class I've banged my head against the wall for hours and can't get past this point. This makes everything a text box.. and When its done this way I can see the data change from the submit method. Any time I try to create a bool (checkbox) or number field I get conversion errors or worse. That dictionary _registry.Fields.FieldsData looks like. (converted to JSON to use here) { "ID": { "ID": "47", "fld_app": "5", "fld_human": "ID", "fld_column": "ID", "fld_enable": "True", "fld_type": "int", "fld_pdotype": "", "fld_length": "NULL", "fld_precision": "", "fld_pass": "", "fld_opt": "False", "fld_opt_table": "", "fld_opt_column": "", "fld_icon_set": "", "fld_regex": "", "fld_uom": "", "fld_placeholder": "", "fld_usr_ID": "False", "fld_link": "", "fld_index": "True", "fld_detail": "True", "fld_form": "True", "fld_order": "1", "fld_title": "False", "fld_required": "False", "fld_double": "False", "fld_encrypt": "False", "fld_time": "False", "fld_image": "False", "fld_unique": "False", "fld_json": "False" }, "Column1": { "ID": "48", "fld_app": "5", "fld_human": "Column1", "fld_column": "Column1", "fld_enable": "True", "fld_type": "nvarchar", "fld_pdotype": "", "fld_length": "50", "fld_precision": "", "fld_pass": "", "fld_opt": "False", "fld_opt_table": "", "fld_opt_column": "", "fld_icon_set": "", "fld_regex": "", "fld_uom": "", "fld_placeholder": "", "fld_usr_ID": "False", "fld_link": "", "fld_index": "True", "fld_detail": "True", "fld_form": "True", "fld_order": "2", "fld_title": "False", "fld_required": "False", "fld_double": "False", "fld_encrypt": "False", "fld_time": "False", "fld_image": "False", "fld_unique": "False", "fld_json": "False" }, "Column2": { "ID": "49", "fld_app": "5", "fld_human": "Column2", "fld_column": "Column2", "fld_enable": "True", "fld_type": "nvarchar", "fld_pdotype": "", "fld_length": "50", "fld_precision": "", "fld_pass": "", "fld_opt": "False", "fld_opt_table": "", "fld_opt_column": "", "fld_icon_set": "", "fld_regex": "", "fld_uom": "", "fld_placeholder": "", "fld_usr_ID": "False", "fld_link": "", "fld_index": "True", "fld_detail": "True", "fld_form": "True", "fld_order": "3", "fld_title": "False", "fld_required": "False", "fld_double": "False", "fld_encrypt": "False", "fld_time": "False", "fld_image": "False", "fld_unique": "False", "fld_json": "False" }, "Column3": { "ID": "50", "fld_app": "5", "fld_human": "Column3", "fld_column": "Column3", "fld_enable": "True", "fld_type": "nvarchar", "fld_pdotype": "", "fld_length": "50", "fld_precision": "", "fld_pass": "", "fld_opt": "False", "fld_opt_table": "", "fld_opt_column": "", "fld_icon_set": "", "fld_regex": "", "fld_uom": "", "fld_placeholder": "", "fld_usr_ID": "False", "fld_link": "", "fld_index": "True", "fld_detail": "True", "fld_form": "True", "fld_order": "4", "fld_title": "False", "fld_required": "False", "fld_double": "False", "fld_encrypt": "False", "fld_time": "False", "fld_image": "False", "fld_unique": "False", "fld_json": "False" }, "Column4": { "ID": "51", "fld_app": "5", "fld_human": "Column4", "fld_column": "Column4", "fld_enable": "True", "fld_type": "nvarchar", "fld_pdotype": "", "fld_length": "50", "fld_precision": "", "fld_pass": "", "fld_opt": "False", "fld_opt_table": "", "fld_opt_column": "", "fld_icon_set": "", "fld_regex": "", "fld_uom": "", "fld_placeholder": "", "fld_usr_ID": "False", "fld_link": "", "fld_index": "True", "fld_detail": "True", "fld_form": "True", "fld_order": "5", "fld_title": "False", "fld_required": "False", "fld_double": "False", "fld_encrypt": "False", "fld_time": "False", "fld_image": "False", "fld_unique": "False", "fld_json": "False" }, "Column5": { "ID": "52", "fld_app": "5", "fld_human": "Column5", "fld_column": "Column5", "fld_enable": "True", "fld_type": "nvarchar", "fld_pdotype": "", "fld_length": "50", "fld_precision": "", "fld_pass": "", "fld_opt": "False", "fld_opt_table": "", "fld_opt_column": "", "fld_icon_set": "", "fld_regex": "", "fld_uom": "", "fld_placeholder": "", "fld_usr_ID": "False", "fld_link": "", "fld_index": "True", "fld_detail": "True", "fld_form": "True", "fld_order": "6", "fld_title": "False", "fld_required": "False", "fld_double": "False", "fld_encrypt": "False", "fld_time": "False", "fld_image": "False", "fld_unique": "False", "fld_json": "False" }, "Column6": { "ID": "53", "fld_app": "5", "fld_human": "Column6", "fld_column": "Column6", "fld_enable": "True", "fld_type": "nvarchar", "fld_pdotype": "", "fld_length": "50", "fld_precision": "", "fld_pass": "", "fld_opt": "False", "fld_opt_table": "", "fld_opt_column": "", "fld_icon_set": "", "fld_regex": "", "fld_uom": "", "fld_placeholder": "", "fld_usr_ID": "False", "fld_link": "", "fld_index": "True", "fld_detail": "True", "fld_form": "True", "fld_order": "7", "fld_title": "False", "fld_required": "False", "fld_double": "False", "fld_encrypt": "False", "fld_time": "False", "fld_image": "False", "fld_unique": "False", "fld_json": "False" } } The .razor component PAGE "/FieldsAdmin" @inject ILogger<FieldsAdmin> Logger @inject portalx.Classes.Main.DBO Database @using System.Data @using System.Collections.Generic @inject portalx.Classes.Main._reg _registry @using System.Text.Json <form method="post" @onsubmit="Submit" @formname="FieldsAdmin"> <AntiforgeryToken /> @if (_registry.Fields.FieldsData != null) { @foreach (var row in _registry.Fields.FieldsData) { <div class="form-row"> @foreach (var field in row.Value) { <div class="form-group col-md-6"> <label>@field.Key</label> @{ var key = $"{row.Key}-{field.Key}"; if (!Model!.DynamicFields.ContainsKey(key)) { Model!.DynamicFields[key] = field.Value?.ToString() ?? string.Empty; } } <InputText @bind-Value="Model!.DynamicFields[key]" /> </div> } </div> } } <div> <button type="submit">Submit</button> </div> </form> <div> <h3>Fields Data (JSON)</h3> <pre>@jsonString</pre> </div> @code { [SupplyParameterFromForm] private ModelFieldsAdmin? Model { get; set; } private Dictionary<string, string> dataDict { get; set; } private string jsonString { get; set; } protected override void OnInitialized() { Model ??= new(); dataDict = new Dictionary<string, string> { { "ID", "hidden" }, { "fld_app", "skip me" }, { "fld_human", "text" }, { "fld_column", "skip me" }, { "fld_enable", "bool" }, { "fld_type", "skip me" }, { "fld_pdotype", "skip me" }, { "fld_length", "skip me" }, { "fld_precision", "skip me" }, { "fld_pass", "bool" }, { "fld_opt", "bool" }, { "fld_opt_table", "text" }, { "fld_opt_column", "text" }, { "fld_icon_set", "text" }, { "fld_regex", "text" }, { "fld_uom", "text" }, { "fld_placeholder", "text" }, { "fld_usr_ID", "bool" }, { "fld_link", "bool" }, { "fld_index", "bool" }, { "fld_detail", "bool" }, { "fld_form", "bool" }, { "fld_order", "number" }, { "fld_title", "bool" }, { "fld_required", "bool" }, { "fld_double", "bool" }, { "fld_encrypt", "bool" }, { "fld_time", "bool" }, { "fld_image", "bool" }, { "fld_unique", "bool" }, { "fld_json", "bool" } }; jsonString = JsonSerializer.Serialize(_registry.Fields.FieldsData, new JsonSerializerOptions { WriteIndented = true }); } private void Submit() { foreach (var kvp in Model!.DynamicFields) { Logger.LogInformation("Field Key: {Key}, Value: {Value}", kvp.Key, kvp.Value); } } public class ModelFieldsAdmin { public string? Id { get; set; } public Dictionary<string, string> DynamicFields { get; set; } = new Dictionary<string, string>(); } }Solved59Views0likes1CommentUse background Service With SignlarR In Blazor
i use blazor webassemly .net 8 i want every 5 sec send time to all clients this is my project https://github.com/jones1995wm/SendTime but when i navigate to /chat page component this code send time to all users await _clockHub.Clients.All.ShowTime(DateTime.Now); but not called the hubConnection.On("ShowTime") and dont update ui (foreach) why ? i use thishttps://learn.microsoft.com/en-us/aspnet/core/signalr/background-services?view=aspnetcore-8.0 how to use timer or background service with signalR in blazor to send time every 10 second11Views0likes0CommentsHow to trigger modal in blazer web server using c#?
Hi Team I have a blazer web server, want to understand something regarding my code. The suppose when clicking add operation it triggers modal, currently its not doing so and checked by debuging there are no any js errors. How do i improve this logic so it can work as expected? PAGE "/main" @using OperationApp.Models @using OperationApp.Components @using Blazored.Modal <h1>Operation Manager</h1> <!-- Button to open modal for adding a device --> <button class="btn btn-primary mb-3" @onclick="OpenAddDeviceModal">Add Device</button> <!-- Listing of operations --> @if (operations.Any()) { <ul class="list-group"> @foreach (var operation in operations) { <li class="list-group-item d-flex justify-content-between align-items-center"> <span>@operation.Name</span> <span> <!-- Button to remove the operation --> <button class="btn btn-danger" @onclick="() => RemoveOperation(operation.OperationID)">Remove</button> </span> </li> } </ul> } else { <p>No operations available.</p> } <!-- AddDeviceModal component --> <AddDeviceModal @ref="addDeviceModal" /> @code { private List<Operation> operations = new List<Operation>(); private AddDeviceModal addDeviceModal; private void OpenAddDeviceModal() { addDeviceModal.Open(); // Open the modal } private void RemoveOperation(int operationID) { var operationToRemove = operations.FirstOrDefault(op => op.OperationID == operationID); if (operationToRemove != null) { operations.Remove(operationToRemove); } } }123Views0likes0CommentsFile selector-Box for getting links to files in Intranet-Filesystems
Hello, i develop a blazor server-application with following requirements: The user wants to to save links to files (e.g. d:\temp\test.doc or \\shareserver\share\test.doc) or directories (e.g. d:\temp or \\shareserver\share) to a database. The user should be able to select those files and directories in the file-system with a file-selector box and get the path to them. The standard html <input type=file>-Element is not working because it is not publishing the path to the selected file. Is there any solution for this? best regards Volkhard104Views0likes0CommentsBlazor has turned out to be a massive disappointment, will it ever get Windows Authentication?
Blazor is a technology I've been hearing about for a couple of years. It sounds like it would be great, especially for not having to write any JavaScript code, unless it is absolutely necessary. I maintain a very old classic ASP.NET WebForms application which has a lot of issues that greatly add technical debt. I have finally convinced my management to let me rewrite this application, and it was my intention to use Blazor in .NET 8. I started a few weeks back. The number one thing is this app MUST use Windows Authentication as it is an Intranet app, working within our corporate firewall. No exceptions!!! I thought at one point that I had found a solution, but then I discovered that when creating the project and selecting Windows Authentication, Visual Studio was changing it from .NET 8 to .NET 6. That took me more than a week to discover that had happened. I have tried, multiple ways of getting Windows Authentication with IIS to work with a Blazor Server App and .NET 8. However, today I realized that is a broken dream. That I am wasting my time and need to give it up. Perhaps someday Microsoft will get around to bringing that back to a current version of .NET, but I need a solution today, not in November when .NET 9 comes out and hope that it brings Windows Authentication with Blazor Server, or some year in the future. This is very disappointing. So, I think the only choice I have at this point, is to go back to ASP.NET Core with .NET 8. I have heard that it is possible to embed Blazor components into ASP.NET Core/Razor pages, so that is an option, I hope. That way I can have ASP.NET Core MVC do the Windows Authentication and use Blazor components here and there. But I don't know how to do that and trying to find some training on how to do that is difficult. I am asking for recommendations/guidance to training either on Microsoft Learn, Pluralsight, or YouTube so I can learn how to do this and move forward. Thank you very much in advance, for your help.365Views0likes0CommentsConvert the standard Blazor navigation menu to a collapsible icon menu
While I admittedly love Blazor I’ve always changed the out-of-the-box navigation menu that comes with it. It’s the first manoeuvreI pull when spinning up a new Blazor app, stripping out the purple gradient and getting it in, what I consider, a “blank slate state”. The other change I’ve wanted to make to the out-the-box look is one of those deluxe collapsible menus that leave just the icons showing. Anyone that’s used Azure DevOps will know what I’m talking about. I’ve included a picture to show DevOps example of what I’d like to see in my Blazor app. It gives a load of extra screen real estate which is always a priority for me in business applications particularly with complex or intensive workflows. Plus it gives the user the option to remove the text prompts once they are familiar with the system which is supported with carefully selected icon choices. As with most tasks that I assume will be an obvious solution I hit my search engine of choice and looked to avoid reinventing the wheel. However I found no source of pre-written changes to achieve this and was directed to fairly expensive third party controls to solve this one for me, which, being tight fisted, pushed me to do it for myself. Here I hope you save you the trouble of paying a pretty penny or having to wrestle the CSS into submission and provide a guide for producing a nice collapsible icon navigation menu by altering the existing out of the box menu in Blazor. In the following example I have left all the standard styling as is with the menu and just done the changes required to make the collapsible menu. The three files that require changes are MainLayout.razor, NavMenu.razor and NavMenu.razor.css. The code changes are shown below: Firstly the NavMenu.razor requires a bool value (IconMenuActive) to indicate whether the icon menu is showing or not, then wrap the text of the each NavItem in an if statement dependent on this bool. Then a method for toggling this bool and EventCalBack to send a bool to the MainLayout.razor for shrinking the width of the sidebar. Lastly there needs to be the control for switching menu views (I used the standard io icon arrows). NavMenu.razor <div class="top-row ps-3 navbar navbar-dark"> <div class="container-fluid"> <span class="oi oi-monitor" style="color:white;" aria-hidden="true"></span> @if (!@IconMenuActive) { <a class="navbar-brand" href="">The Menu Title Here</a> } <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu"> <span class="navbar-toggler-icon"></span> </button> </div> </div> <div class="@NavMenuCssClass" @onclick="ToggleNavMenu"> <nav class="flex-column"> <div class="nav-item px-3"> <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> <span class="oi oi-home" aria-hidden="true"></span> @if (!@IconMenuActive) { <label>Home</label> } </NavLink> </div> <div class="nav-item px-3"> <NavLink class="nav-link" href="counter"> <span class="oi oi-plus" aria-hidden="true"></span> @if (!@IconMenuActive) { <label>Counter</label> } </NavLink> </div> <div class="nav-item px-3"> <NavLink class="nav-link" href="fetchdata"> <span class="oi oi-list-rich" aria-hidden="true"></span> @if (!@IconMenuActive) { <label>Fetch data</label> } </NavLink> </div> </nav> </div> <div class="bottom-row"> <div class="icon-menu-arrow"> @if (!@IconMenuActive) { <span class="oi oi-arrow-left" style="color: white;" @onclick="ToggleIconMenu"></span> } else { <span class="oi oi-arrow-right" style="color: white;" @onclick="ToggleIconMenu"></span> } </div> </div> @code { //bool to send to MainLayout for shrinking sidebar and showing/hide menu text private bool IconMenuActive { get; set; } = false; //EventCallback for sending bool to MainLayout [Parameter] public EventCallback<bool> ShowIconMenu { get; set; } private bool collapseNavMenu = true; private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; private void ToggleNavMenu() { collapseNavMenu = !collapseNavMenu; } //Method to toggle IconMenuActive bool and send bool via EventCallback private async Task ToggleIconMenu() { IconMenuActive = !IconMenuActive; await ShowIconMenu.InvokeAsync(IconMenuActive); } } Next I add in a bit of CSS in to NavMenu.razor.css to put the arrow for toggling the menu at the bottom of the sidebar and a media query to make sure it doesn't show up in mobile view. The CSS classes added are .bottom-row and.icon-menu-arrow. NavMenu.razor.css .navbar-toggler { background-color: rgba(255, 255, 255, 0.1); } .top-row { height: 3.5rem; background-color: rgba(0,0,0,0.4); } .bottom-row { position: absolute; bottom: 0; padding-bottom: 10px; text-align: right; width: 100%; padding-right: 28px; } .icon-menu-arrow { text-align: right; } .navbar-brand { font-size: 1.1rem; } .oi { width: 2rem; font-size: 1.1rem; vertical-align: text-top; top: -2px; } .nav-item { font-size: 0.9rem; padding-bottom: 0.5rem; } .nav-item:first-of-type { padding-top: 1rem; } .nav-item:last-of-type { padding-bottom: 1rem; } .nav-item ::deep a { color: #d7d7d7; border-radius: 4px; height: 3rem; display: flex; align-items: center; line-height: 3rem; } .nav-item ::deep a.active { background-color: rgba(255,255,255,0.25); color: white; } .nav-item ::deep a:hover { background-color: rgba(255,255,255,0.1); color: white; } @media (min-width: 641px) { .navbar-toggler { display: none; } .collapse { /* Never collapse the sidebar for wide screens */ display: block; } } @media (max-width: 640px) { .bottom-row { display: block; } } Finally I add in the handler for the EventCallback to MainLayout.razor and a method to alter the width of the sidebar. MainLayout.razor @inherits LayoutComponentBase <div class="page"> <div class="sidebar" style="@IconMenuCssClass"> <NavMenu ShowIconMenu="ToggleIconMenu"/> </div> <main> <div class="top-row px-4"> <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a> </div> <article class="content px-4"> @Body </article> </main> </div> @code{ private bool _iconMenuActive { get; set; } private string? IconMenuCssClass => _iconMenuActive ? "width: 80px;" : null; protected void ToggleIconMenu(bool iconMenuActive) { _iconMenuActive = iconMenuActive; } } The final product of these little changes are shown in the pictures below: I'd love to hear if anyone has tackled this in a different way to me and if they've got any ideas on making it cleaner. Have yourselves a wonderful day, Gav67KViews10likes14CommentsUsing browser local storage with Blazor
Project based on .NET Blazor Web App in Server render mode. Blazor currently has no built-in function for utilizing local browser storage. However this feature can come in useful for storing user information or partially completed forms etc. Luckily implementing a class for facilitating this function is straightforward enough. Here I’ll run over the steps required to get local storage up and running in your Blazor web app. Note: This method uses JSRuntime so make sure if you want to call it on page/component load you will need to run it on “OnAfterRender” rather than “OnInitialize” otherwise you will get an error. Here is a screenshot of my file structure so you can see the additional files I’ve made and where I’ve placed them: Making the javascript functions: Within the wwwroot of your app, make a new javascript file (I’ve called mine LocalStorage.js) and enter the following code: window.LocalStorageActions = { setItem: function (key, value) { localStorage.setItem(key, value); }, getItem: function (key) { return localStorage.getItem(key); }, removeItem: function (key) { localStorage.removeItem(key); }, clearData: function () { localStorage.clear(); } } These are the four functions we will need for setting, getting, removing and clearing local storage in the browser. Make a C# class to call the functions: To keep things tidy, I’ve put the C# class for calling the local storage functions and it’s interface into a folder called helpers, but you can put this wherever it’s most appropriate in your solution. You can create a new .cs file and add the following code: using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; namespace BlazorLocalStorage.Helpers { public class LocalStorageHelper : ILocalStorageHelper { private readonly IJSRuntime _javaScript; public LocalStorageHelper(IJSRuntime javaScript) { _javaScript = javaScript; } public async Task SetItem(string key, string value) { await _javaScript.InvokeAsync<string>("LocalStorageActions.setItem", key, value); } public async Task<string> GetItem(string key) { return await _javaScript.InvokeAsync<string>("LocalStorageActions.getItem", key); } public async Task RemoveItem(string key) { await _javaScript.InvokeAsync<string>("LocalStorageActions.removeItem", key); } public async Task ClearData() { await _javaScript.InvokeAsync<string>("LocalStorageActions.clearData"); } } } To quickly produce the interface for this class you can right click the class name (LocalStorageHelper in this case) and select “Quick Actions and Refactoring” and then select “Extract Interface” This will open a popup for extracting an interface from the class that you can select OK and a new file called ILocalStorageHelper.cs will appear and the LocalStorageHelper class will now inherit from the interface that’s been created. Registering the new files ready for use: Firstly we want to reference the new javascript file for use in the application. To do this go to the App.razor file and add the following line in the <body> section of the file. <script src="LocalStorage.js"></script> Next, we need to register the LocalStorageHelper so it can be injected wherever we want to use it. To do this open the Program.cs file and add the following line before the builder.Build() method it called. builder.Services.AddScoped<ILocalStorageHelper, LocalStorageHelper>(); Let’s try it out: I’ve made a little example of the new class being used by modifying the Home.razor file to use the various functions we’ve created. Before adding the main code I have created a little css class to centre the content of the page to keep things neat. So you can add the following code snippet to app.css. .center-screen { display: flex; justify-content: center; align-items: center; text-align: center; min-height: 70vh; } Now we can go into the Home.razor file and replace the content with the following. PAGE "/" @using BlazorLocalStorage.Helpers @rendermode InteractiveServer <PageTitle>Home</PageTitle> <div class="center-screen"> <div> <div class="row"> <label>Text-1</label> <InputText class="m-2" @bind-Value="Text1" /> </div> <div class="row"> <button class="btn btn-success m-2" @onclick="Save">Save</button> <button class="btn btn-info m-2" @onclick="Load">Load</button> <button class="btn btn-warning m-2" @onclick="Remove">Remove</button> <button class="btn btn-danger m-2" @onclick="Clear">Clear</button> </div> </div> </div> @code { [Inject] ILocalStorageHelper LocalStorage { get; set; } public string Text1 { get; set; } public async Task Save() { await LocalStorage.SetItem("textData", Text1); } public async Task Load() { Text1 = await LocalStorage.GetItem("textData"); } public async Task Remove() { await LocalStorage.RemoveItem("textData"); } public async Task Clear() { await LocalStorage.ClearData(); } } Apologies for the garish use of coloured buttons but it’s just meant to be an obvious demo. If you open the browsers developer tools and navigate to “Application” the select “Local Storage” you will be able to see the data stored, updated or removed as you use the demo. If you refresh the page or close and open the browser and select load it will pull the stored data back in to the textbox. That’s all there is to it! If you want to see the project, I've stuck a copy up on github that you can have a look at: https://github.com/DrGav/BlazorLocalStorage Have yourselves a wonderful day, Gavin.515Views0likes0CommentsBlazor Web App Server Side .NET 8 .AddMicrosoftAccount not returning Azure App Roles
I have successfully created a Blazor Web App Server Side, and I am able to authenticate with Azure AD using the .AddMicrosoftAccount() builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() .AddMicrosoftAccount(config => { builder.Configuration.GetSection("Authentication:Microsoft").Bind(config); config.Events = new Microsoft.AspNetCore.Authentication.OAuth.OAuthEvents { OnCreatingTicket = async context => { var user = context.Principal; var claimIdentity = user.Identity as ClaimsIdentity; var rolesClaim = user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Role); var role = user.IsInRole("Admin"); if (rolesClaim != null) { var claims = rolesClaim.Value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (var claim in claims) { claimIdentity.AddClaim(new Claim(ClaimTypes.Role, claim)); } } await Task.CompletedTask; } }; }); But it's not returning the roles claim with the attached roles for the user. The roles are setup correctly in Azure. I've searched high and low on the internet for something that would give me a clue as to where to go. I've tried using OpenId, and the roles get returned there, but I can't seem to use them in components. How do I get these roles using the .AddMicrosoftAccount() method?256Views0likes0CommentsAdd AWS Cognito authentication to a Blazor WebAssembly standalone app
I cannot find a step by step guide for using AWS Cognito in a Blazor WebAssembly standalone app for net 8 Microsoft did produce aguidebut not for Cognito. I did find a very goodguidefor adding Cognito but to a Blazor web app which does require a server.404Views0likes0Comments