ASP.NET MVC'de oturum değişkenleri


169

Bir kullanıcının belirli isteklerde bulunarak web sitesinde birden çok web sayfasına göz atmasına izin verecek bir web uygulaması yazıyorum. Kullanıcı tarafından girilen tüm bilgiler oluşturduğum bir nesnede saklanır. Sorun, bu nesnenin web sitesinin herhangi bir kısmından erişilmesi gerekiyor ve bunu başarmanın en iyi yolunu gerçekten bilmiyorum. Bir çözüm oturum değişkenleri kullanmak olduğunu biliyorum ama asp .net MVC bunları nasıl kullanılacağını bilmiyorum. Ve bir oturum değişkeni nerede bildirebilirim? Başka yolu var mı?


3
Web Sitesi ve Web Uygulaması kavramlarını karıştırıyorsunuz ... bunlar aynı şey değil.
adripanico

1
Bir veritabanına ihtiyaç var gibi görünüyor
Coops

Yanıtlar:


123

Bir şeyin gerçekten bir oturum durumuna ait olup olmadığını düşünmek isteyeceğinizi düşünürüm. Bu kendimi arada bir yaptığım bir şey ve her şeye güzel bir şekilde yazılmış güzel bir yaklaşım ama oturum bağlamına bir şeyler koyarken dikkatli olmalısınız. Sadece bir kullanıcıya ait olduğu için her şey orada olmamalı.

global.asax içinde OnSessionStart olayını bağlayın

void OnSessionStart(...)
{
    HttpContext.Current.Session.Add("__MySessionObject", new MySessionObject());
}

HttpContext.Current property! = Null kodunun herhangi bir yerinden bu nesneyi kaldırabilirsiniz. Bunu bir uzatma yöntemi ile yapıyorum.

public static MySessionObject GetMySessionObject(this HttpContext current)
{
    return current != null ? (MySessionObject)current.Session["__MySessionObject"] : null;
}

Bu şekilde kod yazabilirsiniz

void OnLoad(...)
{
    var sessionObj = HttpContext.Current.GetMySessionObject();
    // do something with 'sessionObj'
}

32
ASP MVC kullanılıyorsa, o zaman HttpContext.Current.Session gerçek Session nesnesini kullanmak değil, ancak System.Web.Abstractions.dll yeni HttpSessionStateWrapper & HttpSessionStateBase kullanmak daha sonra Session almak için bir Factory veya DI kullanmak tercih edilir.
Paul

6
Oturum değişkenine nasıl bir şey atarsınız? (sadece erişmenin aksine)
raklos

31
"OnSessionStart" etkinliğinin ne olduğunu ve nasıl "kancaladığınızı" anlamaya çalışan insanlar için bkz. Stackoverflow.com/questions/1531125/…
Cephron

5
@Paul Bir örnek verebilir misiniz? HttpSessionStateWrapper kullanarak herhangi bir örnek bulamıyorum.
Joseph Woodward

4
@AjayKelkar Bu yorum iş parçacığı, "ASP MVC kullanılıyorsa, o zaman HttpContext.Current.Session gerçek Session nesnesini kullanmamanız, ancak yeni HttpSessionStateWrapper & HttpSessionStateBase'i kullanmanız, ancak yanıtlarınızın daha iyi olmadığını önermesi tercih edilir
Coops

48

Buradaki cevap doğrudur, ancak bunu bir ASP.NET MVC 3 uygulamasında uygulamak için mücadele ettim. Denetleyicide bir Oturum nesnesine erişmek istedim ve neden bir "Nesne hatasının bir örneğine ayarlanmayan örnek" almaya devam ettiğimi anlayamadım. Ne farkettim ki, aşağıdakileri yaparak oturuma erişmeye çalıştığımda bir denetleyicide, bu hatayı almaya devam ettim. Bunun nedeni, this.HttpContext öğesinin Controller nesnesinin bir parçası olmasıdır.

this.Session["blah"]
// or
this.HttpContext.Session["blah"]

Ancak, istediğim System.Web ad alanının bir parçası olan HttpContext'di, çünkü bu, yukarıdaki cevabın Global.asax.cs içinde kullanmasını önerdiği. Bu yüzden açıkça aşağıdakileri yapmak zorunda kaldım:

System.Web.HttpContext.Current.Session["blah"]

Bu bana yardımcı oldu, burada MO olmayan bir şey yaptım emin değilim, ama umarım birine yardımcı olur!


6
System.Web.HttpContext.Current.Session ["blah"] = değer
Tomasz Iniewicz

21

Yer hakkında "HTTPContext.Current.Session" görmekten hoşlanmadığım için, oturum değişkenlerine erişmek için tek bir desen kullanıyorum, size güçlü bir şekilde yazılan veri çantasına erişmenizi kolaylaştırıyor.

[Serializable]
public sealed class SessionSingleton
{
    #region Singleton

    private const string SESSION_SINGLETON_NAME = "Singleton_502E69E5-668B-E011-951F-00155DF26207";

    private SessionSingleton()
    {

    }

    public static SessionSingleton Current
    {
        get
        {
            if ( HttpContext.Current.Session[SESSION_SINGLETON_NAME] == null )
            {
                HttpContext.Current.Session[SESSION_SINGLETON_NAME] = new SessionSingleton();
            }

            return HttpContext.Current.Session[SESSION_SINGLETON_NAME] as SessionSingleton;
        }
    }

    #endregion

    public string SessionVariable { get; set; }
    public string SessionVariable2 { get; set; }

    // ...

verilerinize her yerden erişebilirsiniz:

SessionSingleton.Current.SessionVariable = "Hello, World!";

2
Yani bu sınıfın iki sorumluluğu vardır: tek bir örneği korumak ve değişkenleri saklamak ... Ben bir single'a sahip olmak için bir IOC kapsayıcısı kullanırdım.
Jowen

1
Zaten bir kurulum varsa, ben de muhtemelen tam teşekküllü bir enjekte edebilen oturum hizmeti yapmak istiyorum, ama tutarlılık muhtemelen en büyük avantajı, ben küçük özellikler kümesi webapps için bu kodu kullanmak için daha meyilli olurdu.
Dead.Rabit

14

Asp.net mvc kullanıyorsanız, oturuma erişmek için basit bir yol.

Bir Denetleyiciden:

{Controller}.ControllerContext.HttpContext.Session["{name}"]

Bir Görünümden:

<%=Session["{name}"] %>

Bu kesinlikle oturum değişkenlerinize erişmenin en iyi yolu değildir, ancak doğrudan bir yoldur. Bu yüzden dikkatli kullanın (tercihen hızlı prototipleme sırasında) ve uygun olduğunda bir Wrapper / Container ve OnSessionStart kullanın.

HTH


2
hm .. Hangisi en iyi yol? Denetleyiciden Oturumdan ViewState'e veri aktarmalıyım, değil mi?
RredCat

2
ve bu yöntemin daralmalarını açıklayabilir misiniz?
RredCat

1
Sanırım okuma / yazma yöntemlerine sahip olmak en iyisi. Eşzamanlılık / iş parçacığı kullanımına bağlı olarak, bir yarış koşulunu önlemek için bu okuma / yazma yöntemlerinde de kilitlere ihtiyacınız olabilir.
DeepSpace101

13

IMHO ..

  1. görünüm / kalıp sayfanızın içindeki bir Oturuma asla başvurmayın
  2. Oturum kullanımınızı en aza indirin. MVC, temelde sunucuya tek bir gezi için yaşayan bir Oturum olan TempData nesnesini sağlar.

# 1 ile ilgili olarak, Session nesnesinin temsil ettiği her şeye erişmek için bir özelliğe sahip güçlü yazılan bir Master View'e sahibim ... benim örneğimde stongly yazılan Master View genel olarak güçlü yazılan View Pages konusunda biraz esneklik sağlayan geneldir

ViewMasterPage<AdminViewModel>

AdminViewModel
{
    SomeImportantObjectThatWasInSession ImportantObject
}

AdminViewModel<TModel> : AdminViewModel where TModel : class
{
   TModel Content
}

ve sonra...

ViewPage<AdminViewModel<U>>

7

Her ne kadar asp.net mvc hakkında bilmiyorum, ama bu normal bir .net web sitesinde yapmamız gereken budur. Asp.net mvc için de çalışmalıdır.

YourSessionClass obj=Session["key"] as YourSessionClass;
if(obj==null){
obj=new YourSessionClass();
Session["key"]=obj;
}

Bunu kolay erişim için bir yöntem içine koyarsınız. HTH



7

Oturumlara erişme yolum, çeşitli alan adlarını ve türlerini kapsayan yardımcı bir sınıf yazmaktır. Umarım bu örnek yardımcı olur:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.SessionState;

namespace dmkp
{
    /// <summary>
    /// Encapsulates the session state
    /// </summary>
    public sealed class LoginInfo
    {
        private HttpSessionState _session;
        public LoginInfo(HttpSessionState session)
        {
            this._session = session;
        }

        public string Username
        {
            get { return (this._session["Username"] ?? string.Empty).ToString(); }
            set { this._session["Username"] = value; }
        }

        public string FullName
        {
            get { return (this._session["FullName"] ?? string.Empty).ToString(); }
            set { this._session["FullName"] = value; }
        }
        public int ID
        {
            get { return Convert.ToInt32((this._session["UID"] ?? -1)); }
            set { this._session["UID"] = value; }
        }

        public UserAccess AccessLevel
        {
            get { return (UserAccess)(this._session["AccessLevel"]); }
            set { this._session["AccessLevel"] = value; }
        }

    }
}

Cevabınızı seviyorum ... neler olup bittiğini daha ayrıntılı olarak açıklayabilir misiniz ... ve neden bu konudaki diğer cevaplara karşı daha iyi bir yaklaşımdır.
Chef_Code

6

Adamlardan harika yanıtlar ama sizi her zaman oturuma güvenmeye karşı uyarırdım. Bunu yapmak hızlı ve kolaydır ve elbette işe yarar, ancak tüm cicrums'larda harika olmaz.

Örneğin, barındırma hizmetinizin oturum kullanımına izin vermediği bir senaryoda çalışıyorsanız veya bir web çiftliğinde veya paylaşılan bir SharePoint uygulaması örneğinde bulunuyorsanız.

Farklı bir çözüm istiyorsanız , Castle Windsor gibi bir IOC Container'ı kullanabilirsiniz. , bir sarıcı olarak bir sağlayıcı sınıfı oluşturabilir ve ardından gereksinimlerinize bağlı olarak istek başına veya oturum yaşam tarzını kullanarak sınıfınızın bir örneğini tutabilirsiniz.

IOC, her seferinde aynı örneğin döndürülmesini sağlayacaktır.

Daha karmaşık evet, basit bir çözüme ihtiyacınız varsa sadece oturumu kullanın.

Aşağıda ilgi çekici olmayan bazı uygulama örnekleri verilmiştir.

Bu yöntemi kullanarak, aşağıdaki satırlarda bir sağlayıcı sınıfı oluşturabilirsiniz:

public class CustomClassProvider : ICustomClassProvider
{
    public CustomClassProvider(CustomClass customClass)
    { 
        CustomClass = customClass;
    }

    public string CustomClass { get; private set; }
}

Ve şöyle bir şey kaydedin:

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
            Component.For<ICustomClassProvider>().UsingFactoryMethod(
                () => new CustomClassProvider(new CustomClass())).LifestylePerWebRequest());
    }

4

ViewModelBase'i tüm modeller için temel sınıf olarak kullanabilirsiniz, bu sınıf oturumdan veri çekmeye özen gösterir

class ViewModelBase 
{
  public User CurrentUser 
  {
     get { return System.Web.HttpContext.Current.Session["user"] as User };
     set 
     {
        System.Web.HttpContext.Current.Session["user"]=value; 
     }
  }
}

Oturum verileriyle ilgilenmek için HttpContextBase üzerinde bir genişletme yöntemi yazabilirsiniz

T FromSession<T>(this HttpContextBase context ,string key,Action<T> getFromSource=null) 
{
    if(context.Session[key]!=null) 
    {
        return (T) context.Session[key];
    }
  else if(getFromSource!=null) 
  {
    var value = getFromSource();
   context.Session[key]=value; 
   return value; 
   }
  else 
  return null;
}

Denetleyicide aşağıdaki gibi kullanın

User userData = HttpContext.FromSession<User>("userdata",()=> { return user object from service/db  }); 

İkinci argüman isteğe bağlıdır, oturumda değer bulunmadığında o anahtar için dolgu oturumu verilerini kullanacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.