добавить к TempData из неконтроллерного класса - PullRequest
4 голосов
/ 03 февраля 2009

Как добавить словарь TempData из класса, не являющегося контроллером?

Ответы [ 4 ]

3 голосов
/ 04 февраля 2009

Вы должны будете передать TempDataDictionary другому классу. Я делаю это совсем немного, и в этом нет ничего плохого, если другой класс связан с презентацией (что звучит так, как есть).

2 голосов
/ 08 июля 2014

Вам не нужен ControllerContext , вам нужен только текущий HttpContext .

И вам не нужно ничего передавать, вы можете создать новый SessionStateTempDataProvider и использовать его, потому что единственное, что делает метод SaveTempData этого класса, - это устанавливает IDictionary для определенного ключа в текущий сеанс.

(Если ваше приложение не использует какой-либо пользовательский ITempDataProvider . Если вы это сделаете, вы, очевидно, должны вместо этого полагаться на это.)

SessionStateTempDataProvider - это очень простой класс:

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Web.Mvc.Properties;

namespace System.Web.Mvc
{
    public class SessionStateTempDataProvider : ITempDataProvider
    {
        internal const string TempDataSessionStateKey = "__ControllerTempData";

        public virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext)
        {
            HttpSessionStateBase session = controllerContext.HttpContext.Session;

            if (session != null)
            {
                Dictionary<string, object> tempDataDictionary = session[TempDataSessionStateKey] as Dictionary<string, object>;

                if (tempDataDictionary != null)
                {
                    // If we got it from Session, remove it so that no other request gets it
                    session.Remove(TempDataSessionStateKey);
                    return tempDataDictionary;
                }
            }

            return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
        }

        public virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }

            HttpSessionStateBase session = controllerContext.HttpContext.Session;
            bool isDirty = (values != null && values.Count > 0);

            if (session == null)
            {
                if (isDirty)
                {
                    throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
                }
            }
            else
            {
                if (isDirty)
                {
                    session[TempDataSessionStateKey] = values;
                }
                else
                {
                    // Since the default implementation of Remove() (from SessionStateItemCollection) dirties the
                    // collection, we shouldn't call it unless we really do need to remove the existing key.
                    if (session[TempDataSessionStateKey] != null)
                    {
                        session.Remove(TempDataSessionStateKey);
                    }
                }
            }
        }
    }
}

Таким образом, мы можем сделать:

var httpContext = new HttpContextWrapper(HttpContext.Current);
var newValues = new Dictionary<string, object> {{"myKey", myValue}};
new SessionStateTempDataProvider().SaveTempData(new ControllerContext { HttpContext = httpContext }, newValues);

Обратите внимание, что это каждый раз переопределяет существующий Словарь, поэтому, если вы хотите последовательно добавлять данные, вам, очевидно, придется полагаться на промежуточный контейнер или написать дополнительную логику для объединения существующих значений с новыми значениями.

Мой случай, когда мне нужно сделать это, для обработки страниц с ошибками, где я делаю перенаправление, но где мне нужно иметь логику сохранения временных данных вне области действия контроллера.

1 голос
/ 13 февраля 2016

Свойство ControllerBase.TempData

System.Web.Mvc.TempDataDictionary

Вы можете использовать публичные TempDataDictionary TempData {get; задавать; }

для использования TempData

например. Like TempData.Clear (); // Очистить TempData в другом классе

0 голосов
/ 03 февраля 2009

Для этого вам понадобится текущий контекст контроллера, в противном случае вы не сможете.

ViewContext.Controller.TempData ["чем угодно"] = что угодно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...