HFloyd
(Heather Floyd)
October 10, 2025, 7:28pm
1
There is a logout snippet provided:
@using (Html.BeginUmbracoForm<UmbLoginStatusController>("HandleLogout", new { RedirectUrl = logoutModel.RedirectUrl }))
{
<button type="submit" class="btn btn-primary">Log out</button>
}
which generates a visible button for a logged-in member to click.
I am wondering if there is a way to programmatically “log out” a member (automatically triggering the “HandleLogout” function) based on various conditions.
EssCee
(SC)
October 10, 2025, 8:58pm
2
There’s a couple of ways to go about this, but the below hopefully should get you going:
public async Task LogOutMemberAsync(){var httpContext = _httpContextAccessor.HttpContext;
if (httpContext?.User?.Identity?.IsAuthenticated ?? false)
{
await _signInManager.SignOutAsync();
httpContext.Session.Clear();
httpContext.Response.Cookies.Delete(".AspNetCore.Identity.Application");
}
}
You may need to adjust the cookie name.
HFloyd
(Heather Floyd)
October 22, 2025, 5:49pm
4
Thanks, @EssCee ,
So it sounds like I’d basically need to re-create the functionality of that “HandleLogout” Action - there isn’t a way to “call” that one programmatically from the View or Controller directly.
HFloyd
(Heather Floyd)
November 3, 2025, 10:45pm
5
A follow-up question…
I have the general logout functionality working as part of the page controller:
public class LogoutPageController : PageControllerBase
{
private readonly ILogger _Logger;
private readonly IMemberManager _MemberManager;
private readonly UserManager<MemberIdentityUser> _MemberIdentityManager;
private readonly IMemberSignInManager _SignInManager;
private readonly JwtService _JwtService;
public LogoutPageController(
ILogger<LogoutPageController> logger
, ICompositeViewEngine compositeViewEngine
, IUmbracoContextAccessor umbracoContextAccessor
, IMemberManager MemberManager
, UserManager<MemberIdentityUser> MemberIdentityManager
, IMemberSignInManager signInManager
, JwtService jwtService)
: base(logger, siteHelperService, themeHelperService, compositeViewEngine, umbracoContextAccessor)
{
_Logger = logger;
_MemberManager = MemberManager;
_MemberIdentityManager = MemberIdentityManager;
_SignInManager = signInManager;
_JwtService = jwtService;
}
public override IActionResult Index()
{
...
//Membership
var isLoggedIn = _MemberManager.IsLoggedIn();
if (isLoggedIn)
{
return HandleLogout(new PostRedirectModel());
}
...
}
[AllowAnonymous]
[ValidateAntiForgeryToken]
public IActionResult HandleLogout([Bind(new string[] { }, Prefix = "logoutModel")] PostRedirectModel model)
{
IIdentity? identity = this.HttpContext.User.Identity;
if ((identity != null ? (identity.IsAuthenticated ? 1 : 0) : 0) != 0)
{
try
{
this._SignInManager.SignOutAsync().RunSynchronously();
}
catch (Exception e)
{
_Logger.LogWarning(e, "HandleLogout issue");
this._SignInManager.SignOutAsync().Wait();
}
this.HttpContext.Session.Clear();
this.HttpContext.Response.Cookies.Delete(".AspNetCore.Identity.Application");
this.HttpContext.Response.Cookies.Delete(JwtHelper.GetTokenHeaderKey());
}
this.TempData[JwtHelper.GetTokenHeaderKey()] = null;
this.TempData["LogoutSuccess"] = (object)true;
return model.RedirectUrl.IsNullOrWhiteSpace() ? (IActionResult)this.Index() : (IActionResult)this.Redirect(model.RedirectUrl);
}
But it runs VERY slowly. I know I am calling an async method synchronously, but when the page loads visibly for the site visitor, I want the login status to be set correctly.
Has anyone else noticed this delay?
UPDATE: Even if I change it to an async call, it is S-L-O-W.
EssCee
(SC)
November 4, 2025, 1:53pm
6
Could you try to change your HandleLogout and make it truly async by
public async Task<IActionResult> HandleLogout
and changing the existing code similar to
await _SignInManager.SignOutAsync();
and see what difference that makes. Might be worth opening a new thread if this doesnt work to keep the issues separate.
HFloyd
(Heather Floyd)
November 4, 2025, 4:41pm
7
So, I tried that:
public override IActionResult Index()
{
//Membership
var isLoggedIn = _MemberManager.IsLoggedIn();
if (isLoggedIn)
{
var logoutTask= HandleLogout(new PostRedirectModel());
}
...
}
public async Task<IActionResult> HandleLogout([Bind(new string[] { }, Prefix = "logoutModel")] PostRedirectModel model)
{
IIdentity? identity = this.HttpContext.User.Identity;
if ((identity != null ? (identity.IsAuthenticated ? 1 : 0) : 0) != 0)
{
try
{
await this._SignInManager.SignOutAsync();
}
catch (Exception e)
{
_Logger.LogWarning(e, "HandleLogout issue");
}
this.HttpContext.Session.Clear();
this.HttpContext.Response.Cookies.Delete(".AspNetCore.Identity.Application");
this.HttpContext.Response.Cookies.Delete(JwtHelper.GetTokenHeaderKey());
}
this.TempData[JwtHelper.GetTokenHeaderKey()] = null;
this.TempData["LogoutSuccess"] = (object)true;
return model.RedirectUrl.IsNullOrWhiteSpace() ? (IActionResult)this.Index() : (IActionResult)this.Redirect(model.RedirectUrl);
}
And stepping through the code, I noticed that since there was no “waiting” until the logout was completed, when the return redirects back to the same page, isLoggedIn is still TRUE, so it runs HandleLogout again.
I figured that the issue was the redirecting, so I changed it to:
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<bool> HandleLogout([Bind(new string[] { }, Prefix = "logoutModel")] PostRedirectModel model)
{
IIdentity? identity = this.HttpContext.User.Identity;
if ((identity != null ? (identity.IsAuthenticated ? 1 : 0) : 0) != 0)
{
try
{
await this._SignInManager.SignOutAsync();
}
catch (Exception e)
{
_Logger.LogWarning(e, "HandleLogout issue");
return false;
}
this.HttpContext.Session.Clear();
this.HttpContext.Response.Cookies.Delete(".AspNetCore.Identity.Application");
this.HttpContext.Response.Cookies.Delete(JwtHelper.GetTokenHeaderKey());
}
this.TempData[JwtHelper.GetTokenHeaderKey()] = null;
this.TempData["LogoutSuccess"] = (object)true;
return true;
}
Then the page loads faster, but still shows the member logged-in, which isn’t want I want.
If I change the calling code to this:
public override IActionResult Index()
{
//Membership
var isLoggedIn = _MemberManager.IsLoggedIn();
if (isLoggedIn)
{
var logoutTask= HandleLogout(new PostRedirectModel());
logoutTask.Wait();
}
...
}
it once again takes an age to load. I’m just not sure why await this._SignInManager.SignOutAsync(); takes so darn long to complete.
HFloyd
(Heather Floyd)
Closed
December 4, 2025, 4:41pm
8
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.