Cache OnStarting callback delegate (#9283)
This commit is contained in:
parent
9173c5adeb
commit
84da613d2c
|
|
@ -14,6 +14,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Filters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class SaveTempDataFilter : IResourceFilter, IResultFilter
|
internal class SaveTempDataFilter : IResourceFilter, IResultFilter
|
||||||
{
|
{
|
||||||
|
private static readonly Func<object, Task> OnStartingCallback = (state) => OnStarting((HttpContext)state);
|
||||||
// Internal for unit testing
|
// Internal for unit testing
|
||||||
internal static readonly object SaveTempDataFilterContextKey = new object();
|
internal static readonly object SaveTempDataFilterContextKey = new object();
|
||||||
|
|
||||||
|
|
@ -43,38 +44,39 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Filters
|
||||||
|
|
||||||
if (!context.HttpContext.Response.HasStarted)
|
if (!context.HttpContext.Response.HasStarted)
|
||||||
{
|
{
|
||||||
context.HttpContext.Response.OnStarting((state) =>
|
context.HttpContext.Response.OnStarting(
|
||||||
{
|
callback: OnStartingCallback,
|
||||||
var httpContext = (HttpContext)state;
|
state: context.HttpContext);
|
||||||
|
|
||||||
var saveTempDataContext = GetTempDataContext(context.HttpContext);
|
|
||||||
if (saveTempDataContext.RequestHasUnhandledException)
|
|
||||||
{
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If temp data was already saved, skip trying to save again as the calls here would potentially fail
|
|
||||||
// because the session feature might not be available at this point.
|
|
||||||
// Example: An action returns NoContentResult and since NoContentResult does not write anything to
|
|
||||||
// the body of the response, this delegate would get executed way late in the pipeline at which point
|
|
||||||
// the session feature would have been removed.
|
|
||||||
if (saveTempDataContext.TempDataSaved)
|
|
||||||
{
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveTempData(
|
|
||||||
result: null,
|
|
||||||
factory: saveTempDataContext.TempDataDictionaryFactory,
|
|
||||||
filters: saveTempDataContext.Filters,
|
|
||||||
httpContext: httpContext);
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
},
|
|
||||||
state: context.HttpContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Task OnStarting(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
var saveTempDataContext = GetTempDataContext(httpContext);
|
||||||
|
if (saveTempDataContext.RequestHasUnhandledException)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If temp data was already saved, skip trying to save again as the calls here would potentially fail
|
||||||
|
// because the session feature might not be available at this point.
|
||||||
|
// Example: An action returns NoContentResult and since NoContentResult does not write anything to
|
||||||
|
// the body of the response, this delegate would get executed way late in the pipeline at which point
|
||||||
|
// the session feature would have been removed.
|
||||||
|
if (saveTempDataContext.TempDataSaved)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveTempData(
|
||||||
|
result: null,
|
||||||
|
factory: saveTempDataContext.TempDataDictionaryFactory,
|
||||||
|
filters: saveTempDataContext.Filters,
|
||||||
|
httpContext: httpContext);
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||||
{
|
{
|
||||||
|
|
@ -115,7 +117,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Filters
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SaveTempDataContext GetTempDataContext(HttpContext httpContext)
|
private static SaveTempDataContext GetTempDataContext(HttpContext httpContext)
|
||||||
{
|
{
|
||||||
SaveTempDataContext saveTempDataContext = null;
|
SaveTempDataContext saveTempDataContext = null;
|
||||||
if (httpContext.Items.TryGetValue(SaveTempDataFilterContextKey, out var value))
|
if (httpContext.Items.TryGetValue(SaveTempDataFilterContextKey, out var value))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue