Як використовувати сеанси в додатку ASP.NET MVC 4?


113

Я новачок у ASP.NET MVC. Раніше я використовував PHP, і було легко створити сеанс і вибрати записи користувачів на основі змінних поточних сеансів.

Я шукав всюди в Інтернеті простий покроковий посібник, який може показати мені, як створювати та використовувати сеанси в моєму додатку C # ASP.NET MVC 4. Я хочу створити сеанс із змінними користувача, до яких я можу отримати доступ з будь-якого місця моїх контролерів і мати можливість використовувати змінні у своїх запитах LINQ.



2
Ця стаття може зацікавити: brockallen.com/2012/04/07/think-twice-about-using-session-state
Daniel Hollinrake

Відповіді:


160

Спробуйте

//adding data to session
//assuming the method below will return list of Products

var products=Db.GetProducts();

//Store the products to a session

Session["products"]=products;

//To get what you have stored to a session

var products=Session["products"] as List<Product>;

//to clear the session value

Session["products"]=null;

3
Дякую, Джоберте! ти дав мені ідею! просто цікаво, хоча .., можна додати змінні користувача до сеансу під час входу? а також у мене буде доступ до змінних сеансів (створених лише один раз) для різних контролерів у моїй програмі?
Thuto Paul Gaotingwe

31
Ви можете зберігати що-небудь або будь-які дані будь-якого типу в сеансі. Після створення ви можете отримати доступ до збереженого до нього значення у всіх представленнях та контролерах. Зауважте також, що створений сеанс доступний лише для кожного користувача та для одного браузера. Тобто сеанс, створений User1 за допомогою Firefox, не може бути доступним тим самим користувачем, що використовує IE. Є речі, які також не слід робити із сеансом, наприклад. НЕ зберігайте великі дані на ньому. Це може уповільнити продуктивність вашого сервера. Нарешті, НЕ зберігайте конфіденційні дані до сеансу, наприклад, пароль або номер кредитної картки
Jobert Enamno

2
Ще раз дякую! Де я створюю його, щоб мати доступ до нього через різні контролери?
Thuto Paul Gaotingwe

2
@JobertEnamno чи безпечно зберігати значення, яке походить від цього, WebSecurity.CurrentUserIdщоб воно не витягувало його з бази даних кілька разів (я виявив, що це дуже дорого)?
Андрій Нарушевічус

2
Не існує сеансу перехресного контролера, тому коли ви запитуєте інший контролер, наприклад, від Account/LogOnдо Home/Index, Session["FirstName"]є null. Розробники повинні створити батьківський контролер ( BaseController) та визначити захищене поле ( internal protected HttpSessionStateBase SharedSession), яке може відкрити загальну змінну Session у всіх підконтролерах (це передбачає, що всі ваші контролери додатків успадковують саме від цього BaseController)
Bellash

63

Через нестандартність Інтернету, сеанси також є надзвичайно корисним способом зберігання об'єктів у запитах шляхом їх послідовного зберігання та зберігання у сеансі.

Ідеальним випадком використання цього може бути, якщо вам потрібно отримати доступ до регулярної інформації у вашій програмі, щоб зберегти додаткові дзвінки до бази даних за кожним запитом, ці дані можуть бути збережені в об'єкті та несеріалізовані для кожного запиту, наприклад:

Наш об'єкт для багаторазового використання, що серіалізується:

[Serializable]
public class UserProfileSessionData
{
    public int UserId { get; set; }

    public string EmailAddress { get; set; }

    public string FullName { get; set; }
}

Корпус:

public class LoginController : Controller {

    [HttpPost]
    public ActionResult Login(LoginModel model)
    {
        if (ModelState.IsValid)
        {
            var profileData = new UserProfileSessionData {
                UserId = model.UserId,
                EmailAddress = model.EmailAddress,
                FullName = model.FullName
            }

            this.Session["UserProfile"] = profileData;
        }
    }

    public ActionResult LoggedInStatusMessage()
    {
        var profileData = this.Session["UserProfile"] as UserProfileSessionData;

        /* From here you could output profileData.FullName to a view and
        save yourself unnecessary database calls */
    }

}

Після того, як цей об’єкт був серіалізований, ми можемо використовувати його в усіх контролерах, не потребуючи його створення або запитування бази даних щодо даних, що містяться в ньому знову.

Введіть об’єкт сеансу за допомогою ін'єкції залежності

В ідеальному світі ви б " запрограмували на інтерфейс, а не на реалізацію " і ввели ваш об'єкт серіалізаційного сеансу в свій контролер, використовуючи вибраний вами контейнер "Інверсія контролю" (у цьому прикладі використовується StructureMap, оскільки це найбільше мені знайоме ).

public class WebsiteRegistry : Registry
{
    public WebsiteRegistry()
    {
        this.For<IUserProfileSessionData>().HybridHttpOrThreadLocalScoped().Use(() => GetUserProfileFromSession());   
    }

    public static IUserProfileSessionData GetUserProfileFromSession()
    {
        var session = HttpContext.Current.Session;
        if (session["UserProfile"] != null)
        {
            return session["UserProfile"] as IUserProfileSessionData;
        }

        /* Create new empty session object */
        session["UserProfile"] = new UserProfileSessionData();

        return session["UserProfile"] as IUserProfileSessionData;
    }
}

Потім ви зареєструєте це у своєму Global.asax.csфайлі.

Для тих, хто не знайомий з об'єктами введення сеансу, ви можете знайти більш глибоку публікацію в блозі про цю тему тут .

Слово попередження:

Варто зазначити, що сеанси повинні бути зведені до мінімуму, великі сеанси можуть почати викликати проблеми з ефективністю.

Також рекомендується не зберігати в них будь-яких конфіденційних даних (паролів тощо).


Де ви б хоч поставили визначення класу? Я все ще досить новий, але мені просто цікаво, як інші контролери побачать клас і знають, що це таке. Ви просто додаєте його до верхньої частини контролера? Я думав про SessionStart в global.asax, я би ініціалізував речі, але, можливо, це не найкращий спосіб зробити це.
Shaun314

@ Shaun314 В ідеалі ви б використовували контейнер IoC для введення об'єкта в контролер за допомогою ін'єкції залежності (див. Редагування).
Джозеф Вудвард

1
Я зберігаю деяку інформацію про сеанс після входу користувача за допомогою Identity 2. Я не в змозі отримати цю інформацію в інших діях та контролерах, крім першої дії, на яку я перенаправляю користувача. Будь-яка ідея?
Акбарі

17

Ось як працює стан сеансу в ASP.NET та ASP.NET MVC:

Огляд стану сеансу ASP.NET

В основному, ви робите це для збереження значення в об'єкті Session:

Session["FirstName"] = FirstNameTextBox.Text;

Щоб отримати значення:

var firstName = Session["FirstName"];

10
Не існує сеансу перехресного контролера, тому коли ви запитуєте інший контролер, наприклад, від Accountдо Home, сесія ["FirstName"] є недійсною. Розробники повинні створити BaseControllerі визначити захищене поле ( internal protected HttpSessionStateBase SharedSession), яке може викрити загальну Sessionзмінну у всіх підконтролерах (це передбачає, що всі ваші контролери додатків успадковують це BaseController)
Bellash,

4
Гм, впевнений, що є? У контролері є змінна Session (базовий контролер, наданий MVC).
aeliusd

7
@Bellash це абсолютно неправильно. Сесії доступні через контролери. Я просто встановив Session ["тест"] в HomeController, а потім прочитав його в моєму обліковому записі.
niico

0

Ви можете зберігати будь-які дані в сеансі, використовуючи:

Session["VariableName"]=value;

Ця змінна триватиме 20 хвилин або близько того.


-8

U може зберігати будь-яке значення в сеансі, як Session ["FirstName"] = FirstNameTextBox.Text; але я запропону вам взяти статичне поле в моделі, присвоїти йому значення, і ви можете отримати це значення поля будь-де в застосуванні. Вам не потрібен сеанс. сеансу слід уникати.

public class Employee
{
   public int UserId { get; set; }
   public string EmailAddress { get; set; }
   public static string FullName { get; set; }
}

на контролері - Employee.FullName = "ABC"; Тепер ви можете отримати доступ до цього повного Імені в будь-якому місці програми.


10
Зберігання даних про статичні поля, особливо дані користувачів, як-от ім’я Співробітника, спричинить серйозні проблеми в середовищі для багатьох користувачів. Коли два різні користувачі входять у систему, вони побачать одного і того ж Employee.EmailAddress, оскільки статичне поле для Employee однакове для кожного екземпляра.
Gökçer Gökdal
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.