ASP.NET 1.0부터 지원되는 View State 기능 덕분에 컨트롤의 값이 계속 유지되는 편안함을 누리고 있다. 하지만 편안함 덕분에 View State에 값이 많이 저장되어 있는 경우는 페이지의 전체 성능이 떨어지고 문제가 생길 수 있다. GridView컨트롤과 같이 많은 량의 데이타를 가지고 다니는 컨트롤의 경우 필요가 없다면 View State를 꺼두고 사용할 수 있다.
<%@ Page EnableViewState="false" ...%> 로 셋팅하거나 각 컨트롤에서 셋팅할 수 있다. 그런데 이런 경우 꼭 필요한 상태 값이였는데 개발자가 임의로 View State를 false로 셋팅했다면 문제가 생길 수 있다. 이런 이유로 새롭게 ASP.NET 2.0에서 도입된 기능이 Control State이다. Control State는 개발자가 임의로 상태를 변경할 수 없다. ^^
MSDN에 있는 예제를 한번 생성해 보았다. Index라는 속성과 IndexInViewState라는 속성을 가진 웹 컨트롤을 생성해서 일반 웹폼페이지에서 한번 사용해 보는 예제이다.
먼저 Sample이란 이름을 주고 웹컨트롤 템플릿으로 선택해서 프로젝트를 새로 생성한다. 아래의 코드를 입력한다. 또는 복사~~
// IndexButton.cs
using System;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Samples.AspNet.CS.Controls
{
[
AspNetHostingPermission(SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal),
ToolboxData("<{0}:IndexButton runat=\"server\"> </{0}:IndexButton>")
]
public class IndexButton : Button
{
private int indexValue;
[
Bindable(true),
Category("Behavior"),
DefaultValue(0),
Description("The index stored in control state.")
]
public int Index
{
get
{
return indexValue;
}
set
{
indexValue = value;
}
}
[
Bindable(true),
Category("Behavior"),
DefaultValue(0),
Description("The index stored in view state.")
]
public int IndexInViewState
{
get
{
object obj = ViewState["IndexInViewState"];
return (obj == null) ? 0 : (int)obj;
}
set
{
ViewState["IndexInViewState"] = value;
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
protected override object SaveControlState()
{
// Invoke the base class's method and
// get the contribution to control state
// from the base class.
// If the indexValue field is not zero
// and the base class's control state is not null,
// use Pair as a convenient data structure
// to efficiently save
// (and restore in LoadControlState)
// the two-part control state
// and restore it in LoadControlState.
object obj = base.SaveControlState();
if (indexValue != 0)
{
if (obj != null)
{
return new Pair(obj, indexValue);
}
else
{
return (indexValue);
}
}
else
{
return obj;
}
}
protected override void LoadControlState(object state)
{
if (state != null)
{
Pair p = state as Pair;
if (p != null)
{
base.LoadControlState(p.First);
indexValue = (int)p.Second;
}
else
{
if (state is int)
{
indexValue = (int)state;
}
else
{
base.LoadControlState(state);
}
}
}
}
}
}
일반 웹페이지에서 사용하려면 등록을 해야 한다. 일반 웹 프로젝트에서 도구상자에 Sample.dll을 찾아서 등록하면 사용할 수 있다.
<%@ Page Language="C#" AutoEventWireup="true" EnableViewState="false" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="Sample" Namespace="Samples.AspNet.CS.Controls" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<script language="xxjavascript">
function Click()
{
alert('버튼 클릭 클라이언트');
}
</script>
<title>제목 없음</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<cc1:IndexButton ID="IndexButton1" runat="server" EnableViewState="false" [안내]태그제한으로등록되지않습니다-xxOnClick="IndexButton1_Click" Text="첫번째 버튼" /><br />
<br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="xxjavascript:Click()" /> <br />
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label></div>
</form>
</body>
</html>
클래스 파일의 코드는 아래와 같다.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = (IndexButton1.Index++).ToString();
Label2.Text = (IndexButton1.IndexInViewState++).ToString();
}
protected void IndexButton1_Click(object sender, EventArgs e)
{
Response.Write("새로 만든 버튼");
}
}
![](https://img1.daumcdn.net/relay/cafe/original/?fname=http%3A%2F%2Fblog.dreamwiz.com%2Fusr%2Fp%2Fa%2Fpapasmf1%2F3%2Fpapasmf1_20070727154429_6056656_1.bmp)
두개의 프로젝트로 구성되어 있따. Sample이 컨트롤 프로젝트이고 WebSite5가 ASP.NET 웹사이트이다.
![](https://img1.daumcdn.net/relay/cafe/original/?fname=http%3A%2F%2Fblog.dreamwiz.com%2Fusr%2Fp%2Fa%2Fpapasmf1%2F3%2Fpapasmf1_20070727154429_6056656_2.bmp)
내부적으로 ViewState에 값을 저장했던 IndexInViewState속성은 값이 증가되지 않고(페이지의 EnableViewState='false'로 셋팅했기 때문에...) ControlState를 사용하는 Index속성의 값만 계속 증가하는 것을 확인할 수 있다. 실무에서 크게 사용할 일은 없지만 이런 것도 추가되었다는 정도로 알아두면 좋을 것 같다.
버튼의 경우 OnClientClick이라는 속성이 새로 추가되서 필요한 자바스크립트 함수를 바로 연결할 수 있다. 같이 테스트한 코드로 넣어 두었다.