TempData Cook ie Проблема. Размер заголовка запроса слишком длинный - PullRequest
5 голосов
/ 29 января 2020

В Контроллере , я сохраняю коллекцию ошибок в cookies через TempData

var messages = new List<Message>();
...
TempData.Put("Errors", messages);

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);
        }
    }

Когда загружено HTML, я вижу

enter image description here

и было создано несколько файлов cookie (Chrome Инструменты разработчика> Приложение> Хранение> Файлы cookie)

enter image description here

Мне кажется, проблема в том, что общий размер файлов cookie достигает некоторого размера Cook ie где-то в пределе.

Итак, я есть два вопроса: можно ли изменить ограничение размера cook ie (например, в web.config)? Можно ли использовать сеанс вместо файлов 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?}");
});

TempData все еще использует Cookies, я забыл где-нибудь настройки?

1 Ответ

2 голосов
/ 20 февраля 2020

Вы можете использовать файлы cookie HTTP или состояние сеанса в качестве механизма хранения для TempData. Поставщик cook ie TempData по умолчанию. Вы можете прочитать больше о Выбор поставщика TempData .

На основе следующего примера из docs вы можете включить основанного на сеансе поставщика 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?}");
        });
    }
}

HomeController :

public class HomeController : Controller
{
    public IActionResult Index()
    {
        TempData["LargeData"] = new string('a', 1 * 1024 * 1024);
        return 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 поддерживаемые типы

Помните о 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);
}
...