Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TempData Cookie Issue. The size of the request headers is too long

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

enter image description here

and several cookies were created (Chrome Developer Tools > Application > Storage > Cookies)

enter image description here

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 ?

like image 914
Muflix Avatar asked Jan 29 '20 15:01

Muflix


People also ask

How do you use TempData in razor view?

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.

What is TempData in asp net core?

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.


Video Answer


1 Answers

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>

DefaultTempDataSerializer supported types

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);
}
like image 55
Reza Aghaei Avatar answered Oct 05 '22 07:10

Reza Aghaei