2013-02-14 1 views
12

컨텍스트 : 나는 종종 우리의 ASP.NET 페이지가의 GridView에 대한 사용자의 데이터를 표시해야하는 상황에있었습니다ASP.NET 포스트 백에 걸쳐 데이터 지속성

, 그는 기쁘게 그를 그것을 변경할 수 (셀의 텍스트 상자) 실제로 "저장 버튼"을 눌렀을 때만 데이터베이스에 저장하십시오. 이 데이터는 일반적으로 페이지에있는 정보의 가상 상태이므로 사용자가 "저장 버튼"을 누르기 전에는 실제로 저장하지 않고 모든 것을 변경할 수 있습니다. 이러한 경우 항상 ASP.NET 포스트 백에서 유지되어야하는 데이터 목록이 있습니다. 이 데이터는 DataTable 또는 일부 List<Someclass>의 인스턴스 일 수 있습니다.

나는 이것을 구현하고 데이터를 Session에 유지하는 사람들을 종종 봅니다. 그런 경우에는 여러 페이지를 열어 탐색하는 사용자가있을 때 같은 페이지에서 몇 번이나 문제가 발생하는 경우가 종종 있습니다. 두 개의 서로 다른 탭의 데이터가 병합되어 정보가 뒤섞이는 문제가 발생합니다. 세션이 자주 사용되는 방법의

예 : 두 개의 탭이 이미로드 및 사용자 때 약

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack) 
    { 
     DataList = null 
    } 
    else 
    { 
     FillGridView(DataList); 
    } 
} 

그러나 :

private List<SomeClass> DataList 
{ 
    get 
    { 
     return Session["SomeKey"] as List<SomeClass>; 
    } 
    set 
    { 
     Session["SomeKey"] = value; 
    } 
} 

사람들은 종종 이런 일을 수행하여 그것을 해결하려고 GridView 값을 변경하고 어떤 이상한 이유로 다른 페이지의 저장 버튼을 눌러 데이터를 저장하려고합니까? 나는이 옵션을 개인적으로 싫어한다.

다른 방법은 데이터를 ViewState에 넣는 것입니다. 그러나 상당히 큰 목록을 유지하려면 페이지에 저장할 때 페이지에 크게 영향을 줄 수 있습니다 (HiddenField).

하지만 그 작업을 수행하는 가장 좋은 방법은 무엇입니까? 일단 SessionViewState과 함께 사용하는 것으로 생각하면 ViewStateSession 저장된 데이터의 색인을 생성하는 고유 식별자를 보유하게됩니다. 즉, 브라우저에 탭 사이의 데이터 공유를 방지 할 수 :

private List<SomeClass> DataList 
{ 
    get 
    { 
     if (ViewState["SomeKey"] == null) 
     { 
      ViewState["SomeKey"] = Guid.NewGuid().ToString(); 
     } 

     return Session[ViewState["SomeKey"].ToString()] as List<SomeClass>; 
    } 
    set { 

     if (ViewState["SomeKey"] == null) 
     { 
      ViewState["SomeKey"] = Guid.NewGuid().ToString(); 
     } 

     Session[ViewState["SomeKey"].ToString()] = value; 
    } 
} 

을 다른 한편으로는 세션에 사용자가 페이지를 입력 할 때마다 새로운 데이터 목록을 저장합니다. 어떤 것이 서버 메모리에 영향을 미칩니 까? 어쩌면 그들은 어떤 식 으로든 지울 수 있습니다.

질문 :

서버 및 유지 보수 코딩 팀에 적은 비용으로, 포스트 백에 걸쳐 데이터의 종류를 지속 브라우저에 여러 탭의 상황을 고려하는 가장 좋은 방법이 될 것입니다 무엇

?

업데이트 :

으로 멋지게 게시 @nunespascal는, 하나의 옵션은 SessionPageStatePersister를 사용하여 Session에서 ViewState를 저장하는 것입니다. 그러나 불행히도 그것은 나의 경우에 대한 선택 사항이 아닙니다. 그러나 ViewState에 저장된 UniqueId에 의해 인덱싱 된 세션에 데이터를 저장하는 것은 마지막 예제와 크게 다르지 않습니다.

다른 옵션이 있습니까?

+0

두 번째 방법은 몇 가지 조정할 수 있습니다 : 1) ViewState 대신 숨겨진 필드를 사용하십시오. ViewState를 페이지에서 사용할 수있게되기 전에 액세스 할 수 있습니다 (때로는 유용함). 2) 한 번에 저장할 수있는 항목 수를 제한하고 가장 오래된 항목을 버리는 관리자와 세션을 감습니다. 물론 이것은 메모리 문제를 완전히 수정하지는 않지만 바쁜 사용자가 수백 개의 큰 객체/세트를 메모리에 가지고있을 염려없이 사용자가 응용 프로그램에서 유기적으로 작업하게하는 데 도움이 될 수 있습니다. –

답변

2

이 문제에 대한 간단한 해결책이 있습니다.ViewState를 세션에 저장합니다. 사용할 필요가 들어

SessionPageStatePersister

참조 : Page State Persister

당신이 PageStatePersister을 무시하고 대신 기본 HiddenFieldPageStatePersister

protected override PageStatePersister PageStatePersister 
{ 
    get 
    { 
     return new SessionPageStatePersister(this); 
    } 
} 

이을의 SessionPageStatePersister를 사용하도록하기 만하면됩니다 심지어 당신에게 고유 키 유지의 두통을 저장합니다. 숨겨진 필드는 페이지 인스턴스마다 고유 한 키를 자동으로 유지하는 데 사용됩니다.

+0

예, 분명히 해결할 것입니다. 불행히도 내 경우에는 옵션이 아니지만 빠른 답변을 주셔서 감사합니다. –

+0

내가 viewstate에 저장하고 세션에 viewstate를 저장하면, 내가 게시 한 마지막 예제와 어떻게 다릅니 까? 서버 메모리에 영향을 미치지 않거나 사용자가 페이지를 새로 고치고 결과적으로 매번 세션에 새 데이터를 저장하면 어떻게 관리 될까요? –

+0

예, 서버 메모리에 영향을 미칩니다. 하지만 세션에 직접 데이터를 저장하더라도 비용이 발생합니다. 반복되는 새로 고침의 경우 세션 공간을 늘릴 수 있습니다. 그러나 그러한 문제에 직면하면 세션을 통해 항상 데이터베이스로 이동할 수있는 옵션이 제공됩니다. 세션이 결국 제거됩니다. – nunespascal

0

비슷한 상황이 나타났습니다. 아이디어는 각 사용자가 그리드보기를 변경하는 데 긴 세션을 허용하는 경우 결국 데이터에 대한 최종 수정 사항 집합 하나만 수락하기 때문에 병행 성 문제가 있음을 의미합니다.

내 솔루션은 데이터베이스를 변경할 수 있지만 모든 사용자가 SignalR을 통해 동일한 상태를 볼 수 있도록하는 것이 었습니다.

이제는 동시성 문제가 사라졌지만 계속 변경해야합니다. 결국 변경 사항을 저장하지 않을 수도 있습니다. 이 문제를 명령 디자인 패턴을 적용하여 해결했습니다. 이제 모든 변경 사항 세트를 승인하거나 폐기 할 수 있습니다. 색인을 확인할 때마다 마지막으로 승인 된 gridview가 표시됩니다. 업데이트 페이지로 이동하면 라이브 업데이트 된 Gridview가 표시됩니다. 또한 오래된 승인 된 gridview - 명령어 디자인 패턴의 다른 장점 -을 보려면 수정본을 참조하십시오.