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
다니엘 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
감사합니다 Jobert! 나에게 아이디어를 주었다! 그래도 궁금합니다 .. 로그인하는 동안 세션에 사용자 변수를 추가 할 수 있습니까? 또한 내 애플리케이션의 여러 컨트롤러에서 세션 변수 (한 번만 생성됨)에 액세스 할 수 있습니까?
Thuto Paul Gaotingwe 2013 년

31
세션에 모든 유형의 데이터를 저장할 수 있습니다. 일단 생성되면 모든 뷰와 컨트롤러에서 저장된 값에 액세스 할 수 있습니다. 생성 된 세션은 사용자 및 브라우저별로 만 액세스 할 수 있습니다. 즉, Firefox를 사용하여 User1이 만든 세션은 IE를 사용하는 동일한 사용자가 액세스 할 수 없습니다. 세션과 같이하지 말아야 할 것도 있습니다. 대용량 데이터를 저장하지 마십시오. 이로 인해 서버 성능이 저하 될 수 있습니다. 마지막으로 이러한 비밀번호 나 신용 카드 번호와 같은 세션에 민감한 데이터를 저장하지 마십시오
Jobert Enamno

2
다시 한 번 감사드립니다! 다른 컨트롤러에서 액세스 할 수 있도록 어디에서 만들어야합니까?
Thuto Paul Gaotingwe 2013 년

2
@JobertEnamno는 WebSecurity.CurrentUserId데이터베이스에서 여러 번 가져 오지 않도록 값을 저장하는 것이 안전 합니까 (매우 비용이 많이 든다는 것을 알았습니다)?
Andrius Naruševičius 2014

2
교차 컨트롤러 세션이 없으므로 다른 컨트롤러를 요청할 때 (예 : from Account/LogOnto Home/Index) Session["FirstName"]null입니다. 개발자는 부모 컨트롤러 ( BaseController) 를 만들고 internal protected HttpSessionStateBase SharedSession모든 하위 컨트롤러에서 공유 세션 변수를 노출 할 수 있는 보호 된 필드 ( )를 정의해야합니다 ( 이는 모든 앱 컨트롤러가에서 상속한다고 가정 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 */
    }

}

이 개체가 직렬화되면 개체를 만들거나 데이터베이스에 포함 된 데이터를 다시 쿼리 할 필요없이 모든 컨트롤러에서 사용할 수 있습니다.

종속성 주입을 사용하여 세션 개체 삽입

이상적인 세계에서는 ' 구현이 아닌 인터페이스에 프로그래밍 '하고 선택한 Inversion of Control 컨테이너를 사용하여 직렬화 가능한 세션 개체를 컨트롤러에 삽입합니다 (이 예제에서는 내가 가장 잘 알고있는 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파일에 등록 합니다.

세션 객체 삽입에 익숙하지 않은 사용자는 여기 에서 주제에 대한보다 심층적 인 블로그 게시물을 찾을 수 있습니다 .

경고의 말씀 :

세션을 최소로 유지해야하며 대규모 세션이 성능 문제를 일으킬 수 있다는 점은 주목할 가치가 있습니다.

또한 민감한 데이터 (암호 등)를 저장하지 않는 것이 좋습니다.


그래도 클래스 정의를 어디에 두겠습니까? 나는 여전히 모든 것에 익숙하지 않지만 다른 컨트롤러가 클래스를 어떻게보고 그것이 무엇인지 알 수 있는지 궁금합니다. 컨트롤러 상단에 추가 하시겠습니까? 나는 global.asax에서 SessionStart에 대해 생각하고 있었지만 초기화하는 것이 최선의 방법이 아닐 수도 있습니다.
Shaun314

@ Shaun314 이상적으로는 IoC 컨테이너를 사용하여 종속성 주입을 통해 컨트롤러에 개체를 주입하는 것이 좋습니다 (편집 참조).
Joseph Woodward

1
ID 2를 사용하여 사용자 로그인 후 일부 세션 정보를 저장하고 있습니다. 사용자를 리디렉션하는 첫 번째 작업이 아닌 다른 작업 및 컨트롤러에서 해당 정보를 검색 할 수 없습니다. 어떤 생각?
악바리

17

다음은 ASP.NET 및 ASP.NET MVC에서 세션 상태가 작동하는 방식입니다.

ASP.NET 세션 상태 개요

기본적으로 세션 개체에 값을 저장하려면 다음을 수행합니다.

Session["FirstName"] = FirstNameTextBox.Text;

값을 검색하려면 :

var firstName = Session["FirstName"];

10
교차 컨트롤러 세션이 없으므로 다른 컨트롤러를 요청할 때 (예 : from Accountto Home) Session [ "FirstName"]은 null입니다. 개발자는 BaseController보호 된 필드 를 만들고 정의해야합니다 (internal protected HttpSessionStateBase SharedSessionSession 모든 하위 컨트롤러에서 공유 변수를 노출 할 수 ) 이는 모든 앱 컨트롤러가에서 상속한다고 가정 BaseController)
Bellash

4
음, 확실합니까? Controller (MVC에서 제공하는 기본 컨트롤러)에 세션 변수가 있습니다.
aeliusd

7
@Bellash 이것은 완전히 잘못되었습니다. 세션은 컨트롤러에서 사용할 수 있습니다. HomeController에서 Session [ "test"]를 설정 한 다음 AccountController에서 읽습니다.
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의 정적 필드가 각 인스턴스에 대해 동일하기 때문에 동일한 Employee.EmailAddress가 표시됩니다.
Gökçer Gökdal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.