کار با Session در ASP.NET Core

یکشنبه 15 مرداد 1396

در این مقاله، مفاهیم اولیه و نحوه کار با Session در ASP.NET Core به صورت یک آموزش گام به گام و عملی آموزش داده می شود. همچنین متد های مربوط به Session به طول کام توضیح داده خواهد شد.

کار با Session در ASP.NET Core

برنامه های کاربردی تحت وب روی پروتکل HTTP کار می کنند و پروتکل HTTP یک پروتکل stateless می باشد. هر درخواست HTTP به عنوان یک درخواست مستقل عمل می کند. سرور اطلاعی در مورد مقادیر متغیرها که در درخواست قبلی استفاده می شوند، ندارد.


session یک ویژگی در هسته ی ASP.net است که ما را در ذخیره کردن داده های کاربر توانا می کند. session داده ها را در دیکشنری بر روی سرور ذخیره می کند و SessionId به عنوان کلید استفاده می شود. SessionId در کوکی کاربر ذخیره می شود. کوکی مربوط به SessionId با هر درخواستی ارسال می شود. کوکی SessionId در هر مرورگری به صورت جداگانه وجود دارد و نمی تواند بین مرورگرها به اشتراک گذاشته شود. هیچ timeout مشخصی برای کوکی SessionId وجود ندارد و این کوکی ها زمانی حذف می شوند که Session به پایان زمانش رسیده باشد. هر session برای مدت زمان محدودی می تواند در سرور بماند، مقدار پیشفرض برای session ها، 20 دقیقه است که البته این مقدار قابل تغییر است.

Session ها دارای دو نوع هستند که دسته اول با نام In-Proc یا In-memory و دسته دوم با نام Out-Proc یا Distributed session شناخته می شوند. اگر session ما از نوع in-memory و برنامه ما در محیط Web-Farm میزبانی شود، ما باید از sticky sessions استفاده کنیم تا بتوانیم هر Session را به یک سرور اختصاص دهیم. در حالیکه Out-Proc session نیازی به sticky sessions ندارد و این روش، روش محبوب و پراستفاده تری برای استفاده ازsession  در برنامه است.

پیکربندی session

پکیج Microsoft.AspNetCore.Session یک میان افزار برای مدیریت session ها در ASP.NET Core است. برای استفاده از session در برنامه، ما نیاز داریم که پکیج نام برده شده را در بخش dependency در داخل فایل project.json اضافه نماییم.

Project.json

    {  
      "version": "1.0.0-*",  
      "buildOptions": {  
        "debugType": "portable",  
        "emitEntryPoint": true  
      },  
      "dependencies": {},  
      "frameworks": {  
        "netcoreapp1.0": {  
          "dependencies": {  
            "Microsoft.NETCore.App": {  
              "type": "platform",  
              "version": "1.0.1"  
            },  
            "Microsoft.AspNetCore.Mvc": "1.0.1",  
            "Microsoft.AspNetCore.Server.Kestrel": "1.0.1",  
            "Microsoft.AspNetCore.Routing": "1.0.1",  
            "Microsoft.AspNetCore.Session" : "1.0.1"  
          },  
          "imports": "dnxcore50"  
        }  
      }  
    }  

مرحله بعدی، پیکربندی session در کلاس Startup است. ما نیاز داریم که متد AddSession را در داخل متد ConfigureServices که در داخل کلاس startup است، فراخوانی کنیم. متد AddSession دارای یک overload است که تنظیمات مختلفی از session مانند Idle Timeout، نام کوکی، دامنه کوکی و .... را قبول می کند. اگر ما مقادیر تنظیمات session را مشخص نکنیم، سیستم از تنظیمات پیشفرض استفاده می کند. اکنون ما باید متد UseSession را در متد Configure که در داخل کلاس startup است فراخوانی نماییم. این متد، session را در برنامه فعال می نماید.

Startup.cs

    using System;  
    using Microsoft.AspNetCore.Builder;  
    using Microsoft.AspNetCore.Hosting;  
    using Microsoft.AspNetCore.Http;  
    using Microsoft.Extensions.DependencyInjection;  
      
    namespace WebApplication {  
        public class Startup {  
            public void Configure(IApplicationBuilder app)  
            {  
                app.UseSession();  
                app.UseMvc();  
                app.Run(context => {  
                    return context.Response.WriteAsync("Hello Readers!");  
                });  
            }  
      
            public void ConfigureServices(IServiceCollection services)  
            {  
                services.AddMvc();  
                services.AddSession(options => {   
                    options.IdleTimeout = TimeSpan.FromMinutes(30);   
                });  
            }       
        }  
    }  

در داخل متد Configure که در کلاس startup وجود دارد، باید متد UseSession را حتما قبل از متد UseMvc فراخوانی نماییم. اگر فراخوانی متد UseMvc قبل از متد UseSession باشد، برنامه هنگام اجرا، دچار خطا می شود.

نحوه دسترسی به session

پس از اتمام مراحل نصب و پیکربندی، ما می توانیم به کمک HttpContext از session استفاده کنیم. برای استفاده از session در داخل کنترلر، ما باید مرجع Microsoft.AspNet.Http را به کنترلر اضافه کنیم. سه متد وجود دارد که ما را قادر می سازد تا مقادیر مورد نظر را در session ذخیره کنیم. متدهای SetInt32 و SetString ، از نوع extension متدها هستند که در این متد ها آرایه ایی از نوع byte به نوع های int و string تبدیل می شود. به طور مشابه، سه متد هم برای دریافت اطلاعات از session وجود دارد. نام این متدها GetInt32، GetString و Get است که متد Get آرایه هایی از نوع بایت را به عنوان خروجی بر می گرداند.

دلیل اصلی برای ذخیره داده ها به صورت آرایه ایی از بایت ها، این است که اطمینان پیدا کنیم که داده ها به صورت serializable در داخل سرور نگه داری می شوند. به جز مقادیر int و string، ما نیاز داریم که مقادیر را به صورت آرایه ایی از بایت که serialize شده باشد، در session نگه داری کنیم.

مثال

در مثالی که در پایین آمده است، ما یک رشته را در داخل session قرار داده ایم و این مقدار را در درخواست بعدی دریافت کرده ایم.

   using Microsoft.AspNetCore.Http;  
    using Microsoft.AspNetCore.Mvc;  
      
    public class HomeController : Controller
    {

        [Route("home/index")]
        public IActionResult Index()
        {
            HttpContext.Session.SetString("name", "آموزش کار باSession ");
            return View();
        }
        [Route("home/GetSessionData")]
        public IActionResult GetSessionData()
        {
            ViewBag.data = HttpContext.Session.GetString("name"); ;
            return View();
        }
    }

خروجی

ساخت Extension متد سفارشی برای session

همانطور که در بالاتر گفته شده بود، دو extension متد برای ارسال و دریافت داده از session وجود دارد. نام این متدها GetInt32 و GetString ، SetInt32 و SetString است. ما نیز می توانیم برای استفاده های خودمان یک Extension متد سفارشی بسازیم تا بتوانیم مقادیر مورد نظرمان را به session بفرستیم یا از session دریافت نماییم.

using System;  
using Microsoft.AspNetCore.Http;  
public static class SessionExtensions  
{  
    public static double? GetDouble(this ISession session, string key)  
    {  
        var data = session.Get(key);  
        if (data == null)  
        {  
            return null;  
        }  
        return BitConverter.ToDouble(data, 0);  
    }   
  
    public static void SetDouble(this ISession session, string key, double value)  
    {  
        session.Set(key, BitConverter.GetBytes(value));  
    }  
} 

نحوه کار با Extension متد

 using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    public class HomeController : Controller
    {
        [Route("home/index")]
        public IActionResult Index()
        {
            HttpContext.Session.SetString("name", "آموزش کار با ");
            HttpContext.Session.SetDouble("Percentage", 75.56);
            return View();
        }
        [Route("home/GetSessionData")]
        public IActionResult GetSessionData()
        {
            ViewBag.data = HttpContext.Session.GetString("name");
            ViewBag.Percent = HttpContext.Session.GetDouble("Percentage");
            return View();
        }
    }

خروجی

ذخیره داده های پیچیده در session

همانطور که می دانیم، session توانایی ذخیره فقط یک بایت از آرایه را دارد. در مقایسه با ورژن قبلی، ASP.NET Core هیچ گونه عملیاتی مانند serialization یا  de-serializationرا برای ذخیره داده در session انجام نمی دهد. در اینجا ما می خواهیم یک شی پیچیده را به json تبدیل کنیم و سپس آن را به صورت string ذخیره نماییم. بعدا برای استفاده از این مقدار، آن را به صورت string دریافت می نماییم و به json تبدیل می کنیم.

بدین ترتیب، ما یک extension  متد برای ارسال و دریافت شی های پیچیده در session نوشته ایم.

    using System;  
    using Microsoft.AspNetCore.Http;  
    using Newtonsoft.Json;  
      
    public static class SessionExtensions  
    {  
        public static T GetComplexData<T>(this ISession session, string key)  
        {  
            var data = session.GetString(key);  
            if (data == null)  
            {  
                return default(T);  
            }  
            return JsonConvert.DeserializeObject<T>(data);  
        }   
      
        public static void SetComplexData(this ISession session, string key, object value)  
        {  
            session.SetString(key, JsonConvert.SerializeObject(value));  
        }  
    }  

نحوه کار با Extension متد

در این مثال، ما یک کلاس کنار کنترلر ساخته ایم. در داخل اکشن متدی که در این کنترلر وجود دارد،یک نمونه از این کلاس می سازیم و سپس مقادیری را برای ذخیره شدن در session می فرستیم. در اکشن متد دیگری، این مقادیر ارسال شده به session را دریافت می کنیم و به کاربر نمایش می دهیم.

    public class User   
    {  
        public string Name { get; set; }  
        public double Percentage { get; set; }  
    }  

اکشن متد

    [Route("home/SetComplexData")]  
    public IActionResult SetComplexData()  
    {  
        User user = new User();  
        user.Name = "mr programer";  
        user.Percentage = 75.45;             
          
        HttpContext.Session.SetComplexData("UserData", user);  
        return View("index");  
    }  
    [Route("home/GetComplexData")]  
    public IActionResult GetComplexData()  
    {  
        ViewBag.data = HttpContext.Session.GetComplexData<User>("UserData");  
        return View();  
    }  

آموزش asp.net mvc

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید