dotnet / dotnet/aspnetcore

Setting TempData on IExceptionFilter with SessionStateTempDataProvider

Open
#63,845 0 comments 0 reactions 0 assignees View on GitHub
area-mvc feature-session
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

I have implemented a `IExceptionFilter `that sets some data on `TempData `to be read on the redirect action, however since I have enabled `SessionStateTempDataProvider `when the pipeline reaches the response.OnStarting it will try to access Session that at that time has been closed on the `SessionMiddleware`. I know that I can pass the data as query string for example, but this is a legacy application migration that we are migrating slowly so the redirect endpoint is not to be migrated yet and it reads the data from the `TempData`.

### Expected Behavior

To not give exception.

### Steps To Reproduce

Example:

```
var builder = WebApplication.CreateBuilder();

builder.Services.AddSession();
builder.Services.AddScoped();

builder.Services
.AddControllersWithViews()
.AddSessionStateTempDataProvider();
var app = builder.Build();

app.UseRouting();
app.UseSession();
app.MapControllers();
app.Run();
```

```
public sealed class BaseControllerExceptionFilter : IExceptionFilter
{
private readonly ITempDataDictionaryFactory _tempDataFactory;

public BaseControllerExceptionFilter(ITempDataDictionaryFactory tempDataFactory)
{
_tempDataFactory = tempDataFactory;
}

public void OnException(ExceptionContext context)
{

var tempData = _tempDataFactory.GetTempData(context.HttpContext);
tempData["example"] = context.Exception.Message;

context.Result = new RedirectToActionResult(null, "WeatherForecast", null);
context.ExceptionHandled = true;
}
}

```

```
[ApiController]
[Route("[controller]")]
[ServiceFilter(typeof(BaseControllerExceptionFilter))]
public class WeatherForecastController : Controller
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

private readonly ILogger _logger;

public WeatherForecastController(ILogger logger)
{
_logger = logger;
}

[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable Get()
{
var example = TempData["example"];
if(example == null)
{
throw new Exception("123 = 123");
}

return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
```

### Exceptions (if any)

System.InvalidOperationException: Session has not been configured for this application or request.
at Microsoft.AspNetCore.Http.DefaultHttpContext.get_Session()
at Microsoft.AspNetCore.Mvc.ViewFeatures.SessionStateTempDataProvider.SaveTempData(HttpContext context, IDictionary`2 values)
at Microsoft.AspNetCore.Mvc.ViewFeatures.TempDataDictionary.Save()
at Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.SaveTempDataFilter.OnStarting(HttpContext httpContext)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.g__ProcessEvents|241_0(HttpProtocol protocol, Stack`1 events)

### .NET Version

net8.0

### Anything else?

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.