Skip to content

Commit 1333973

Browse files
committed
[add] previous page URL update handling (disabled by default)
1 parent cfa3067 commit 1333973

8 files changed

Lines changed: 58 additions & 9 deletions

File tree

src/Simplify.Web.Tests/Controllers/Execution/PreviousPageUrlUpdaterTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System.Collections.Generic;
22
using System.Threading.Tasks;
3+
using Microsoft.AspNetCore.Http;
34
using Moq;
45
using NUnit.Framework;
56
using Simplify.Web.Controllers;
67
using Simplify.Web.Controllers.Execution;
8+
using Simplify.Web.Modules.Context;
79
using Simplify.Web.Modules.Redirection;
810

911
namespace Simplify.Web.Tests.Controllers.Execution;
@@ -17,13 +19,18 @@ public class PreviousPageUrlUpdaterTests
1719

1820
private Mock<IControllersExecutor> _baseExecutor = null!;
1921
private Mock<IRedirector> _redirector = null!;
22+
private Mock<IWebContext> _webContext = null!;
2023

2124
[SetUp]
2225
public void Initialize()
2326
{
2427
_baseExecutor = new Mock<IControllersExecutor>();
2528
_redirector = new Mock<IRedirector>();
26-
_updater = new PreviousPageUrlUpdater(_baseExecutor.Object, _redirector.Object);
29+
_webContext = new Mock<IWebContext>();
30+
31+
_webContext.SetupGet(x => x.Response).Returns(new Mock<HttpResponse>().Object);
32+
33+
_updater = new PreviousPageUrlUpdater(_baseExecutor.Object, _redirector.Object, _webContext.Object);
2734
}
2835

2936
[Test]

src/Simplify.Web/Bootstrapper/Setup/BaseBootstrapperControllersExecution.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Simplify.Web.Controllers.Response;
77
using Simplify.Web.Controllers.V1.Execution;
88
using Simplify.Web.Controllers.V2.Execution;
9+
using Simplify.Web.Modules.Context;
910
using Simplify.Web.Modules.Redirection;
1011

1112
namespace Simplify.Web.Bootstrapper.Setup;
@@ -62,9 +63,13 @@ public virtual void RegisterControllersExecutor()
6263

6364
BootstrapperFactory.ContainerProvider.Register<ControllersExecutor>();
6465

65-
BootstrapperFactory.ContainerProvider.Register<IControllersExecutor>(r =>
66-
new PreviousPageUrlUpdater(
66+
if (!Settings.DisablePreviousPageUrlUpdate)
67+
BootstrapperFactory.ContainerProvider.Register<IControllersExecutor>(r =>
68+
new PreviousPageUrlUpdater(
6769
r.Resolve<ControllersExecutor>(),
68-
r.Resolve<IRedirector>()));
70+
r.Resolve<IRedirector>(),
71+
r.Resolve<IWebContext>()));
72+
else
73+
BootstrapperFactory.ContainerProvider.Register<IControllersExecutor>(r => r.Resolve<ControllersExecutor>());
6974
}
7075
}

src/Simplify.Web/CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Changelog
22

3+
## [5.6.0] - 2026-07-24
4+
5+
### Added
6+
7+
- `DisablePreviousPageUrlUpdate` setting (default: `true`) to control automatic
8+
previous-page URL cookie tracking. The feature is now disabled by default — the
9+
`PreviousPageUrlUpdater` decorator is not registered, eliminating both the cookie
10+
write and its entry in the controller-execution call stack.
11+
Set to `false` in `SimplifyWebSettings` to re-enable the previous-page tracking.
12+
Configure via `SimplifyWebSettings:DisablePreviousPageUrlUpdate` in appsettings.json.
13+
14+
### Fixed
15+
16+
- `StatusCode.ExecuteAsync()`: check `Response.HasStarted` before setting the status
17+
code and content type, preventing an `InvalidOperationException` when the response
18+
has already started (e.g. because an earlier middleware wrote to it).
19+
- `PreviousPageUrlUpdater`: skip cookie setting when `Response.HasStarted` is true,
20+
preventing a crash when the response stream is already being written.
21+
322
## [5.5.0] - 2026-07-06
423

524
### Added

src/Simplify.Web/Controllers/Execution/PreviousPageUrlUpdater.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Threading.Tasks;
3+
using Simplify.Web.Modules.Context;
34
using Simplify.Web.Modules.Redirection;
45

56
namespace Simplify.Web.Controllers.Execution;
@@ -8,7 +9,7 @@ namespace Simplify.Web.Controllers.Execution;
89
/// Provides the previous page URL updater
910
/// </summary>
1011
/// <seealso cref="IControllersExecutor" />
11-
public class PreviousPageUrlUpdater(IControllersExecutor baseExecutor, IRedirector redirector) : IControllersExecutor
12+
public class PreviousPageUrlUpdater(IControllersExecutor baseExecutor, IRedirector redirector, IWebContext webContext) : IControllersExecutor
1213
{
1314
/// <summary>
1415
/// Executes the controllers asynchronously.
@@ -18,7 +19,7 @@ public async Task<ResponseBehavior> ExecuteAsync(IReadOnlyList<IMatchedControlle
1819
{
1920
var result = await baseExecutor.ExecuteAsync(controllers);
2021

21-
if (result == ResponseBehavior.Default)
22+
if (result == ResponseBehavior.Default && !webContext.Response.HasStarted)
2223
redirector.SetPreviousPageUrlToCurrentPage();
2324

2425
return result;

src/Simplify.Web/Responses/StatusCode.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ public class StatusCode(int statusCode, string? responseData = null, string? con
3737
/// </summary>
3838
public override async Task<ResponseBehavior> ExecuteAsync()
3939
{
40-
Context.Response.StatusCode = Code;
40+
if (!Context.Response.HasStarted)
41+
Context.Response.StatusCode = Code;
4142

42-
if (ContentType != null)
43+
if (ContentType != null && !Context.Response.HasStarted)
4344
Context.Response.ContentType = ContentType;
4445

4546
if (ResponseData != null)

src/Simplify.Web/Settings/ISimplifyWebSettings.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,14 @@ public interface ISimplifyWebSettings
188188
/// Requests with a Content-Length exceeding this value will be rejected.
189189
/// </summary>
190190
long MaxRequestBodySize { get; }
191+
192+
/// <summary>
193+
/// Gets the value indicating whether the automatic previous page URL update
194+
/// (via cookie) after each request should be disabled.
195+
/// When enabled, Simplify.Web automatically stores the current page URL as the
196+
/// "previous page" URL after each successful request.
197+
/// Disable this if you do not need this functionality or if it conflicts with
198+
/// responses that start writing before the URL can be stored (e.g. <c>StatusCode</c> responses).
199+
/// </summary>
200+
bool DisablePreviousPageUrlUpdate { get; }
191201
}

src/Simplify.Web/Settings/SimplifyWebSettings.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ public SimplifyWebSettings(IConfiguration configuration)
216216
/// </summary>
217217
public long MaxRequestBodySize { get; private set; } = 104857600;
218218

219+
/// <summary>
220+
/// Gets the value indicating whether the automatic previous page URL update (via cookie) after each request should be disabled.
221+
/// </summary>
222+
public bool DisablePreviousPageUrlUpdate { get; private set; } = true;
223+
219224
private void LoadLanguageManagerSettings(IConfiguration config)
220225
{
221226
DefaultLanguage = config.GetValueOrDefaultValue(nameof(DefaultLanguage), DefaultLanguage);
@@ -273,6 +278,7 @@ private void LoadEngineBehaviorSettings(IConfiguration config)
273278
HideExceptionDetails = config.GetValue<bool?>(nameof(HideExceptionDetails)) ?? HideExceptionDetails;
274279
ErrorPageDarkStyle = config.GetValue<bool>(nameof(ErrorPageDarkStyle));
275280
MaxRequestBodySize = config.GetValue<long?>(nameof(MaxRequestBodySize)) ?? MaxRequestBodySize;
281+
DisablePreviousPageUrlUpdate = config.GetValue<bool?>(nameof(DisablePreviousPageUrlUpdate)) ?? DisablePreviousPageUrlUpdate;
276282
}
277283

278284
private void LoadCacheSettings(IConfiguration config)

src/Simplify.Web/Simplify.Web.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
1010
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1111

12-
<Version>5.5</Version>
12+
<Version>5.6</Version>
1313

1414
<Description>Lightweight and fast .NET web-framework based on MVC and OWIN</Description>
1515
<Product>Simplify</Product>

0 commit comments

Comments
 (0)