TempData не равен нулю после обновления

Я думал, что TempData должен был стать нулевым после одного обновления или перенаправления страницы. Для очистки данных требуется два обновления моей страницы, хотя это не то, что я хочу, как мне сделать так, чтобы она стала нулевой после 1 обновления/перенаправления?

@using (Html.BeginForm())
{
    <div class="form-group">
        <button class="btn btn-default" type="submit">test</button>
    </div>
}

public void test()
{
    List<int> integers = new List<int>();
    integers.Add(10);
    integers.Add(20);

    //First Refresh and myList still has values when I want it to be null
    List<int> myList = (List<int>)TempData["test"]; // Take the value from the current data variable

    if (myList == null) // Not yet stored in session, create a new list and store it as a session variable
    {
        myList = new List<int>();
        TempData.Add("test", myList);
    }

    myList.AddRange(integers); // Add a new entry          
}

person Martin Dawson    schedule 10.09.2015    source источник
comment
Он должен быть доступен для следующего запроса, иначе он будет бесполезен.   -  person Evan Mulawski    schedule 10.09.2015
comment
Хорошо. Как мне сохранить данные для следующего запроса, только если действие снова будет test()? И очистить данные для любого другого запроса.   -  person Martin Dawson    schedule 10.09.2015
comment
Покажи свой код действия.   -  person kamil-mrzyglod    schedule 10.09.2015


Ответы (3)


Недавно я просмотрел его исходный код, чтобы узнать, как работает TempData.

Таким образом, срок службы tempdata довольно необычен, так как это только один запрос. Для этого он поддерживает 2 HashSet для управления ключами, а также словарем данных:

private Dictionary<string, object> _data;
private HashSet<string> _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private HashSet<string> _retainedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

Когда вы читаете некоторые данные с помощью индексатора или метода TryGetValue, он удаляет этот ключ из коллекции _initalKeys.

public bool TryGetValue(string key, out object value)
{
    _initialKeys.Remove(key);
    return _data.TryGetValue(key, out value);
}

На данный момент фактический словарь, содержащий данные, не поврежден. Вот почему мы можем читать одни и те же данные последовательно без каких-либо проблем. Он только удаляет ключ из коллекции _initialKeys, помечая его как подлежащий удалению при сохранении данных.

Если вы хотите, чтобы ваши значения в TempData сохранялись дольше, вы можете использовать методы Peek и Keep. Что делает Peek, так это возвращает значение, не удаляя его из _initialKeys:

public object Peek(string key)
{
    object value;
    _data.TryGetValue(key, out value);
    return value;
}

Кроме того, вы можете вызвать метод Keep. Точно так же он не манипулирует данными напрямую, а просто помечает ключ как сохраняемый, добавляя его в коллекцию _retainedKeys.

public void Keep(string key)
{
    _retainedKeys.Add(key);
}

И, наконец, он сохраняет данные (по умолчанию в Session), вызывая метод Save провайдера:

public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider)
{
    _data.RemoveFromDictionary((KeyValuePair<string, object> entry, TempDataDictionary tempData) =>
        {
            string key = entry.Key;
            return !tempData._initialKeys.Contains(key) 
                && !tempData._retainedKeys.Contains(key);
        }, this);

    tempDataProvider.SaveTempData(controllerContext, _data);
}

Таким образом, будут сохранены только те данные, которые остались в коллекции _initialKeys (непрочитанные), и те, которые специально указаны для сохранения (ключи в коллекции _retainedKeys). Отсюда и срок службы!

Ссылка: исходный код TempDataDictionary

person Volkan Paksoy    schedule 10.09.2015

В Asp.Net MVC у нас есть разные методы управления состоянием, такие как Viewbag, ViewData и TempData. TempData является чем-то особенным в том смысле, что он может хранить значение даже для нескольких последовательных запросов в зависимости от того, как значение читается в представлении.

  1. Если это нормальное чтение, то значение станет нулевым для следующего запроса. 2. Если это чтение Peek, например, если вы использовали метод Peek() TempData, тогда значение будет сохранено для следующего запроса. 3. Если это Keep read, что означает, что вы использовали метод Keep() TempData, тогда значение также будет доступно для следующего запроса. 4. Если вы не прочитали значение в представлении, оно будет сохранено до тех пор, пока оно не будет прочитано.

    TempData в MVC с примером

person Aashima Khatoon    schedule 29.07.2020

Если вы хотите сохранить значение в объекте TempData после завершения запроса, вам нужно вызвать метод Keep в текущем действии.

руководство

person Kevin Raffay    schedule 10.09.2015