programing

ASP.NET MVC의 세션 변수

new-time 2020. 5. 27. 22:55
반응형

ASP.NET MVC의 세션 변수


사용자가 특정 요청을하는 웹 사이트 내에서 여러 웹 페이지를 탐색 할 수있는 웹 응용 프로그램을 작성 중입니다. 사용자가 입력 한 모든 정보는 내가 만든 개체에 저장됩니다. 문제는 웹 사이트의 어느 부분에서 나이 객체에 액세스해야하며 이것을 달성하는 가장 좋은 방법을 모른다는 것입니다. 하나의 솔루션은 세션 변수를 사용하는 것이지만 ASP .net MVC에서 사용하는 방법을 모르겠습니다. 세션 변수는 어디에서 선언합니까? 다른 방법이 있습니까?


사물이 실제로 세션 상태에 속하는지 생각하고 싶을 것입니다. 이것은 내가 지금하고있는 일이며, 모든 것에 대한 강력하게 타이핑 된 접근 방식이지만 세션 컨텍스트에 넣을 때주의해야합니다. 일부 사용자의 것이기 때문에 모든 것이 있어야하는 것은 아닙니다.global.asax에서 OnSessionStart 이벤트 연결

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

HttpContext.Current 속성! = null 인 코드의 어느 곳에서나 해당 객체를 검색 할 수 있습니다. 확장 방법 으로이 작업을 수행합니다.

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

이렇게하면 코드에서 할 수 있습니다

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

대답은 정확하지만 ASP.NET MVC 3 앱에서 구현하는 데 어려움을 겪었습니다. 컨트롤러에서 Session 객체에 액세스하고 싶고 왜 "인스턴스가 객체 오류의 인스턴스로 설정되지 않았습니다"라는 메시지가 계속 나타나는지 알 수 없었습니다. 내가 알았던 것은 컨트롤러에서 다음을 수행하여 세션에 액세스하려고 할 때 해당 오류가 계속 발생한다는 것입니다. 이것은 this.HttpContext가 Controller 객체의 일부이기 때문입니다.

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

그러나 내가 원했던 것은 위의 답변이 Global.asax.cs에서 사용하도록 제안하기 때문에 System.Web 네임 스페이스의 일부인 HttpContext였습니다. 따라서 다음을 명시 적으로 수행해야했습니다.

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

이것은 내가 MO 주변에 있지 않은 것을했는지 확실하지 않지만 누군가에게 도움이되기를 바랍니다.


장소에 대해 "HTTPContext.Current.Session"을 보는 것을 싫어하기 때문에 단일 톤 패턴을 사용하여 세션 변수에 액세스하므로 강력하게 형식화 된 데이터 백에 쉽게 액세스 할 수 있습니다.

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

    // ...

어디서나 데이터에 액세스 할 수 있습니다.

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

asp.net mvc를 사용하는 경우 세션에 액세스하는 간단한 방법이 있습니다.컨트롤러에서 :

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

보기에서 :

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

이것이 세션 변수에 액세스하는 가장 좋은 방법은 아니지만 직접 경로입니다. 따라서 빠른 프로토 타입 제작시주의해서 사용하고, 적절 해지면 래퍼 / 컨테이너 및 OnSessionStart를 사용하십시오.HTH


이모 ..

  1. 뷰 / 마스터 페이지에서 세션을 참조하지 마십시오
  2. 세션 사용을 최소화하십시오. MVC는이를 위해 TempData obj를 제공하는데, 이는 기본적으로 서버로 단일 여행을하는 세션입니다.

With regards to #1, I have a strongly typed Master View which has a property to access whatever the Session object represents....in my instance the stongly typed Master View is generic which gives me some flexibility with regards to strongly typed View Pages

ViewMasterPage<AdminViewModel>

AdminViewModel
{
    SomeImportantObjectThatWasInSession ImportantObject
}

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

and then...

ViewPage<AdminViewModel<U>>


Although I don't know about asp.net mvc, but this is what we should do in a normal .net website. It should work for asp.net mvc also.

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

You would put this inside a method for easy access. HTH


There are 3 ways to do it.

  1. You can directly access HttpContext.Current.Session

  2. You can Mock HttpContextBase

  3. Create a extension method for HttpContextBase

I prefer 3rd way.This link is good reference.

Get/Set HttpContext Session Methods in BaseController vs Mocking HttpContextBase to create Get/Set methods


Great answers from the guys but I would caution you against always relying on the Session. It is quick and easy to do so, and of course would work but would not be great in all cicrumstances.

For example if you run into a scenario where your hosting doesn't allow session use, or if you are on a web farm, or in the example of a shared SharePoint application.

If you wanted a different solution you could look at using an IOC Container such as Castle Windsor, creating a provider class as a wrapper and then keeping one instance of your class using the per request or session lifestyle depending on your requirements.

The IOC would ensure that the same instance is returned each time.

More complicated yes, if you need a simple solution just use the session.

Here are some implementation examples below out of interest.

Using this method you could create a provider class along the lines of:

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

    public string CustomClass { get; private set; }
}

And register it something like:

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

My way of accessing sessions is to write a helper class which encapsulates the various field names and their types. I hope this example helps:

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

    }
}

You can use ViewModelBase as base class for all models , this class will take care of pulling data from session

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

You can write a extention method on HttpContextBase to deal with session data

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

Use this like below in controller

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

The second argument is optional it will be used fill session data for that key when value is not present in session.

참고URL : https://stackoverflow.com/questions/560084/session-variables-in-asp-net-mvc

반응형