У меня есть несколько переменных, которые я должен отправить от страницы до страницы... Что лучший способ состоит в том, чтобы сделать это?
Просто отправьте их один за другим:
string var1 = Session["var1"] == null ? "" : Session["var1"].ToString();
int var2 = Session["var2"] == null ? 0 : int.Parse(Session["var2"].ToString());
и так далее...
Или помещенный их всех в некоторый контейнерный объект?
struct SessionData
{
public int Var1 { get; set; }
public string Var2 { get; set; }
public int Var3 { get; set; }
}
--
SessionData data = Session["data"] as SessionData;
Каково лучшее решение? Что Вы используете?
Гибрид этих двух подходов является наиболее поддерживаемым. Сеанс
предлагает гибкое хранилище пар ключ-значение с низким импедансом, поэтому было бы расточительно не использовать это преимущество. Однако для сложных фрагментов данных, которые всегда связаны друг с другом - например, UserProfile - имеет смысл иметь глубоко вложенный объект.
Я не думаю, что каждый создавал объект только для объединения других объектов для хранения в сеансе, поэтому я бы, вероятно, выбрал первый вариант. Тем не менее, если у вас есть такое большое количество объектов, которые вам нужно объединить, чтобы упростить работу, вы можете пересмотреть свою архитектуру.
Если все данные, которые вы храните в сеансе, связаны, я бы предложил объединить их в один объект, как в вашем втором примере:
public class UserData
{
public string UserName { get; set; }
public string LastPageViewed { get; set; }
public int ParentGroupId { get; set; }
}
А затем загрузить все один раз и сохранить для сеанса.
Однако я бы не предлагал объединять несвязанные данные сеанса в один объект. Я бы разбил каждую отдельную группу связанных элементов на отдельные. В результате получится нечто среднее между двумя предложенными вами жесткими подходами.
Я использую SessionHandler, который представляет собой настраиваемый свернутый класс, который выглядит следующим образом
public static class SessionHandler
{
public static string UserId
{
get
{
return Session["UserId"];
}
set
{
Session["UserId"] = value;
}
}
}
И затем в коде я использую
var user = myDataContext.Users.Where(u => u.UserId = SessionHandler.UserId).FirstOrDefault();
Я использовал оба. В общем, многие имена переменных сеанса приводят к возможности коллизий, что делает коллекции немного более надежными. Убедитесь, что содержимое коллекции относится к единственной ответственности, как и к любому объекту. (Фактически, бизнес-объекты являются отличными кандидатами для объектов сеанса.)
Два совета:
Определите все имена сеансов как общедоступные статические переменные, доступные только для чтения, и сделайте стандартом кодирования использование только этих статических переменных при именовании данных сеанса.
Во-вторых, убедитесь, что каждый объект отмечен атрибутом [Serializable]
. Если вам когда-либо понадобится сохранить состояние сеанса вне процесса, это необходимо.