From ccc8997d3623423572ec06ba24cb22cfcb7d2d7b Mon Sep 17 00:00:00 2001 From: Daria Tiurina Date: Tue, 10 Mar 2026 12:04:39 +0100 Subject: [PATCH 1/8] Fixed bug with the lazy loading --- .../Endpoints/src/TempData/TempData.cs | 10 ++- .../Endpoints/test/TempData/TempDataTest.cs | 76 +++++++++++++++++++ .../Pages/TempData/TempDataComponent.razor | 10 +-- 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/src/Components/Endpoints/src/TempData/TempData.cs b/src/Components/Endpoints/src/TempData/TempData.cs index f1f312726dad..5d2e691e87b1 100644 --- a/src/Components/Endpoints/src/TempData/TempData.cs +++ b/src/Components/Endpoints/src/TempData/TempData.cs @@ -49,8 +49,9 @@ public object? this[string key] public object? Get(string key) { + var value = Data.GetValueOrDefault(key); _retainedKeys.Remove(key); - return Data.GetValueOrDefault(key); + return value; } public object? Peek(string key) @@ -60,7 +61,7 @@ public object? this[string key] public void Keep() { - _retainedKeys.UnionWith(_data.Keys); + _retainedKeys.UnionWith(Data.Keys); } public void Keep(string key) @@ -78,8 +79,9 @@ public bool ContainsKey(string key) public bool Remove(string key) { + var removed = Data.Remove(key); _retainedKeys.Remove(key); - return Data.Remove(key); + return removed; } public IDictionary Save() @@ -175,7 +177,7 @@ sealed class TempDataEnumerator : IEnumerator> public TempDataEnumerator(TempData tempData) { _tempData = tempData; - _innerEnumerator = tempData._data.GetEnumerator(); + _innerEnumerator = tempData.Data.GetEnumerator(); } public KeyValuePair Current diff --git a/src/Components/Endpoints/test/TempData/TempDataTest.cs b/src/Components/Endpoints/test/TempData/TempDataTest.cs index c7725e55e8c7..dd8d7d217b92 100644 --- a/src/Components/Endpoints/test/TempData/TempDataTest.cs +++ b/src/Components/Endpoints/test/TempData/TempDataTest.cs @@ -250,4 +250,80 @@ public void TempData_Loads_WhenLoaded() Assert.True(tempData.WasLoaded); Assert.Equal("Value", value); } + + [Fact] + public void Get_ConsumesValue_WhenFirstAccessTriggersLazyLoad() + { + var tempData = new TempData(() => new Dictionary + { + ["Message"] = "hello" + }); + + var value = tempData.Get("Message"); + var saved = tempData.Save(); + + Assert.Equal("hello", value); + Assert.Empty(saved); + } + + [Fact] + public void Indexer_ConsumesValue_WhenFirstAccessTriggersLazyLoad() + { + var tempData = new TempData(() => new Dictionary + { + ["Message"] = "hello" + }); + + var value = tempData["Message"]; + var saved = tempData.Save(); + + Assert.Equal("hello", value); + Assert.Empty(saved); + } + + [Fact] + public void Remove_RemovesValue_WhenFirstAccessTriggersLazyLoad() + { + var tempData = new TempData(() => new Dictionary + { + ["Message"] = "hello" + }); + + var result = tempData.Remove("Message"); + var saved = tempData.Save(); + + Assert.True(result); + Assert.Empty(saved); + } + + [Fact] + public void Keep_RetainsAllKeys_WhenFirstAccessTriggersLazyLoad() + { + var tempData = new TempData(() => new Dictionary + { + ["Key1"] = "Value1", + ["Key2"] = "Value2" + }); + + tempData.Keep(); + var saved = tempData.Save(); + + Assert.Equal(2, saved.Count); + Assert.Equal("Value1", saved["Key1"]); + Assert.Equal("Value2", saved["Key2"]); + } + + [Fact] + public void Enumerator_IteratesAllKeys_WhenFirstAccessTriggersLazyLoad() + { + var tempData = new TempData(() => new Dictionary + { + ["Key1"] = "Value1", + ["Key2"] = "Value2" + }); + + var items = ((IEnumerable>)tempData).ToList(); + + Assert.Equal(2, items.Count); + } } diff --git a/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/TempData/TempDataComponent.razor b/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/TempData/TempDataComponent.razor index a9352c953ab3..eae47406d350 100644 --- a/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/TempData/TempDataComponent.razor +++ b/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/TempData/TempDataComponent.razor @@ -65,13 +65,6 @@ protected override void OnInitialized() { - _containsMessageKey = TempData?.ContainsKey("Message") ?? false; - _containsPeekedValueKey = TempData?.ContainsKey("PeekedValue") ?? false; - - if (Handler is not null) - { - return; - } _message = TempData!.Get("Message") as string ?? "No message"; _peekedValue = TempData!.Peek("PeekedValue") as string ?? "No peeked value"; _keptValue = TempData!.Get("KeptValue") as string ?? "No kept value"; @@ -82,6 +75,9 @@ _stringArrayResult = stringArray is string[] arr ? string.Join(",", arr) : $"Wrong type: {stringArray?.GetType().Name ?? "null"}"; _intArrayResult = intArray is int[] nums ? string.Join(",", nums) : $"Wrong type: {intArray?.GetType().Name ?? "null"}"; + _containsMessageKey = TempData?.ContainsKey("Message") ?? false; + _containsPeekedValueKey = TempData?.ContainsKey("PeekedValue") ?? false; + if (ValueToKeep == "all") { TempData!.Keep(); From f7aa7c3e3b0dbc0222a08e8e9458086901709abf Mon Sep 17 00:00:00 2001 From: Daria Tiurina Date: Tue, 10 Mar 2026 13:09:34 +0100 Subject: [PATCH 2/8] Fix nullable --- .../Endpoints/test/TempData/TempDataTest.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Components/Endpoints/test/TempData/TempDataTest.cs b/src/Components/Endpoints/test/TempData/TempDataTest.cs index dd8d7d217b92..14312686fbce 100644 --- a/src/Components/Endpoints/test/TempData/TempDataTest.cs +++ b/src/Components/Endpoints/test/TempData/TempDataTest.cs @@ -254,7 +254,7 @@ public void TempData_Loads_WhenLoaded() [Fact] public void Get_ConsumesValue_WhenFirstAccessTriggersLazyLoad() { - var tempData = new TempData(() => new Dictionary + var tempData = new TempData(() => new Dictionary { ["Message"] = "hello" }); @@ -269,7 +269,7 @@ public void Get_ConsumesValue_WhenFirstAccessTriggersLazyLoad() [Fact] public void Indexer_ConsumesValue_WhenFirstAccessTriggersLazyLoad() { - var tempData = new TempData(() => new Dictionary + var tempData = new TempData(() => new Dictionary { ["Message"] = "hello" }); @@ -284,7 +284,7 @@ public void Indexer_ConsumesValue_WhenFirstAccessTriggersLazyLoad() [Fact] public void Remove_RemovesValue_WhenFirstAccessTriggersLazyLoad() { - var tempData = new TempData(() => new Dictionary + var tempData = new TempData(() => new Dictionary { ["Message"] = "hello" }); @@ -299,7 +299,7 @@ public void Remove_RemovesValue_WhenFirstAccessTriggersLazyLoad() [Fact] public void Keep_RetainsAllKeys_WhenFirstAccessTriggersLazyLoad() { - var tempData = new TempData(() => new Dictionary + var tempData = new TempData(() => new Dictionary { ["Key1"] = "Value1", ["Key2"] = "Value2" @@ -316,13 +316,13 @@ public void Keep_RetainsAllKeys_WhenFirstAccessTriggersLazyLoad() [Fact] public void Enumerator_IteratesAllKeys_WhenFirstAccessTriggersLazyLoad() { - var tempData = new TempData(() => new Dictionary + var tempData = new TempData(() => new Dictionary { ["Key1"] = "Value1", ["Key2"] = "Value2" }); - var items = ((IEnumerable>)tempData).ToList(); + var items = ((IEnumerable>)tempData).ToList(); Assert.Equal(2, items.Count); } From 85047cb3e63130b15f23f6e6faf0da0490b1705d Mon Sep 17 00:00:00 2001 From: Daria Tiurina Date: Tue, 10 Mar 2026 17:32:18 +0100 Subject: [PATCH 3/8] Changed template to use TempData instead of custom cookies --- .../Account/IdentityRedirectManager.cs | 23 +++++---------- .../Account/Pages/ConfirmEmailChange.razor | 7 +++-- .../Account/Pages/ExternalLogin.razor | 11 ++++--- .../Account/Pages/Manage/ChangePassword.razor | 11 ++++--- .../Pages/Manage/DeletePersonalData.razor | 7 +++-- .../Account/Pages/Manage/Disable2fa.razor | 11 ++++--- .../Account/Pages/Manage/Email.razor | 9 ++++-- .../Pages/Manage/EnableAuthenticator.razor | 9 ++++-- .../Account/Pages/Manage/ExternalLogins.razor | 19 +++++++----- .../Pages/Manage/GenerateRecoveryCodes.razor | 7 +++-- .../Account/Pages/Manage/Index.razor | 11 ++++--- .../Account/Pages/Manage/Passkeys.razor | 29 ++++++++++--------- .../Account/Pages/Manage/PersonalData.razor | 5 +++- .../Account/Pages/Manage/RenamePasskey.razor | 13 +++++---- .../Pages/Manage/ResetAuthenticator.razor | 7 +++-- .../Account/Pages/Manage/SetPassword.razor | 11 ++++--- .../Manage/TwoFactorAuthentication.razor | 9 ++++-- .../Account/Shared/StatusMessage.razor | 13 +++------ 18 files changed, 124 insertions(+), 88 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs index 9d7e30adae19..d8ec26775c12 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs @@ -1,3 +1,4 @@ +using System.Security.Claims; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Identity; using BlazorWebCSharp._1.Data; @@ -6,15 +7,7 @@ namespace BlazorWebCSharp._1.Components.Account; internal sealed class IdentityRedirectManager(NavigationManager navigationManager) { - public const string StatusCookieName = "Identity.StatusMessage"; - - private static readonly CookieBuilder StatusCookieBuilder = new() - { - SameSite = SameSiteMode.Strict, - HttpOnly = true, - IsEssential = true, - MaxAge = TimeSpan.FromSeconds(5), - }; + public const string StatusMessageKey = "Identity.StatusMessage"; public void RedirectTo(string? uri) { @@ -36,9 +29,9 @@ public void RedirectTo(string uri, Dictionary queryParameters) RedirectTo(newUri); } - public void RedirectToWithStatus(string uri, string message, HttpContext context) + public void RedirectToWithStatus(string uri, string message, ITempData tempData) { - context.Response.Cookies.Append(StatusCookieName, message, StatusCookieBuilder.Build(context)); + tempData[StatusMessageKey] = message; RedirectTo(uri); } @@ -46,9 +39,9 @@ public void RedirectToWithStatus(string uri, string message, HttpContext context public void RedirectToCurrentPage() => RedirectTo(CurrentPath); - public void RedirectToCurrentPageWithStatus(string message, HttpContext context) - => RedirectToWithStatus(CurrentPath, message, context); + public void RedirectToCurrentPageWithStatus(string message, ITempData tempData) + => RedirectToWithStatus(CurrentPath, message, tempData); - public void RedirectToInvalidUser(UserManager userManager, HttpContext context) - => RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.", context); + public void RedirectToInvalidUser(UserManager userManager, ClaimsPrincipal user, ITempData tempData) + => RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(user)}'.", tempData); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor index 3a76b7261564..dcbb39ed6cce 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor @@ -21,6 +21,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromQuery] private string? UserId { get; set; } @@ -34,8 +37,8 @@ { if (UserId is null || Email is null || Code is null) { - RedirectManager.RedirectToWithStatus( - "Account/Login", "Error: Invalid email change confirmation link.", HttpContext); + RedirectManager.RedirectToWithStatus( + "Account/Login", "Error: Invalid email change confirmation link.", TempData); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor index 0c30821599fa..ae28ec92fedc 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor @@ -53,6 +53,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -73,14 +76,14 @@ if (RemoteError is not null) { - RedirectManager.RedirectToWithStatus("Account/Login", $"Error from external provider: {RemoteError}", HttpContext); + RedirectManager.RedirectToWithStatus("Account/Login", $"Error from external provider: {RemoteError}", TempData); return; } var info = await SignInManager.GetExternalLoginInfoAsync(); if (info is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", HttpContext); + RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", TempData); return; } @@ -104,7 +107,7 @@ { if (externalLoginInfo is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", HttpContext); + RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information during callback.", TempData); return; } @@ -141,7 +144,7 @@ { if (externalLoginInfo is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information during confirmation.", HttpContext); + RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information during confirmation.", TempData); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor index 0a47876de2ba..e19941fede7c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor @@ -52,6 +52,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -62,7 +65,7 @@ user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -77,11 +80,11 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } - var changePasswordResult = await UserManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword); + var changePasswordResult= await UserManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword); if (!changePasswordResult.Succeeded) { message = $"Error: {string.Join(",", changePasswordResult.Errors.Select(error => error.Description))}"; @@ -91,7 +94,7 @@ await SignInManager.RefreshSignInAsync(user); Logger.LogInformation("User changed their password successfully."); - RedirectManager.RedirectToCurrentPageWithStatus("Your password has been changed", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Your password has been changed", TempData); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor index f9c247897223..f3eec475138c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor @@ -45,6 +45,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -55,7 +58,7 @@ user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } requirePassword = await UserManager.HasPasswordAsync(user); @@ -65,7 +68,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor index 8a6921b2ae5b..d3a123980940 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor @@ -35,12 +35,15 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + protected override async Task OnInitializedAsync() { user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -54,11 +57,11 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } - var disable2faResult = await UserManager.SetTwoFactorEnabledAsync(user, false); + var disable2faResult= await UserManager.SetTwoFactorEnabledAsync(user, false); if (!disable2faResult.Succeeded) { throw new InvalidOperationException("Unexpected error occurred disabling 2FA."); @@ -69,6 +72,6 @@ RedirectManager.RedirectToWithStatus( "Account/Manage/TwoFactorAuthentication", "2fa has been disabled. You can reenable 2fa when you setup an authenticator app", - HttpContext); + TempData); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor index a2ca61841b0b..884ed7138e53 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor @@ -64,6 +64,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm(FormName = "change-email")] private InputModel Input { get; set; } = default!; @@ -74,7 +77,7 @@ user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -94,7 +97,7 @@ if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -119,7 +122,7 @@ if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor index 588134b5fa5a..5c5d474412cf 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor @@ -77,6 +77,9 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -87,7 +90,7 @@ else user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -98,7 +101,7 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -126,7 +129,7 @@ else } else { - RedirectManager.RedirectToWithStatus("Account/Manage/TwoFactorAuthentication", message, HttpContext); + RedirectManager.RedirectToWithStatus("Account/Manage/TwoFactorAuthentication", message, TempData); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor index 4c2582dcae89..9bae26e636bd 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor @@ -73,6 +73,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm] private string? LoginProvider { get; set; } @@ -87,7 +90,7 @@ user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -114,19 +117,19 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } var result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!); if (!result.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not removed.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not removed.", TempData); } else { await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("The external login was removed.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("The external login was removed.", TempData); } } @@ -134,7 +137,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -142,7 +145,7 @@ var info = await SignInManager.GetExternalLoginInfoAsync(userId); if (info is null) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not load external login info.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not load external login info.", TempData); return; } @@ -152,11 +155,11 @@ // Clear the existing external cookie to ensure a clean login process await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); - RedirectManager.RedirectToCurrentPageWithStatus("The external login was added.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("The external login was added.", TempData); } else { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not added. External logins can only be associated with one account.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not added. External logins can only be associated with one account.", TempData); } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor index 7ef969efb286..24be6c17b721 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor @@ -45,12 +45,15 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + protected override async Task OnInitializedAsync() { user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -65,7 +68,7 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor index 13faf41804f2..a6011197fc1b 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor @@ -40,6 +40,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -50,7 +53,7 @@ user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -64,7 +67,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -73,13 +76,13 @@ var setPhoneResult = await UserManager.SetPhoneNumberAsync(user, Input.PhoneNumber); if (!setPhoneResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: Failed to set phone number.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Error: Failed to set phone number.", TempData); return; } } await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("Your profile has been updated", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Your profile has been updated", TempData); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor index 1536f17305be..088f968a87e1 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor @@ -71,6 +71,9 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm] private string? Action { get; set; } @@ -87,7 +90,7 @@ else user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } currentPasskeys = await UserManager.GetPasskeysAsync(user); @@ -97,32 +100,32 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } if (!string.IsNullOrEmpty(Input.Error)) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: {Input.Error}", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus($"Error: {Input.Error}", TempData); return; } if (string.IsNullOrEmpty(Input.CredentialJson)) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The browser did not provide a passkey.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Error: The browser did not provide a passkey.", TempData); return; } if (currentPasskeys!.Count >= MaxPasskeyCount) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: You have reached the maximum number of allowed passkeys.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus($"Error: You have reached the maximum number of allowed passkeys.", TempData); return; } var attestationResult = await SignInManager.PerformPasskeyAttestationAsync(Input.CredentialJson); if (!attestationResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: Could not add the passkey: {attestationResult.Failure.Message}", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus($"Error: Passkey attestation failed: {attestationResult.Failure.Message}", TempData); return; } @@ -135,14 +138,14 @@ else var addPasskeyResult = await UserManager.AddOrUpdatePasskeyAsync(user, attestationResult.Passkey); if (!addPasskeyResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be added to your account.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be added to your account.", TempData); return; } // If a name was inferred, go back to the passkeys list if (!string.IsNullOrEmpty(attestationResult.Passkey.Name)) { - RedirectManager.RedirectToCurrentPageWithStatus("Your passkey was added successfully.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Your passkey was added successfully.", TempData); return; } @@ -162,7 +165,7 @@ else await DeletePasskey(); break; default: - RedirectManager.RedirectToCurrentPageWithStatus($"Error: Unknown action '{Action}'.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus($"Error: Unknown action '{Action}'.", TempData); break; } } @@ -171,7 +174,7 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -182,17 +185,17 @@ else } catch (FormatException) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The specified passkey ID had an invalid format.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Error: The specified passkey ID had an invalid format.", TempData); return; } var result = await UserManager.RemovePasskeyAsync(user, credentialId); if (!result.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be deleted.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be deleted.", TempData); return; } - RedirectManager.RedirectToCurrentPageWithStatus("Passkey deleted successfully.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Passkey deleted successfully.", TempData); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor index 214902bdbdec..7882e321bad4 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor @@ -31,12 +31,15 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + protected override async Task OnInitializedAsync() { var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor index a28d1bb85a50..dc8b13c1ff56 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor @@ -37,6 +37,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [Parameter] public string? Id { get; set; } @@ -50,7 +53,7 @@ user = (await UserManager.GetUserAsync(HttpContext.User))!; if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -61,14 +64,14 @@ } catch (FormatException) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The specified passkey ID had an invalid format.", HttpContext); + RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The specified passkey ID had an invalid format.", TempData); return; } passkey = await UserManager.GetPasskeyAsync(user, credentialId); if (passkey is null) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The specified passkey could not be found.", HttpContext); + RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The specified passkey could not be found.", TempData); return; } } @@ -79,11 +82,11 @@ var result = await UserManager.AddOrUpdatePasskeyAsync(user!, passkey); if (!result.Succeeded) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The passkey could not be updated.", HttpContext); + RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The passkey could not be updated.", TempData); return; } - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Passkey updated successfully.", HttpContext); + RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Passkey updated successfully.", TempData); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor index beb54b93a5f8..34cfa7362573 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor @@ -33,12 +33,15 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + private async Task OnSubmitAsync() { var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -52,6 +55,6 @@ RedirectManager.RedirectToWithStatus( "Account/Manage/EnableAuthenticator", "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.", - HttpContext); + TempData); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor index 180b4d77a4cc..c2ebb45739b1 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor @@ -43,6 +43,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -53,7 +56,7 @@ user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } @@ -68,11 +71,11 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } - var addPasswordResult = await UserManager.AddPasswordAsync(user, Input.NewPassword!); + var addPasswordResult= await UserManager.AddPasswordAsync(user, Input.NewPassword!); if (!addPasswordResult.Succeeded) { message = $"Error: {string.Join(",", addPasswordResult.Errors.Select(error => error.Description))}"; @@ -80,7 +83,7 @@ } await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("Your password has been set.", HttpContext); + RedirectManager.RedirectToCurrentPageWithStatus("Your password has been set.", TempData); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor index 6774ba789335..ae3c5803e28b 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor @@ -79,16 +79,19 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] + private ITempData TempData { get; set; } = default!; + protected override async Task OnInitializedAsync() { var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); return; } - canTrack = HttpContext.Features.Get()?.CanTrack ?? true; + canTrack= HttpContext.Features.Get()?.CanTrack ?? true; hasAuthenticator = await UserManager.GetAuthenticatorKeyAsync(user) is not null; is2faEnabled = await UserManager.GetTwoFactorEnabledAsync(user); isMachineRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(user); @@ -101,6 +104,6 @@ else RedirectManager.RedirectToCurrentPageWithStatus( "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code.", - HttpContext); + TempData); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor index 12cd544cfe77..0f93ba5a50f2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor @@ -7,23 +7,18 @@ } @code { - private string? messageFromCookie; + private string? messageFromTempData; [Parameter] public string? Message { get; set; } [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; + private ITempData TempData { get; set; } = default!; - private string? DisplayMessage => Message ?? messageFromCookie; + private string? DisplayMessage => Message ?? messageFromTempData; protected override void OnInitialized() { - messageFromCookie = HttpContext.Request.Cookies[IdentityRedirectManager.StatusCookieName]; - - if (messageFromCookie is not null) - { - HttpContext.Response.Cookies.Delete(IdentityRedirectManager.StatusCookieName); - } + messageFromTempData = TempData.Get(IdentityRedirectManager.StatusMessageKey) as string; } } From 29856740d59de2db57623a504ff67f9bcdc91baf Mon Sep 17 00:00:00 2001 From: Daria Tiurina Date: Mon, 16 Mar 2026 11:45:31 +0100 Subject: [PATCH 4/8] Feedback getting addressed --- .../Components/Account/Pages/ConfirmEmailChange.razor | 4 ++-- .../Components/Account/Pages/ExternalLogin.razor | 4 ++-- .../Components/Account/Pages/Manage/ChangePassword.razor | 2 +- .../Components/Account/Pages/Manage/Disable2fa.razor | 2 +- .../Components/Account/Pages/Manage/Passkeys.razor | 2 +- .../Components/Account/Pages/Manage/PersonalData.razor | 2 +- .../Components/Account/Pages/Manage/SetPassword.razor | 2 +- .../Account/Pages/Manage/TwoFactorAuthentication.razor | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor index dcbb39ed6cce..7eda9e8684e2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor @@ -37,7 +37,7 @@ { if (UserId is null || Email is null || Code is null) { - RedirectManager.RedirectToWithStatus( + RedirectManager.RedirectToWithStatus( "Account/Login", "Error: Invalid email change confirmation link.", TempData); return; } @@ -45,7 +45,7 @@ var user = await UserManager.FindByIdAsync(UserId); if (user is null) { - message = "Unable to find user with Id '{userId}'"; + message = $"Unable to find user with Id '{UserId}'"; return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor index ae28ec92fedc..d781730a3375 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor @@ -23,7 +23,7 @@

Associate your @ProviderDisplayName account.


-
+
You've successfully authenticated with @ProviderDisplayName. Please enter an email address for this site below and click the Register button to finish logging in. @@ -107,7 +107,7 @@ { if (externalLoginInfo is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information during callback.", TempData); + RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", TempData); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor index e19941fede7c..474731335b6a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor @@ -84,7 +84,7 @@ return; } - var changePasswordResult= await UserManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword); + var changePasswordResult = await UserManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword); if (!changePasswordResult.Succeeded) { message = $"Error: {string.Join(",", changePasswordResult.Errors.Select(error => error.Description))}"; diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor index d3a123980940..d4b4318bc1a4 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor @@ -61,7 +61,7 @@ return; } - var disable2faResult= await UserManager.SetTwoFactorEnabledAsync(user, false); + var disable2faResult = await UserManager.SetTwoFactorEnabledAsync(user, false); if (!disable2faResult.Succeeded) { throw new InvalidOperationException("Unexpected error occurred disabling 2FA."); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor index 088f968a87e1..ef35f94361d0 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor @@ -125,7 +125,7 @@ else var attestationResult = await SignInManager.PerformPasskeyAttestationAsync(Input.CredentialJson); if (!attestationResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: Passkey attestation failed: {attestationResult.Failure.Message}", TempData); + RedirectManager.RedirectToCurrentPageWithStatus($"Error: Could not add the passkey: {attestationResult.Failure.Message}", TempData); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor index 7882e321bad4..b4db742ac972 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor @@ -36,7 +36,7 @@ protected override async Task OnInitializedAsync() { - var user = await UserManager.GetUserAsync(HttpContext.User); + var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor index c2ebb45739b1..7937f77996e7 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor @@ -75,7 +75,7 @@ return; } - var addPasswordResult= await UserManager.AddPasswordAsync(user, Input.NewPassword!); + var addPasswordResult = await UserManager.AddPasswordAsync(user, Input.NewPassword!); if (!addPasswordResult.Succeeded) { message = $"Error: {string.Join(",", addPasswordResult.Errors.Select(error => error.Description))}"; diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor index ae3c5803e28b..b43f12b95c10 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor @@ -91,7 +91,7 @@ else return; } - canTrack= HttpContext.Features.Get()?.CanTrack ?? true; + canTrack = HttpContext.Features.Get()?.CanTrack ?? true; hasAuthenticator = await UserManager.GetAuthenticatorKeyAsync(user) is not null; is2faEnabled = await UserManager.GetTwoFactorEnabledAsync(user); isMachineRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(user); From 6dc811f64138a98a0966252a7aab30c830b33491 Mon Sep 17 00:00:00 2001 From: Daria Tiurina Date: Tue, 21 Apr 2026 15:41:02 +0200 Subject: [PATCH 5/8] Change to usage of the SupplyParameterFromTempData --- .../Account/IdentityRedirectManager.cs | 15 ------- .../Account/Pages/ConfirmEmailChange.razor | 11 +++-- .../Account/Pages/ExternalLogin.razor | 18 +++++--- .../Account/Pages/InvalidUser.razor | 10 ++++- .../Components/Account/Pages/Login.razor | 5 +++ .../Account/Pages/Manage/ChangePassword.razor | 13 +++--- .../Pages/Manage/DeletePersonalData.razor | 12 ++--- .../Account/Pages/Manage/Disable2fa.razor | 22 ++++----- .../Account/Pages/Manage/Email.razor | 12 ++--- .../Pages/Manage/EnableAuthenticator.razor | 15 ++++--- .../Account/Pages/Manage/ExternalLogins.razor | 31 ++++++++----- .../Pages/Manage/GenerateRecoveryCodes.razor | 13 +++--- .../Account/Pages/Manage/Index.razor | 19 +++++--- .../Account/Pages/Manage/Passkeys.razor | 45 ++++++++++++------- .../Account/Pages/Manage/PersonalData.razor | 13 ++++-- .../Account/Pages/Manage/RenamePasskey.razor | 19 +++++--- .../Pages/Manage/ResetAuthenticator.razor | 22 +++++---- .../Account/Pages/Manage/SetPassword.razor | 15 ++++--- .../Manage/TwoFactorAuthentication.razor | 17 ++++--- .../Account/Shared/StatusMessage.razor | 18 ++------ 20 files changed, 202 insertions(+), 143 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs index d8ec26775c12..5f0d9418d9c5 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs @@ -1,7 +1,4 @@ -using System.Security.Claims; using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Identity; -using BlazorWebCSharp._1.Data; namespace BlazorWebCSharp._1.Components.Account; @@ -29,19 +26,7 @@ public void RedirectTo(string uri, Dictionary queryParameters) RedirectTo(newUri); } - public void RedirectToWithStatus(string uri, string message, ITempData tempData) - { - tempData[StatusMessageKey] = message; - RedirectTo(uri); - } - private string CurrentPath => navigationManager.ToAbsoluteUri(navigationManager.Uri).GetLeftPart(UriPartial.Path); public void RedirectToCurrentPage() => RedirectTo(CurrentPath); - - public void RedirectToCurrentPageWithStatus(string message, ITempData tempData) - => RedirectToWithStatus(CurrentPath, message, tempData); - - public void RedirectToInvalidUser(UserManager userManager, ClaimsPrincipal user, ITempData tempData) - => RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(user)}'.", tempData); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor index 7eda9e8684e2..01e6f8bce614 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor @@ -21,8 +21,8 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromQuery] private string? UserId { get; set; } @@ -35,10 +35,13 @@ protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + if (UserId is null || Email is null || Code is null) { - RedirectManager.RedirectToWithStatus( - "Account/Login", "Error: Invalid email change confirmation link.", TempData); + IdentityStatusMessage = "Error: Invalid email change confirmation link."; + RedirectManager.RedirectTo("Account/Login"); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor index d781730a3375..a8a386f32a4a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor @@ -53,8 +53,8 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -72,18 +72,22 @@ protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); if (RemoteError is not null) { - RedirectManager.RedirectToWithStatus("Account/Login", $"Error from external provider: {RemoteError}", TempData); + IdentityStatusMessage = $"Error from external provider: {RemoteError}"; + RedirectManager.RedirectTo("Account/Login"); return; } var info = await SignInManager.GetExternalLoginInfoAsync(); if (info is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", TempData); + IdentityStatusMessage = "Error loading external login information."; + RedirectManager.RedirectTo("Account/Login"); return; } @@ -107,7 +111,8 @@ { if (externalLoginInfo is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", TempData); + IdentityStatusMessage = "Error loading external login information."; + RedirectManager.RedirectTo("Account/Login"); return; } @@ -144,7 +149,8 @@ { if (externalLoginInfo is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information during confirmation.", TempData); + IdentityStatusMessage = "Error loading external login information during confirmation."; + RedirectManager.RedirectTo("Account/Login"); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor index e61fe5def569..06e5cd1a73bb 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor @@ -1,7 +1,15 @@ @page "/Account/InvalidUser" +@using Microsoft.AspNetCore.Identity +@inject UserManager UserManager + Invalid user

Invalid user

- +

Error: Unable to load user with ID '@UserManager.GetUserId(HttpContext.User)'.

+ +@code { + [CascadingParameter] + private HttpContext HttpContext { get; set; } = default!; +} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Login.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Login.razor index 65157408b009..286969a93179 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Login.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Login.razor @@ -82,6 +82,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -90,6 +93,8 @@ protected override async Task OnInitializedAsync() { + errorMessage = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); editContext = new EditContext(Input); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor index 474731335b6a..4197acb78ff2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor @@ -52,20 +52,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -80,7 +82,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -94,7 +96,8 @@ await SignInManager.RefreshSignInAsync(user); Logger.LogInformation("User changed their password successfully."); - RedirectManager.RedirectToCurrentPageWithStatus("Your password has been changed", TempData); + IdentityStatusMessage = "Your password has been changed"; + RedirectManager.RedirectToCurrentPage(); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor index f3eec475138c..0c814bf0102d 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor @@ -45,20 +45,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } requirePassword = await UserManager.HasPasswordAsync(user); @@ -68,11 +70,11 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } - if (requirePassword && !await UserManager.CheckPasswordAsync(user, Input.Password)) + if (requirePassword&& !await UserManager.CheckPasswordAsync(user, Input.Password)) { message = "Error: Incorrect password."; return; diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor index d4b4318bc1a4..403e392a4522 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor @@ -9,7 +9,7 @@ Disable two-factor authentication (2FA) - +

Disable two-factor authentication (2FA)

@code { + private string? message; private ApplicationUser? user; [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } - if (HttpMethods.IsGet(HttpContext.Request.Method) && !await UserManager.GetTwoFactorEnabledAsync(user)) + if (HttpMethods.IsGet(HttpContext.Request.Method)&& !await UserManager.GetTwoFactorEnabledAsync(user)) { throw new InvalidOperationException("Cannot disable 2FA for user as it's not currently enabled."); } @@ -57,7 +61,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -69,9 +73,7 @@ var userId = await UserManager.GetUserIdAsync(user); Logger.LogInformation("User with ID '{UserId}' has disabled 2fa.", userId); - RedirectManager.RedirectToWithStatus( - "Account/Manage/TwoFactorAuthentication", - "2fa has been disabled. You can reenable 2fa when you setup an authenticator app", - TempData); + IdentityStatusMessage = "2fa has been disabled. You can reenable 2fa when you setup an authenticator app"; + RedirectManager.RedirectTo("Account/Manage/TwoFactorAuthentication"); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor index 884ed7138e53..3e46514e0c3f 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor @@ -64,20 +64,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm(FormName = "change-email")] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -97,7 +99,7 @@ if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -122,7 +124,7 @@ if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor index 5c5d474412cf..a3f80adb72e1 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor @@ -77,20 +77,22 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -101,11 +103,11 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } - // Strip spaces and hyphens + // Strip spacesand hyphens var verificationCode = Input.Code.Replace(" ", string.Empty).Replace("-", string.Empty); var is2faTokenValid = await UserManager.VerifyTwoFactorTokenAsync( @@ -129,7 +131,8 @@ else } else { - RedirectManager.RedirectToWithStatus("Account/Manage/TwoFactorAuthentication", message, TempData); + IdentityStatusMessage = message; + RedirectManager.RedirectTo("Account/Manage/TwoFactorAuthentication"); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor index 9bae26e636bd..1e14a8d3b604 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor @@ -11,7 +11,7 @@ Manage your external logins - + @if (currentLogins?.Count > 0) {

Registered Logins

@@ -65,6 +65,7 @@ @code { public const string LinkLoginCallbackAction = "LinkLoginCallback"; + private string? message; private ApplicationUser? user; private IList? currentLogins; private IList? otherLogins; @@ -73,8 +74,8 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm] private string? LoginProvider { get; set; } @@ -87,10 +88,13 @@ protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -117,19 +121,21 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } var result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!); if (!result.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not removed.", TempData); + IdentityStatusMessage = "Error: The external login was not removed."; + RedirectManager.RedirectToCurrentPage(); } else { await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("The external login was removed.", TempData); + IdentityStatusMessage = "The external login was removed."; + RedirectManager.RedirectToCurrentPage(); } } @@ -137,7 +143,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -145,7 +151,8 @@ var info = await SignInManager.GetExternalLoginInfoAsync(userId); if (info is null) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not load external login info.", TempData); + IdentityStatusMessage = "Error: Could not load external login info."; + RedirectManager.RedirectToCurrentPage(); return; } @@ -155,11 +162,13 @@ // Clear the existing external cookie to ensure a clean login process await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); - RedirectManager.RedirectToCurrentPageWithStatus("The external login was added.", TempData); + IdentityStatusMessage = "The external login was added."; + RedirectManager.RedirectToCurrentPage(); } else { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not added. External logins can only be associated with one account.", TempData); + IdentityStatusMessage = "Error: The external login was not added. External logins can only be associated with one account."; + RedirectManager.RedirectToCurrentPage(); } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor index 24be6c17b721..b4efd404cf02 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor @@ -45,19 +45,22 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } - var isTwoFactorEnabled = await UserManager.GetTwoFactorEnabledAsync(user); + var isTwoFactorEnabled= await UserManager.GetTwoFactorEnabledAsync(user); if (!isTwoFactorEnabled) { throw new InvalidOperationException("Cannot generate recovery codes for user because they do not have 2FA enabled."); @@ -68,7 +71,7 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor index a6011197fc1b..f0f2b9ce26e3 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor @@ -11,7 +11,7 @@ Profile

Profile

- +
@@ -33,6 +33,7 @@
@code { + private string? message; private ApplicationUser? user; private string? username; private string? phoneNumber; @@ -40,20 +41,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -67,7 +70,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -76,13 +79,15 @@ var setPhoneResult = await UserManager.SetPhoneNumberAsync(user, Input.PhoneNumber); if (!setPhoneResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: Failed to set phone number.", TempData); + IdentityStatusMessage = "Error: Failed to set phone number."; + RedirectManager.RedirectToCurrentPage(); return; } } await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("Your profile has been updated", TempData); + IdentityStatusMessage = "Your profile has been updated"; + RedirectManager.RedirectToCurrentPage(); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor index ef35f94361d0..8810bea2d701 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor @@ -13,7 +13,7 @@

Manage your passkeys

- + @if (currentPasskeys is { Count: > 0 }) { @@ -65,14 +65,15 @@ else @code { private const int MaxPasskeyCount = 100; + private string? message; private ApplicationUser? user; private IList? currentPasskeys; [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm] private string? Action { get; set; } @@ -85,12 +86,14 @@ else protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } currentPasskeys = await UserManager.GetPasskeysAsync(user); @@ -100,32 +103,36 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } if (!string.IsNullOrEmpty(Input.Error)) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: {Input.Error}", TempData); + IdentityStatusMessage = $"Error: {Input.Error}"; + RedirectManager.RedirectToCurrentPage(); return; } if (string.IsNullOrEmpty(Input.CredentialJson)) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The browser did not provide a passkey.", TempData); + IdentityStatusMessage = "Error: The browser did not provide a passkey."; + RedirectManager.RedirectToCurrentPage(); return; } if (currentPasskeys!.Count >= MaxPasskeyCount) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: You have reached the maximum number of allowed passkeys.", TempData); + IdentityStatusMessage = $"Error: You have reached the maximum number of allowed passkeys."; + RedirectManager.RedirectToCurrentPage(); return; } var attestationResult = await SignInManager.PerformPasskeyAttestationAsync(Input.CredentialJson); if (!attestationResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: Could not add the passkey: {attestationResult.Failure.Message}", TempData); + IdentityStatusMessage = $"Error: Could not add the passkey: {attestationResult.Failure.Message}"; + RedirectManager.RedirectToCurrentPage(); return; } @@ -138,14 +145,16 @@ else var addPasskeyResult = await UserManager.AddOrUpdatePasskeyAsync(user, attestationResult.Passkey); if (!addPasskeyResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be added to your account.", TempData); + IdentityStatusMessage = "Error: The passkey could not be added to your account."; + RedirectManager.RedirectToCurrentPage(); return; } // If a name was inferred, go back to the passkeys list if (!string.IsNullOrEmpty(attestationResult.Passkey.Name)) { - RedirectManager.RedirectToCurrentPageWithStatus("Your passkey was added successfully.", TempData); + IdentityStatusMessage = "Your passkey was added successfully."; + RedirectManager.RedirectToCurrentPage(); return; } @@ -165,7 +174,8 @@ else await DeletePasskey(); break; default: - RedirectManager.RedirectToCurrentPageWithStatus($"Error: Unknown action '{Action}'.", TempData); + IdentityStatusMessage = $"Error: Unknown action '{Action}'."; + RedirectManager.RedirectToCurrentPage(); break; } } @@ -174,7 +184,7 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -185,17 +195,20 @@ else } catch (FormatException) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The specified passkey ID had an invalid format.", TempData); + IdentityStatusMessage = "Error: The specified passkey ID had an invalid format."; + RedirectManager.RedirectToCurrentPage(); return; } var result = await UserManager.RemovePasskeyAsync(user, credentialId); if (!result.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be deleted.", TempData); + IdentityStatusMessage = "Error: The passkey could not be deleted."; + RedirectManager.RedirectToCurrentPage(); return; } - RedirectManager.RedirectToCurrentPageWithStatus("Passkey deleted successfully.", TempData); + IdentityStatusMessage = "Passkey deleted successfully."; + RedirectManager.RedirectToCurrentPage(); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor index b4db742ac972..65708ecd703c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor @@ -8,7 +8,7 @@ Personal Data - +

Personal Data

@@ -28,18 +28,23 @@
@code { + private string? message; + [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor index dc8b13c1ff56..4b76ce786d29 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor @@ -37,8 +37,8 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [Parameter] public string? Id { get; set; } @@ -48,12 +48,13 @@ protected override async Task OnInitializedAsync() { + IdentityStatusMessage = null; Input ??= new(); user = (await UserManager.GetUserAsync(HttpContext.User))!; if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -64,14 +65,16 @@ } catch (FormatException) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The specified passkey ID had an invalid format.", TempData); + IdentityStatusMessage = "Error: The specified passkey ID had an invalid format."; + RedirectManager.RedirectTo("Account/Manage/Passkeys"); return; } passkey = await UserManager.GetPasskeyAsync(user, credentialId); if (passkey is null) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The specified passkey could not be found.", TempData); + IdentityStatusMessage = "Error: The specified passkey could not be found."; + RedirectManager.RedirectTo("Account/Manage/Passkeys"); return; } } @@ -82,11 +85,13 @@ var result = await UserManager.AddOrUpdatePasskeyAsync(user!, passkey); if (!result.Succeeded) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The passkey could not be updated.", TempData); + IdentityStatusMessage = "Error: The passkey could not be updated."; + RedirectManager.RedirectTo("Account/Manage/Passkeys"); return; } - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Passkey updated successfully.", TempData); + IdentityStatusMessage = "Passkey updated successfully."; + RedirectManager.RedirectTo("Account/Manage/Passkeys"); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor index 34cfa7362573..74542ddb37f8 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor @@ -10,7 +10,7 @@ Reset authenticator key - +

Reset authenticator key

@code { + private string? message; + [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + + protected override void OnInitialized() + { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + } private async Task OnSubmitAsync() { var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -52,9 +60,7 @@ await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToWithStatus( - "Account/Manage/EnableAuthenticator", - "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.", - TempData); + IdentityStatusMessage = "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key."; + RedirectManager.RedirectTo("Account/Manage/EnableAuthenticator"); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor index 7937f77996e7..f7bdc79d9ba6 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor @@ -43,20 +43,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -71,11 +73,11 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } - var addPasswordResult = await UserManager.AddPasswordAsync(user, Input.NewPassword!); + var addPasswordResult= await UserManager.AddPasswordAsync(user, Input.NewPassword!); if (!addPasswordResult.Succeeded) { message = $"Error: {string.Join(",", addPasswordResult.Errors.Select(error => error.Description))}"; @@ -83,7 +85,8 @@ } await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("Your password has been set.", TempData); + IdentityStatusMessage = "Your password has been set."; + RedirectManager.RedirectToCurrentPage(); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor index b43f12b95c10..795d01d386cb 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor @@ -10,7 +10,7 @@ Two-factor authentication (2FA) - +

Two-factor authentication (2FA)

@if (canTrack) { @@ -70,6 +70,7 @@ else } @code { + private string? message; private bool canTrack; private bool hasAuthenticator; private int recoveryCodesLeft; @@ -79,15 +80,18 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [CascadingParameter] - private ITempData TempData { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext.User, TempData); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -102,8 +106,7 @@ else { await SignInManager.ForgetTwoFactorClientAsync(); - RedirectManager.RedirectToCurrentPageWithStatus( - "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code.", - TempData); + IdentityStatusMessage = "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code."; + RedirectManager.RedirectToCurrentPage(); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor index 0f93ba5a50f2..8f2724a45f24 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor @@ -1,24 +1,12 @@ -@if (!string.IsNullOrEmpty(DisplayMessage)) +@if (!string.IsNullOrEmpty(Message)) { - var statusMessageClass = DisplayMessage.StartsWith("Error") ? "danger" : "success"; + var statusMessageClass = Message.StartsWith("Error") ? "danger" : "success"; } @code { - private string? messageFromTempData; - [Parameter] public string? Message { get; set; } - - [CascadingParameter] - private ITempData TempData { get; set; } = default!; - - private string? DisplayMessage => Message ?? messageFromTempData; - - protected override void OnInitialized() - { - messageFromTempData = TempData.Get(IdentityRedirectManager.StatusMessageKey) as string; - } } From 28e5798ab372453ad4648c0067a47a62b9b6e964 Mon Sep 17 00:00:00 2001 From: Daria Tiurina Date: Tue, 21 Apr 2026 17:25:12 +0200 Subject: [PATCH 6/8] Fix InvalidUser page --- .../Components/Account/Pages/InvalidUser.razor | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor index 06e5cd1a73bb..45c6e609438d 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor @@ -7,9 +7,16 @@

Invalid user

-

Error: Unable to load user with ID '@UserManager.GetUserId(HttpContext.User)'.

+ @code { + private string? message; + [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + + protected override void OnInitialized() + { + message = $"Error: Unable to load user with ID '{UserManager.GetUserId(HttpContext.User)}'."; + } } From 7cd3bd2cd04ce85bf1a9635ab0974216aa56cc01 Mon Sep 17 00:00:00 2001 From: Daria Tiurina Date: Wed, 22 Apr 2026 10:48:40 +0200 Subject: [PATCH 7/8] Fix --- .../Components/Account/Pages/Manage/DeletePersonalData.razor | 2 +- .../Components/Account/Pages/Manage/Disable2fa.razor | 2 +- .../Components/Account/Pages/Manage/EnableAuthenticator.razor | 2 +- .../Components/Account/Pages/Manage/GenerateRecoveryCodes.razor | 2 +- .../Components/Account/Pages/Manage/Passkeys.razor | 2 +- .../Components/Account/Pages/Manage/SetPassword.razor | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor index 0c814bf0102d..bbece664423e 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor @@ -74,7 +74,7 @@ return; } - if (requirePassword&& !await UserManager.CheckPasswordAsync(user, Input.Password)) + if (requirePassword && !await UserManager.CheckPasswordAsync(user, Input.Password)) { message = "Error: Incorrect password."; return; diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor index 403e392a4522..3a6d501b7d70 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor @@ -51,7 +51,7 @@ return; } - if (HttpMethods.IsGet(HttpContext.Request.Method)&& !await UserManager.GetTwoFactorEnabledAsync(user)) + if (HttpMethods.IsGet(HttpContext.Request.Method) && !await UserManager.GetTwoFactorEnabledAsync(user)) { throw new InvalidOperationException("Cannot disable 2FA for user as it's not currently enabled."); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor index a3f80adb72e1..002202c690f8 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor @@ -107,7 +107,7 @@ else return; } - // Strip spacesand hyphens + // Strip spaces and hyphens var verificationCode = Input.Code.Replace(" ", string.Empty).Replace("-", string.Empty); var is2faTokenValid = await UserManager.VerifyTwoFactorTokenAsync( diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor index b4efd404cf02..6caf5d210e61 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor @@ -60,7 +60,7 @@ else return; } - var isTwoFactorEnabled= await UserManager.GetTwoFactorEnabledAsync(user); + var isTwoFactorEnabled = await UserManager.GetTwoFactorEnabledAsync(user); if (!isTwoFactorEnabled) { throw new InvalidOperationException("Cannot generate recovery codes for user because they do not have 2FA enabled."); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor index 8810bea2d701..35198ee58d52 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor @@ -123,7 +123,7 @@ else if (currentPasskeys!.Count >= MaxPasskeyCount) { - IdentityStatusMessage = $"Error: You have reached the maximum number of allowed passkeys."; + IdentityStatusMessage = "Error: You have reached the maximum number of allowed passkeys."; RedirectManager.RedirectToCurrentPage(); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor index f7bdc79d9ba6..c5662be69af0 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor @@ -77,7 +77,7 @@ return; } - var addPasswordResult= await UserManager.AddPasswordAsync(user, Input.NewPassword!); + var addPasswordResult = await UserManager.AddPasswordAsync(user, Input.NewPassword!); if (!addPasswordResult.Succeeded) { message = $"Error: {string.Join(",", addPasswordResult.Errors.Select(error => error.Description))}"; From ba68f23b05cf9de47bf6422125d464fed054aae0 Mon Sep 17 00:00:00 2001 From: Daria Tiurina Date: Wed, 22 Apr 2026 12:06:13 +0200 Subject: [PATCH 8/8] Fix --- .../Components/Account/Pages/ConfirmEmailChange.razor | 2 +- .../Components/Account/Pages/InvalidUser.razor | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor index 01e6f8bce614..6b9052849d68 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor @@ -48,7 +48,7 @@ var user = await UserManager.FindByIdAsync(UserId); if (user is null) { - message = $"Unable to find user with Id '{UserId}'"; + message = $"Error: Unable to find user with Id '{UserId}'"; return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor index 45c6e609438d..f67f733baba2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor @@ -1,6 +1,7 @@ @page "/Account/InvalidUser" @using Microsoft.AspNetCore.Identity +@using BlazorWebCSharp._1.Data @inject UserManager UserManager Invalid user