2016-08-13 4 views
1

저는 Visual Studio 웹 사이트 프로젝트에서 비롯된 이전 사이트에서 작업 중이며 다른 작업 외에도 웹 응용 프로그램으로 변환 중입니다. 사이트의 한 페이지는 GridView를 사용하고 DataTable을 사용하여 코드 숨김으로 DataSource를 설정합니다. GridView는 몇 개의 BoundField와 그 안에 확인란이있는 하나의 TemplateField를 노출합니다. GridView는 EnableViewState를 사용하도록 구성됩니다.asp.net GridView는 ViewState를 사용할 수 있습니까?

<asp:GridView ID="Results" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" EnableViewState="true"> 
    <AlternatingRowStyle BackColor="White" ForeColor="#284775" /> 
    <Columns> 
     <asp:BoundField DataField="Type" HeaderText="Type"/> 
     <asp:BoundField DataField="ProcessDate" HeaderText="Process Date" /> 
     <asp:BoundField DataField="Classification" HeaderText="Classification" /> 
     <asp:BoundField DataField="Email" HeaderText="Email" /> 
     <asp:TemplateField HeaderText="Notify?" ItemStyle-HorizontalAlign="Center"> 
      <EditItemTemplate> 
       <asp:CheckBox ID="CheckBox1" runat="server" onclick="EnableSubmit(this);" /> 
      </EditItemTemplate> 
      <ItemTemplate> 
       <asp:CheckBox ID="CheckBox1" runat="server" onclick="EnableSubmit(this);" /> 
      </ItemTemplate> 
     </asp:TemplateField> 
    </Columns> 
</asp:GridView> 

이 페이지는 또한 제출 버튼을 가지고 있으며, _CLICK 핸들러에서, 코드는 Results.Rows를 잡기 위해 시도한 다음 행이 체크 박스를 체크 한 결정하기 위해 주변에 판다. 검사 된 행을 기반으로 후속 처리를 수행합니다.

  • 이전 사이트 코드는 IsPostBack 검사를 수행하고 false 일 때만 DataBind를 호출합니다.
  • 이 페이지는 EnableViewState 또는 ViewStateMode를 정의하지 않습니다. 즉, MSDN에 따르면이 둘은 모두 기본값으로 true입니다.
  • 마스터 페이지 또는 기타 항목에 DataBind를 호출 할 필요가 없습니다.
  • 이전 사이트 코드는 ViewState 사전에 지속되는 수동 작업을 수행하지 않습니다.
  • 놀랍게도이 사이트의 제작 버전이 실제로 작동합니다.

나는이 작업을 수행해 왔기 때문에 GridView에서 ViewState를 실제로 사용하지 않는 방법과 사용자에게 보낸 데이터를 사용하는 방법, DataTable을 DataSource는 Code Behind 등에서 ViewState에 수동으로 삽입해야합니다.

내가 작업하고있는 사이트의 버전이 웹 응용 프로그램 프로젝트로 변환되었으며 .NET 4.5를 대상으로합니다. 사이트를 디버그하여 Page_Load 또는 Submit_Click에 도달하면 Results GridView에 null DataSource가 있고 Rows 속성의 수가 0입니다. 이것은 GridView가 "작동하는 방식"에 관한 현재의 일반적인 지혜와 일치하는 것으로 보입니다.

나는이 사이트의 기능에 대해 매우 까다로운 구현이며이를 수행하는 훨씬 더 좋은 방법이 있음을 잘 알고 있습니다. 그러나 내가 가장 염려하는 점은 이전 버전이 어떻게 작동하는지에 대한 설명을 찾을 수 없다는 것입니다.

GridView는 EnableViewState 속성을 무시하기 위해 히스토리의 특정 시점에서 변경 되었습니까? GridView에서 EnableViewState는 실제로 무엇을합니까? 웹 사이트와 웹 응용 프로그램 프로젝트의 차이점이 있습니까?

어떻게 이것이 가능합니까?

업데이트 : Bert Evans의 예제 페이지를 기반으로이 수정 된 페이지를 사용해 보았습니다.

<%@ Page Language="C#" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<script runat="server"> 
    public class Thing 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
    } 
    IEnumerable<Thing> Things 
    { 
     get 
     { 
      var things = new List<Thing>(); 
      things.Add(new Thing { ID = 1, Name = "One" }); 
      things.Add(new Thing { ID = 2, Name = "Two" }); 
      things.Add(new Thing { ID = 3, Name = "Three" }); 
      things.Add(new Thing { ID = 4, Name = "Four" }); 
      things.Add(new Thing { ID = 5, Name = "Five" }); 
      return things; 
     } 
    } 

    void Page_Load(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      ThingGridView.DataSource = Things; 
      ThingGridView.DataBind(); 
     } 

     pageLoadLabel.Text = string.Format("On page Load, row count: '{0}'", ThingGridView.Rows.Count); 
    } 

    void OnClickMe(object sender, EventArgs e) 
    { 
     onClickLabel.Text = string.Format("On click, row count: '{0}'", ThingGridView.Rows.Count); 
    } 

</script> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
     <asp:GridView runat="server" ID="ThingGridView"> 
      <Columns> 
       <asp:BoundField HeaderText="Name" DataField="Name" /> 
      </Columns> 
     </asp:GridView> 
    </div> 
     <asp:Button runat="server" ID="ThingButton" Text="Click Me!" OnClick="OnClickMe" /> 
     <asp:Label runat="server" ID="onClickLabel" Text="[set on click]" /> 
     <asp:Label runat="server" ID="pageLoadLabel" Text="[set on page load]" /> 
    </form> 
</body> 
</html> 

유일한 차이점은 페이지 본문의 행 개수를 인쇄하는 라벨입니다. 이 페이지를 실행할 때. 첫 번째 Page_Load 호출은 행 수 5를 페이지에 인쇄합니다. 그러나 포스트 백에서는 페이지로드와 OnClick 메서드에서 행 수가 0입니다.

+0

페이지의 HTML 마크 업에서보기 상태를 살펴보십시오. enable viewstate를 켜고 끄고 차이점을 살펴보십시오. – mason

+0

제품 버전에서는 작동하지만 사용자 버전에서는 작동하지 않는다고 말씀 하시겠습니까? – Bert

+0

@BertEvans 예 - 어떻게 든 이전 버전은 포스트 백 처리 중에 GridView의 Rows 속성에서 데이터를 가져 오는 작업을 관리하고 있으며 일부 SQL 액세스를 데이터 영역으로 조각하는 것을 제외하고 변경 한 내용은 모두 프로젝트를 업그레이드하고 있습니다. 웹 응용 프로그램 (그리고 아마도 더 새로운 .NET 버전 사용). – bwerks

답변

1

Bert Evans와 그의 예제 페이지 덕분에 결국 문제가 격리되었습니다. 이 버그는 실제로 Unity DI를 ASP.NET과 통합하는 UnityHttpModule의 현저하게 나쁜 MSDN 코드 예제에 있습니다. UnityHttpModule은 https://msdn.microsoft.com/en-us/library/ff664534(v=pandp.50).aspx에 자세히 설명되어 있습니다.

나열된대로 실제로 컴파일하지 않는 것 외에도 클래스는 ViewComplete 이벤트에 DI 코드를 연결합니다.이 이벤트는 ViewState가로드되기 전에 발생합니다 (ASP.NET 4.0 GridView OnRowEditing events not firing when using Unity 2.0 http module). 필자의 경우 PreLoad에서 DI 코드를 실행하면 문제가 해결되었습니다.

마지막으로, 완성을 위해 MSDN Unity DI HttpModule에 문제가있는 다른 사용자를 위해 다른 SO 스레드도 ASP.NET Dependency Injection HTTP Module (MS Enterprise Library)을 제공합니다.

1

데이터 바인딩은 컨트롤의 지정된 데이터 소스를 페이지에 렌더링되는 컨트롤 트리로 변환하는 프로세스입니다.GridView s의 경우 기본적으로 DataSource 속성을 설정하고 DataBind 메서드를 호출하면 DataSet 또는 DataTable과 같은 다른 소스에서 추출한 IEnumerable 또는 IEnumerable을 데이터가 포함 된 컨트롤이있는 HTML 테이블로 변환합니다.

테이블 셀에 렌더링 컨트롤의 각

은 유지하고 그것의, ViewState 자신의 페이지가 서버에 다시 게시 될 때 GridView는 제어 구조를 재 구축하고, ViewState의 데이터와 컨트롤을 채 웁니다 (또는 오히려 있도록 , 페이지가 제어 구조의 재구성을 시작하고 GridView이 방금 참여합니다.

DataSource은 렌더링 된 컨트롤의 상태 인 ViewState에 저장되지 않습니다.

GridView에서 ViewState을 사용 중지하면 페이지의 특정 요소를 저장하지 못하게되어 페이지 매김 및 정렬과 같은 작업을 수행 할 수 없습니다. 또한 GridView에서 ViewState을 사용하지 않도록 설정하고 페이지 다시 렌더링을 수행하면 (서버에 다시 페이지를 전송하는 클라이언트 쪽에서 이벤트가 발생 함) GridView은 페이지가 다시 렌더링 될 때 아무 것도 표시하지 않습니다. 왜냐하면 EnableViewState 상속되며 자식 컨트롤이 자신의 상태를 저장할 수 없습니다. GridView을 사용할 수 없도록 설정하고 ViewState 게시물을 게시 한 후에 다시 데이터를 표시하려면 데이터가 포함 된 데이터 소스로 DataBind을 다시 바인딩하거나 하위 컨트롤에 수동으로 ViewState을 사용하도록 설정해야합니다. GridView 안에는 ViewState이 있습니다. 작업중인 페이지의 DataBind!IsPostback으로 보호되어 있으므로 페이지의 초기로드에만 바인딩됩니다.

이 한 번에 DataSource을 저장하는 것과 같이 변경되는 것을 모르는 경우, 이것이 항상 효과가 있다고 생각합니다.

+0

궁극적으로 MSDN에서 Microsoft의 UnityHttpModule 코드가 문제가되었지만 도움을 주셔서 감사드립니다. 나는 그것없이 이것을 알아 내지 못했을 것이다. – bwerks

+0

@bwerks 당신이 알아 낸 것을 기쁘게 생각합니다. 내 샘플 페이지 수정 내용을 제 상자에 복사 했으므로 예상대로 작동 했으므로 앞으로 어떻게 도움을 줘야했는지 알 수 없었습니다. 좋은 발견! – Bert