TempData Cookie 问题。请求头的大小太长

Muf*_*lix 9 cookies session tempdata asp.net-core

Controller 中,我将一组错误保存到cookiesviaTempData

var messages = new List<Message>();
...
TempData.Put("Errors", messages);
Run Code Online (Sandbox Code Playgroud)

TempData.Put 是一个扩展方法

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

加载 HTML 时,我看到

在此处输入图片说明

并创建了几个 cookie(Chrome 开发者工具 > 应用程序 > 存储 > Cookies)

在此处输入图片说明

我认为的问题是 Cookie 的总大小在某处达到了某些 Cookie 大小限制。

所以我有两个问题:是否可以更改 cookie 大小限制(例如在 web.config 中)?是否可以使用 session 而不是 cookie TempData

我尝试了第二种方法,如果我更改了startup.cs文件

\\ 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?}");
});
Run Code Online (Sandbox Code Playgroud)

TempData 仍在使用 Cookie,我是否忘记了某些设置?

Rez*_*aei 5

您可以使用 HTTP cookie 或会话状态作为TempData. 基于 cookie 的TempData提供程序是默认的。您可以阅读有关选择 TempData 提供程序的更多信息。

根据文档中的以下示例,您可以TempData通过调用AddSessionStateTempDataProvider扩展方法启用基于会话的提供程序。中间件的顺序很重要。

请注意DefaultTempDataSerializer此答案底部指出的限制。

例子

Hers 是使用我为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?}");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

家庭控制器

public class HomeController : Controller
{
    public IActionResult Index()
    {
        TempData["LargeData"] = new string('a', 1 * 1024 * 1024);
        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)

索引视图:

@{
    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>
Run Code Online (Sandbox Code Playgroud)

DefaultTempDataSerializer 支持的类型

请注意DefaultTempDataSerializer支持的类型限制:

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);
}
Run Code Online (Sandbox Code Playgroud)