Bagaimana cara menggunakan sesi dalam aplikasi ASP.NET MVC 4?

113

Saya baru mengenal ASP.NET MVC. Saya telah menggunakan PHP sebelumnya dan mudah untuk membuat sesi dan memilih catatan pengguna berdasarkan variabel sesi saat ini.

Saya telah mencari di mana-mana di Internet untuk tutorial langkah-demi-langkah sederhana yang dapat menunjukkan cara membuat dan menggunakan sesi di aplikasi C # ASP.NET MVC 4 saya. Saya ingin membuat sesi dengan variabel pengguna yang dapat saya akses dari mana saja di pengontrol saya dan dapat menggunakan variabel dalam kueri LINQ saya.

Thuto Paul Gaotingwe
sumber
2
kemungkinan duplikat Cara mempertahankan sesi Pengguna dengan ASP.NET MVC
adatapost
2
Artikel ini mungkin menarik: brockallen.com/2012/04/07/think-twice-about-using-session-state
Daniel Hollinrake

Jawaban:

160

Mencoba

//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;
Jobert Enamno
sumber
3
Terima kasih Jobert! kamu memberi saya ide! hanya ingin tahu .., apakah mungkin menambahkan variabel pengguna ke sesi selama login? dan juga akankah saya memiliki akses ke variabel sesi (dibuat hanya sekali) di berbagai pengontrol dalam aplikasi saya?
Thuto Paul Gaotingwe
31
Anda dapat menyimpan apa saja atau data apa pun dalam satu sesi. Setelah dibuat, Anda dapat mengakses nilai yang disimpan di dalamnya di semua tampilan dan pengontrol. Perhatikan juga bahwa sesi yang dibuat hanya dapat diakses per pengguna dan per browser. Artinya sesi yang dibuat oleh User1 menggunakan Firefox tidak dapat diakses oleh pengguna yang sama menggunakan IE. Ada hal-hal yang juga tidak boleh Anda lakukan dengan sesi seperti. JANGAN menyimpan data besar di dalamnya. Ini dapat memperlambat kinerja server Anda. Terakhir JANGAN menyimpan data sensitif ke sesi seperti Kata Sandi atau nomor kartu kredit
Jobert Enamno
2
Terima kasih sekali lagi! Di mana saya membuatnya agar dapat mengaksesnya di berbagai pengontrol?
Thuto Paul Gaotingwe
2
@JobertEnamno apakah aman untuk menyimpan nilai yang berasal dari WebSecurity.CurrentUserIdsehingga tidak menariknya dari database berkali-kali (menurut saya sangat mahal)?
Andrius Naruševičius
2
Tidak ada sesi pengontrol silang jadi ketika Anda meminta pengontrol lain, misalnya dari Account/LogOnke Home/Index, Session["FirstName"]adalah null. Pengembang harus membuat pengontrol induk ( BaseController) dan menentukan bidang yang dilindungi ( internal protected HttpSessionStateBase SharedSession) yang dapat mengekspos variabel Sesi bersama di semua sub pengontrol (ini mengasumsikan bahwa semua pengontrol aplikasi Anda mewarisi dari BaseController)
Bellash
63

Karena sifat web yang tidak memiliki kewarganegaraan, sesi juga merupakan cara yang sangat berguna untuk mempertahankan objek di seluruh permintaan dengan menserialisasinya dan menyimpannya dalam satu sesi.

Contoh penggunaan yang sempurna dari hal ini adalah jika Anda perlu mengakses informasi reguler di seluruh aplikasi Anda, untuk menyimpan panggilan database tambahan pada setiap permintaan, data ini dapat disimpan dalam sebuah objek dan tidak diserialisasikan pada setiap permintaan, seperti:

Objek kami yang dapat digunakan kembali dan dapat diserialkan:

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

    public string EmailAddress { get; set; }

    public string FullName { get; set; }
}

Kasus penggunaan:

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 */
    }

}

Setelah objek ini telah diserialisasi, kita dapat menggunakannya di semua pengontrol tanpa perlu membuatnya atau meminta database untuk data yang ada di dalamnya lagi.

Suntikkan objek sesi Anda menggunakan Injeksi Ketergantungan

Dalam dunia yang ideal Anda akan ' memprogram ke antarmuka, bukan implementasi ' dan menyuntikkan objek sesi yang dapat diserialkan ke pengontrol Anda menggunakan wadah Inversion of Control pilihan Anda, seperti itu (contoh ini menggunakan StructureMap karena itu yang paling saya kenal ).

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

Anda kemudian akan mendaftarkan ini di Global.asax.csfile Anda .

Bagi mereka yang tidak terbiasa dengan menyuntikkan objek sesi, Anda dapat menemukan entri blog yang lebih mendalam tentang subjek di sini .

Sebuah kata peringatan:

Perlu dicatat bahwa sesi harus diminimalkan, sesi besar dapat mulai menyebabkan masalah kinerja.

Juga disarankan untuk tidak menyimpan data sensitif apa pun di dalamnya (kata sandi, dll).

Joseph Woodward
sumber
Di mana Anda akan meletakkan definisi kelas? Saya masih cukup baru dalam segala hal, tetapi saya hanya ingin tahu tentang bagaimana pengontrol lain akan melihat kelas dan tahu apa itu. Apakah Anda hanya menambahkannya ke bagian atas pengontrol? Saya berpikir tentang SessionStart di global.asax saya akan menginisialisasi sesuatu tapi mungkin itu bukan cara terbaik untuk melakukannya.
Shaun314
@ Shaun314 Idealnya Anda akan menggunakan wadah IoC untuk menyuntikkan objek ke pengontrol Anda melalui injeksi ketergantungan (lihat sunting).
Joseph Woodward
1
Saya menyimpan beberapa informasi sesi setelah masuk pengguna menggunakan Identity 2. Saya tidak dapat mengambil informasi tersebut dalam tindakan dan pengontrol lain selain tindakan pertama yang saya arahkan pengguna ke. Ada ide?
Akbari
17

Ini adalah bagaimana status sesi bekerja di ASP.NET dan ASP.NET MVC:

Ikhtisar Status Sesi ASP.NET

Pada dasarnya, Anda melakukan ini untuk menyimpan nilai di objek Session:

Session["FirstName"] = FirstNameTextBox.Text;

Untuk mengambil nilai:

var firstName = Session["FirstName"];
Leniel Maccaferri
sumber
10
Tidak ada sesi pengontrol silang jadi ketika Anda meminta pengontrol lain, misalnya dari Accountke Home, Sesi ["NamaDepan"] adalah null. Pengembang harus membuat BaseControllerdan menentukan bidang terlindungi ( internal protected HttpSessionStateBase SharedSession) yang dapat mengekspos Sessionvariabel bersama di semua sub pengontrol (ini mengasumsikan bahwa semua pengontrol aplikasi Anda mewarisi dari BaseController)
Bellash
4
Umm, yakin ada? Ada variabel Sesi di Pengontrol (pengontrol dasar yang disediakan oleh MVC).
aeliusd
7
@ Bellash ini sepenuhnya salah. Sesi tersedia di seluruh pengontrol. Saya baru saja menyetel Sesi ["test"] di HomeController lalu membacanya di AccountController saya.
niico
0

Anda dapat menyimpan semua jenis data dalam satu sesi menggunakan:

Session["VariableName"]=value;

Variabel ini akan bertahan sekitar 20 menit.

Kegunaan
sumber
-8

U dapat menyimpan nilai apa pun dalam sesi seperti Sesi ["FirstName"] = FirstNameTextBox.Text; tetapi saya akan menyarankan u untuk mengambil bidang statis dalam model menetapkan nilai untuk itu dan u dapat mengakses nilai bidang itu di mana saja dalam aplikasi. Kamu tidak butuh sesi. sesi harus dihindari.

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

pada pengontrol - Employee.FullName = "ABC"; Sekarang Anda dapat mengakses Nama lengkap ini di mana saja dalam aplikasi.

Mukul Sharma
sumber
10
Menyimpan data di bidang statis, terutama data pengguna seperti Nama karyawan akan menyebabkan masalah parah di lingkungan multi-pengguna. Ketika dua pengguna yang berbeda masuk ke sistem, mereka akan melihat Employee.EmailAddress yang sama karena bidang statis pada Employee sama untuk setiap instance.
Gökçer Gökdal