In Controller, I save a collection of errors into cookies
via TempData
var messages = new List<Message>();
...
TempData.Put("Errors", messages);
TempData.Put is an extension method
public static class TempDataExtensions
{
public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class
{
tempData[key] = JsonConvert.SerializeObject(value);
}
public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class
{
tempData.TryGetValue(key, out object o);
return o == null ? null : JsonConvert.DeserializeObject<T>((string)o);
}
}
When HTML is loaded, I see
and several cookies were created (Chrome Developer Tools > Application > Storage > Cookies)
The issue I think, is that total size of Cookies is hitting some Cookie Size limit somewhere.
So I have two questions :
Is it possible to change the cookie size limit (in web.config for example) ?
Is it possible to use session instead of cookies for TempData
?
I tried the second approach and if I change the startup.cs file
\\ ConfigureServices method
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddSessionStateTempDataProvider();
services.AddSession();
\\ Configure method
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
The TempData are still using Cookies, do I forgot some setting somewhere ?
Passing the data from Controller to View using TempDataGo to File then New and select “Project” option. Then create the ASP.NET web application project as depicted below. Then select “Empty” and tick “MVC” then click OK. The project is created successfully.
TempData. ASP.NET Core exposes the Razor Pages TempData or Controller TempData. This property stores data until it's read in another request. The Keep(String) and Peek(string) methods can be used to examine the data without deletion at the end of the request.
You can use HTTP cookies or session state as storage mechanism for TempData
. The cookie-based TempData
provider is the default.
You can read more about Choose a TempData provider.
Based on the following example from docs you can enable the session-based TempData
provider, by calling AddSessionStateTempDataProvider
extension method. The order of middleware is important.
Be aware of
DefaultTempDataSerializer
limitations pointed out at bottom of this answer.
Example
Hers is a working deployment using the following setup that I have for Srartup:
public class Startup
{
public Startup(IConfiguration configuration) { Configuration = configuration; }
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddSessionStateTempDataProvider();
services.AddSession();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else {
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseMvc(routes => {
routes.MapRoute(name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
The HomeController:
public class HomeController : Controller
{
public IActionResult Index()
{
TempData["LargeData"] = new string('a', 1 * 1024 * 1024);
return View();
}
}
And the Index View:
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome - @(((string)TempData["LargeData"]).Length)</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">
building Web apps with ASP.NET Core</a>.</p>
</div>
Be aware of DefaultTempDataSerializer
supported type limitations:
public override bool CanSerializeType(Type type)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
type = Nullable.GetUnderlyingType(type) ?? type;
return
type.IsEnum ||
type == typeof(int) ||
type == typeof(string) ||
type == typeof(bool) ||
type == typeof(DateTime) ||
type == typeof(Guid) ||
typeof(ICollection<int>).IsAssignableFrom(type) ||
typeof(ICollection<string>).IsAssignableFrom(type) ||
typeof(IDictionary<string, string>).IsAssignableFrom(type);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With