Fix #5649: handle not found request.

This commit is contained in:
Ben
2025-11-20 19:03:26 +08:00
parent e08c033e76
commit 012b7ba6ed
4 changed files with 95 additions and 4 deletions

View File

@ -29,6 +29,8 @@ namespace Oqtane.UI
public bool Refresh { get; set; }
public bool AllowCookies { get; set; }
public int? StatusCode { get; set; }
public List<Page> Pages
{
get { return Site?.Pages; }
@ -63,7 +65,8 @@ namespace Oqtane.UI
IsInternalNavigation = IsInternalNavigation,
RenderId = RenderId,
Refresh = Refresh,
AllowCookies = AllowCookies
AllowCookies = AllowCookies,
StatusCode = StatusCode
};
}
}

View File

@ -158,7 +158,9 @@
// verify user is authenticated for current site
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (authState.User.Identity.IsAuthenticated && authState.User.Claims.Any(item => item.Type == Constants.SiteKeyClaimType && item.Value == SiteState.Alias.SiteKey))
if (authState.User.Identity.IsAuthenticated
&& authState.User.Claims.Any(item => item.Type == Constants.SiteKeyClaimType && item.Value == SiteState.Alias.SiteKey)
&& PageState.StatusCode != (int)HttpStatusCode.NotFound)
{
// get user
var userid = int.Parse(authState.User.Claims.First(item => item.Type == ClaimTypes.NameIdentifier).Value);
@ -337,6 +339,7 @@
IsInternalNavigation = _isInternalNavigation,
RenderId = renderid,
Refresh = false,
StatusCode = PageState?.StatusCode,
AllowCookies = _allowCookies.GetValueOrDefault(true)
};
OnStateChange?.Invoke(_pagestate);

View File

@ -170,6 +170,7 @@
if (page == null || page.IsDeleted)
{
HandlePageNotFound(site, page, route);
return;
}
else
{
@ -248,6 +249,7 @@
IsInternalNavigation = false,
RenderId = Guid.NewGuid(),
Refresh = true,
StatusCode = Context.Response.StatusCode,
AllowCookies = _allowCookies
};
}
@ -300,8 +302,16 @@
{
if (route.PagePath != "404")
{
// redirect to 404 page
NavigationManager.NavigateTo(route.SiteUrl + "/404", true);
// handle not found request in static mode
if(_renderMode == RenderModes.Static)
{
NavigationManager.NotFound();
}
else
{
// redirect to 404 page
NavigationManager.NavigateTo(route.SiteUrl + "/404", true);
}
}
}
}

View File

@ -1,8 +1,11 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
@ -65,6 +68,7 @@ namespace Oqtane.Extensions
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();
app.UseNotFoundResponse();
// execute any IServerStartup logic
app.ConfigureOqtaneAssemblies(environment);
@ -146,5 +150,76 @@ namespace Oqtane.Extensions
public static IApplicationBuilder UseExceptionMiddleWare(this IApplicationBuilder builder)
=> builder.UseMiddleware<ExceptionMiddleware>();
public static IApplicationBuilder UseNotFoundResponse(this IApplicationBuilder app)
{
const string notFoundRoute = "/404";
app.UseStatusCodePagesWithReExecute(notFoundRoute, createScopeForStatusCodePages: true);
app.Use(async (context, next) =>
{
var path = context.Request.Path.Value ?? string.Empty;
if (ShouldSkipStatusCodeReExecution(path))
{
var feature = context.Features.Get<IStatusCodePagesFeature>();
feature?.Enabled = false;
}
await next();
});
app.Use(async (context, next) =>
{
var feature = context.Features.Get<IStatusCodeReExecuteFeature>();
var handled = false;
if (feature != null
&& context.Response.StatusCode == (int)HttpStatusCode.NotFound
&& notFoundRoute.Equals(context.Request.Path.Value, StringComparison.OrdinalIgnoreCase))
{
var alias = context.GetAlias();
if (!string.IsNullOrEmpty(alias?.Path))
{
var originalPath = context.Request.Path;
context.Request.Path = new PathString($"/{alias.Path}{notFoundRoute}");
try
{
handled = true;
await next();
}
finally
{
context.Request.Path = originalPath;
}
}
}
if (!handled)
{
await next();
}
});
return app;
}
static bool ShouldSkipStatusCodeReExecution(string path)
{
return path.Contains("/api/", StringComparison.OrdinalIgnoreCase) ||
path.StartsWith("/_framework/", StringComparison.OrdinalIgnoreCase) ||
path.StartsWith("/_content/", StringComparison.OrdinalIgnoreCase) ||
HasStaticFileExtension(path);
}
static bool HasStaticFileExtension(string path)
{
var extension = Path.GetExtension(path);
if (string.IsNullOrEmpty(extension))
{
return false;
}
var staticExtensions = new[] { ".js", ".css", ".map", ".json", ".jpg", ".jpeg", ".png", ".gif", ".svg", ".webp", ".ico", ".woff", ".woff2", ".ttf", ".eot", ".otf", ".mp4", ".webm", ".ogg", ".mp3", ".wav", ".pdf", ".txt", ".xml" };
return staticExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
}
}
}