login register Sysop! about ME  
qrcode
    최초 작성일 :    2003년 10월 29일
  최종 수정일 :    2003년 10월 29일
  작성자 :    taeyo
  편집자 :    Taeyo (김 태영)
  읽음수 :    57,104

강좌 목록으로 돌아가기

필자의 잡담~

남아일언 중천금.... 이옵니다만.... ㅠ_ㅠ.. 그렇게 되었습니다. 죄송하다는 말씀밖에는...

대상 : ASP.NET을 이용하여 스스로 일반 게시판이 작성가능하거나,
         Taeyo's ASP.NET v1.0 서적을 통해서 게시판 만들기를 이미 공부하신 분

(슬그머니)자. 이제 Content.aspx 페이지의 나머지 부분들을 마저 채워보도록 하겠습니다.그러니깐, 이번 강좌에서 진행해야 할 것은 말입니다. 글의 [수정]과 [삭제]이지요 ^^. 그렇습니다. (옅은 미소를 띄우며) 그럼 이번 강좌에서는 저번 강좌에서 남긴 부분들을 하나씩 하나씩 마무리를 지어보도록 하겠습니다요...

(약간 뜸을 들이는 듯 하다가..)아참.. 그전에 개인적인 사담 하나 올리겠습니다. 요즘 제가 개인적으로 많은 분들을 만났는데요.. 그 분들 중 많은 분들이 제게 이런 말씀을 하시더군요..

"태오 사이트는 요즘 업데이트가 너무 늦는 것 같아. 정신 좀 차려야 하지 않겠어? 먹고 사는게 바빠??
 그리고, 강좌가 올라와도 언제나 초급적인 강좌만 올라오는 것 같아...
 이제는 태오 사이트도 중급적인 강좌가 좀 올라와야 하지 않나?
 설계적인 부분이나 컨설팅과 관계된 이야기들 말야.... 
 언제까지나 겉핧기 식의 내용만 다룰 수는 없지않아.... 뭔가 변화되는 모습을 보여줘야지... "

라고 말입니다. 지당하신 말씀입니다.... 해서, 한 말씀 드리면...  그러한 시도를 서서히 준비해 나가려고 합니다.(관중들 믿지 못하는 눈빛을 보낸다. 이 때, 필자 당황스러워 하며, 뭔가 변명거리를 찾는다. 말을 더듬거리며) 지.. 지.. 지금은 1100여 페이지나 되는 두꺼운 원서를 번역하고 있어서... 사.. 사..사실 힘이 많이 부치는 형편이라... 말한 것을 자주 못 지키고는 하지만요... 조만간.... 태오 사이트의 ASP.NET 버전을 비롯하여.. 많은 것들을 새롭게 시도하려 하오니.. 부디... 너무 실망하지 마시고... 지켜봐 주셨으면 합니다...  ^^ 감사합니다.(관중들 약간 믿는 듯한 분위기로 돌아선다)

(지긋히 눈끝을 올리며)그럼 이제 본격적으로 본래의 강좌 내용을 시작해 볼까요???

(친절하게)이번에 해야할 작업은 [EDIT]버튼과 [DELETE]버튼이 각각 클릭되었을 경우에, 실제로 각각 변경 페이지로의 이동하거나 삭제 처리를 수행하는 것입니다. 두 작업 모두... 비밀번호의 입력을 요구하는 것은 두말할 필요가 없구요 ^^;  두 작업 모두 비밀번호가 실제 글 작성시에 기입된 비밀번호와 일치하는지 여부를 검사해야 합니다. 그래서, 비밀번호가 일치하는 경우에만 [수정] 및 [삭제] 작업이 처리되도록 해야하겠지요. 아무나 마구 데이터를 수정하거나 삭제할 수 있어서는 안될테니까요..

(발음을 굴리며)물론, 썸바리(somebody)가 슬며시 어떤 비밀번호를 입력했을 때, 우연히 그 비밀번호가 원래의 비밀번호와 일치하여 그 썸바리가 여러분의 글을 수정하거나 삭제할 가능성도 없진 않습니다만... 그런 경우는 드물고, 또한 그렇게 되는 경우는 쉬운 비밀번호를 지정한 원본 글 작성자에게도 상당부분 책임이 있기에... 이 강좌에서 그런 부분까지는 어떻게 해결할 수가 없을 것 같네요...  해서, 보다 보안적으로 데이터를 관리하고 싶다면, 회원 가입 및 로긴을 받아서... 글을 작성한 사용자만이 글을 수정하거나 제거할 수 있게 하는 것이 바람직 할 것입니다만... 지금은..  보편적인 게시판을 제작하는 것이니, 비밀번호로만 검증과정을 끝내도록 하겠습니다. 다른 일반적인 게시판들이 그러하듯이 말입니다.

(뭔가 발견한 것처럼 강조하면서)어쨌든, 글을 읽다보니... [수정]과 [삭제], 두 작업 모두 비밀번호의 일치여부를 무엇보다 먼저 검사해야 한다는 공통적인 부분이 있는 것을 알 수 있었습니다.

(이 시점 관중들은 괄호로 표현되는 이러한 개그에 싫증을 느끼기 시작한다. 필자는 자제 모드로 돌입한다)

해서, 그 부분 즉, 비밀번호의 일치여부를 검사하는 로직을 별도의 함수로 분리하여 처리해 보도록 하겠습니다. 그러면, 이 함수를 [수정] 작업 및 [삭제] 작업에서 간단히 빌려다가 사용할 수 있을테니 말입니다. 

함수의 역할은 매우 명확하죠? 그렇다면, 우선적으로 필요한 것은 무엇일까요? 그렇습니다. 비밀번호의 일치여부를 검사하는 프로시저일 것입니다. 글의 seq 값과 pwd 컨트롤에 입력된 비밀번호를 인자로 하여... 실제 비밀번호가 일치하는지를 확인하는 프로시저 말입니다. 해서 작성해 본 프로시저는 다음과 같습니다.

CREATE PROC UP_IS_PASSWORD_VALID
    @seq    int,
    @pwd   varchar(20)
AS
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    SET NOCOUNT ON

    SELECT seq FROM ThreadBoard
    WHERE seq = @seq AND pwd = @pwd
GO

쿼리는 매우 간단합니다. 단지, 인자로 넘어온 seq값과 pwd 값에 부합하는 레코드가 있다면 그 레코드의 seq 값을 얻어오는 것이 전부입니다. 왜 하필이면 seq 컬럼값을 얻어오냐구요????  사실, 그것은 별 의미가 없습니다. 이 프로시저는 단지 해당 seq 및 pwd에 일치하는 레코드가 있느냐 없느냐를 알아내는 것이 목적일 뿐이니까요....  프로시저를 실행해서, 그 결과로 레코드가 있다면 비밀번호가 일치하는 것이고, 레코드가 없다면 비밀번호가 일치하지 않는 것입니다.

이제, 프로시저를 위와 같이 작성하셨다면, [쿼리 분석기]로 이를 실행해 주세요~~ 그러면, 뚜~둥 하면서.... UP_IS_PASSWORD_VALID 프로시저가 만들어질 것입니다.

쿼리가 준비되었으니 이번에는 해당 함수를 작성해 보도록 할께요.. Content.aspx의 코드 비하인드 페이지에 다음과 같은 함수를 추가해 보도록 해요~~

    private bool IsPasswordValid()
    {
        bool flag = false;

        string ConnectStr = "server=(local);database= TEST;user id=sa";

        SqlConnection Con = new SqlConnection(ConnectStr);
        SqlCommand Cmd = new SqlCommand();
        Cmd.Connection = Con;

        Cmd.CommandText = "UP_IS_PASSWORD_VALID";
        Cmd.CommandType = CommandType.StoredProcedure;

        Cmd.Parameters.Add("@seq", SqlDbType.Int);
        Cmd.Parameters["@seq"].Value = ViewState["seq"].ToString();
        Cmd.Parameters.Add("@pwd", SqlDbType.VarChar, 20);
        Cmd.Parameters["@pwd"].Value = pwd.Text;

        try
        {
            Con.Open();

            if(Cmd.ExecuteScalar() != null)
                flag = true;
        }
        catch(Exception ex)
        {
            lblError.Text = "ERROR : " + ex.Source + " - " + ex.Message;
            lblError.Visible = true;
        }

        if(Con.State == ConnectionState.Open) Con.Close();

        Cmd = null;
        Con = null;

        return flag;
    }

코드에서는 사실 한가지를 빼면 그다지 주목할만한 부분은 없어 보입니다. 그 외의 부분들은 다들 이미 공부가 된 부분들일 것이고, 기존의 SELECT 명령의 처리 방법과 사실 거의 동일하니까요... 그렇담, 주목할만한 그 한 부분은 어디일까요? 그것은 Command 매개변수 중 seq 값을 지정하는 부분입니다... 그 부분이 왜 주목할만한지 그 설명을 들어보실까요~

Command 매개변수 중 seq 값을 지정하는 부분이 중요한 이유는 그 값을 지정하기 위해서, ViewState에 저장되어져 있는 값을 사용하고 있기 때문입니다. 비밀번호 일치여부를 검사하는 작업은 언제나 Content.aspx 페이지에서 [EDIT]나 [DELETE] 버튼이 클릭될 경우, 포스트백을 통해서만 일어나는 작업입니다. 이 부분이 중요합니다. 포스트백 작업으로 일어난다는 것 말입니다.

사실, seq나 기타 값들은 그 값을 어떤 별도의 저장소에 담아두지 않는 한, 페이지 요청간에 그 데이터를 유지할 방법이 없습니다. 이미 아시는 이야기이겠습니다만, 그것이 바로 Http의 단점이지요. 해서, 필요에 따라서는 Session이나 Cache를 사용해야 하구요... 만일, 동일 페이지 간에서의 데이터 유지라면 좀 더 성능에 좋은 ViewState를 사용하곤 하지요. 그러한 이유로 이전 강좌에서 제가 seq나 thread 값 등을 ViewState에 넣어둔 것입니다. ^^. 그러면, 지금과 같은 포스트백 상황에서도 그 값을 불러와서 사용할 수 있을테니까요 ^^

사실, 위의 구현방식은 기존 제 ASP.NET 서적에서의 방법과 약간은 차이가 있긴 하지만요. 관점에 따라서는 이 코드가 조금 더 나은 소스처럼 느껴지기도 하네요 ^^;;

자자... 어쨌든 비밀번호 일치여부를 확인하기 위해서, 위의 코드는 해당 프로시저를  seq 인자와 사용자가 입력한 pwd 값을 가지고 준비한 다음, 실행하고 있습니다. 실행 시에는 ExecuteScalar() 메서드를 사용하고 있는데요. 재미있는 것은 만일, 비밀번호가 일치하지 않는 경우에는, 반환되는 레코드 자체가 없을 것이기에, ExecuteScalar() 메서드의 결과 자체는 null 이 될 것이라는 점입니다.

고로, 우리는 간단하게 그 리턴 값이 null이냐 아니냐를 따져서, 비밀번호가 일치하느냐 아니냐를 알아낼 수 있는 것이지요. 이 부분도 제 ASP.NET 책과는 조금 다른 데요. 책에서는 쿼리를 통해서 비밀번호를 얻어와서 그 비밀번호와 사용자가 입력한 비밀번호를 비교하는 식으로 풀어나가고 있습니다. 여러분은 맘에 드는 어떤 방법을 써도 무관하겠습니다. ^^;

이제, 비밀번호 일치여부를 알아내는 별도 함수가 완성되었으니, 한번 테스트를 해보도록 할까요?

웹 폼에서 [DELETE] 이미지 버튼을 더블 클릭해서, 해당 버튼의 Click 이벤트 처리기 코드 작성 구역으로 가보도록 합시다~~~  이, 이벤트는 사용자가 비밀번호를 입력하고 btnDelete 버튼을 클릭할 경우에 서버에서 반응하는 이벤트 처리기라는 것은 이미 아시죠? 네.. 그렇습니다. 그렇다면, 이 구역에 다음과 같은 코드를 작성해 보아요~~~

    private void btnDelete_Click(object sender, System.Web.UI.ImageClickEventArgs e)
    {
        bool isValid = IsPasswordValid();

        if(isValid)
            lblError.Text = "비밀번호 일치!!";
        else
            lblError.Text = "비밀번호 불일치!!";

        lblError.Visible = true;
    }

위의 코드가 실제로 btnDelete_Click의 코드인 것은 아닙니다. 일단 테스트를 한번 해 보자는 것이지요. ^^;; 비밀번호가 일치할 경우와 일치하지 않을 경우 각각 올바르게 동작하는지를 먼저 알아보려는 의미에서 말입니다. ^^

자. 위와 같이 작성하시고... 페이지를 한번 실행해 보도록 하겠습니다. 물론, 페이지의 실행은 list.aspx 부터 해야 하겠죠? Content.aspx는 List.aspx에 종속적인 페이지이니까요 ^^

다음 그림은 비밀번호가 일치할 경우와 일치하지 않을 경우 각각의 그림입니다. 제대로 lblError 컨트롤에 메시지가 출력되는 것을 확인하실 수 있을 겁니다. ^^

[비밀번호 일치 시]

[비밀번호 불일치 시]

제대로 잘도 동작하고 있네요... 글쵸????  그렇다면, 이제 제대로 된 btnDelete_Click 코드를 작성해 보도록 해요~~~  자. 그럴라면, 먼저 btnDelete_Click 에서 어떤 처리를 수행해야 할지를 한번 알아봐야 하겠죠? 그렇습니다. btnDelete_Click에서는 비밀번호가 일치할 경우, 해당 레코드를 삭제하는 작업을 수행해야 합니다. ^^ 그러합니다...

그렇다면, 이 시점에서 그렇게 특정 레코드를 삭제하기 위한 저장 프로시저도 필요하겠네요. 맞쑴니다. 마꾸요~~~ 바로 그것이 필요합니다. 두둥-----

CREATE PROC UP_DELETE_BOARD
    @seq    int
AS
    SET NOCOUNT ON

    DELETE ThreadBoard
    WHERE seq = @seq
GO

역시 삭제를 위한 프로시저는 간단하죠??  ^^

자, 그렇다면 이 프로시저를 사용하는 Delete 로직을 만들어 보도록 하겠습니다. 근데요. 뭐 반드시 그래야 하는 것은 아닙니다만.. 코드의 가독성을 높이는 차원에서요... 이 삭제 로직은 btnDelete_Click 이벤트 처리기 내부가 아닌 별도의 함수로 작성해 보려 합니다. 다시 말씀드리지만, 반드시 그래야 하는 것은 아닙니다. 그냥 그렇게 하는게 경험기반적으로 낫기 때문에 추천드리는 것이랍니다. ^^

해서, 저는 그러한 별도 함수를 다음과 같이 작성해 보았습니다.

private void DeleteRecord()
{
    string ConnectStr = "server=(local);database= TEST;user id=sa";

    SqlConnection Con = new SqlConnection(ConnectStr);
    SqlCommand Cmd = new SqlCommand();
    Cmd.Connection = Con;

    Cmd.CommandText = "UP_DELETE_BOARD";
    Cmd.CommandType = CommandType.StoredProcedure;

    Cmd.Parameters.Add("@seq", SqlDbType.Int);
    Cmd.Parameters["@seq"].Value = ViewState["seq"].ToString();

    try
    {
        Con.Open();
        Cmd.ExecuteNonQuery();
    }
    catch(Exception ex)
    {
        lblError.Text = "ERROR : " + ex.Source + " - " + ex.Message;
        lblError.Visible = true;
    }

    if(Con.State == ConnectionState.Open) Con.Close();

    Cmd = null;
    Con = null;
}

하~~ 어려운 내용은 없죠? 단지, 지정된 글을 삭제하는 역할을 할 뿐이랍니다. ^^ 전체적인 코드는 기존의 코드들과 크게 다를 것도 없구요 ^^; 하하하...  그러면, 이제 btnDelete_Click 이벤트 처리기를 마무리 지어보도록 해요~~~  지금쯤의 실력이시면 이미 대략적인 코드를 눈치채실 수 있으시겠죠??  그렇습니다. 다음과 같이 하면 될 것 같아요~~~

private void btnDelete_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
    bool isValid = IsPasswordValid();
    if(isValid)
    {
        DeleteRecord();
        Response.Redirect("list.aspx");
    }
    else
    {
        string script;
        script = "<script>alert('비밀번호가 일치하지 않습니다');</script>";

        this.RegisterStartupScript("pwd", script);
    }
}

그렇죠???  비밀번호가 일치하면 방금 제작한 DeleteRecord() 메서드를 호출하는 것이구요. 비밀번호가 일치하지 않는다면 "비밀번호가 일치하지 않습니다"라는 메시지 박스를 자바스크립트를 사용해서 나타나게 하는 것입니다. ^^;; 

여기까지의 코드 구성이 다 되었다면, 그럼 한번 실행하고 결과를 보도록 할까요??? 먼저, 비밀번호를 틀리게 입력하였을 경우는 예상한대로 다음과 같은 결과가 나타날 것입니다.

그리고, 비밀번호가 올바르게 입력이 되는 경우는 글이 삭제되고, List.aspx 페이지로 이동하게 될 것이구요.

 

__doPostback 메서드의 비밀!!

이하의 내용은 최신 ASP.NET 버전(아마도 2.0 이상)에서는 올바로 동작하지 않을 수 있습니다.

그런데, 테스트를 하다보니 한가지 조금 개선했으면 하는 점이 있지는 않나요? 개인적인 생각일런지 모르겠습니다만... 저는 뭔가 2% 부족함이 느껴지는데요~~  그것은 바로... 삭제가 너무 간단하게(?) 된다는 것입니다. 그러니깐, 다시 말하자면, 삭제를 함에 있어서... 혹시라도 사용자가 잘못 클릭할 수도 있으니... 진짜로 삭제하려는 것이 맞는지 확인하는 과정이 있었으면 좋겠다는 것이지요...  -_-;  "정말로 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다" 와 같은 메시지를 띄워서... 확인을 받는... 등등 말입니다.

그렇습니다. 해서, 이번에는 그러한 작업을 해보려 하는 것이지요 ^^;

근데, 이러한 작업이 ASP.NET에서는 그리 만만하지는 않습니다. 이를 완전하게 이해하려면 ASP.NET의 구조뿐만 아니라 웹 프로그래밍의 수행방식에 대해서 조금은 구체적으로 ^^알고 있어야 하거든요. 하지만, 이해하려 노력한다면 이해할 수 있다고 생각합니다. 노력으로 안되는 것은 없다고 믿으니까요...  ^^;

자. 그럼 어떻게 하면 그러한 중간 Confirm을 삽입할 수 있는지 알아보도록 하겠습니다.

우선!!! "정말로 삭제하시겠습니까?" 와 같은 그러한 컨펌 메시지 박스를 띄워서 사용자로부터 확인을 받고 싶다면, 당연히 그러한 작업은 클라이언트 스크립트로써 수행해야 합니다. 예를 들면, 자바 스크립트와 같은 것을 통해서 말이지요 ^^; 이 부분이 중요합니다..  이러한 작업을 하려면, 서버 컨트롤을 사용할 수가 없고, 일반 HTML 태그와 자바스크립트를 사용해야만 한다는 사실이 말입니다.

그런데, 자바스크립트를 사용할 경우에는, 서버 컨트롤의 서버 측 이벤트 핸들러를 호출하기가 난감하다는 문제가 있습니다. 기존에 우리가 사용한 ASP.NET 서버 컨트롤들의 서버 측 Click 이벤트의 수행은 ASP.NET의 기반상에서 모든 내부적인 처리들을 ASP.NET이 처리해 주었기에, 우리가 서버측 이벤트를 호출하기 위해 별다른 작업을 할 필요가 없이, 단지 컨트롤을 ASP.NET 서버 컨트롤로만 설정해 주면 되었습니다만....  만일, 서버 컨트롤을 사용하지 않는다면, 서버 측의 특정 이벤트를 HTML과 자바스크립트로 수행할 방법이 묘연하다는 것이지요...

하지만, 지금은 그게 가능해야만 합니다. 그게 가능해야만 원하는 기능을 구현할 수가 있으니까요. 즉, 쉽게 말하면... 클라이언트 자바스크립트 만으로, 서버 측의 이벤트 핸들러를 호출할 수가 있다면 지금의 문제는 해결될 수가 있다는 것입니다...

다시 한번 더 쉽게 풀면, 자바스크립트를 사용해서 서버측의 btnDelete_Click 이벤트 처리기를 호출할 수만 있다면 문제가 풀릴 수 있다는 것이지요.... 하지만, 이게 쉽다면... 얼마나 좋겠습니까??? 결코 쉽지가 않다는 것이 문제입니다...

일단, 기본적인 방법으로는 이것은 사실상 불가능에 가깝습니다. 약간의 편법을 사용하지 않는다면 말이지요. 그렇다면, 말입니다... 그넘의 편법이라는 것은 무엇일까???  그게 포인트일 것 같다는 생각이 들지요???

일단, 하나씩 짚어나가 봅시다. ASP.NET이라 할지라도 어차피 결과 페이지는 단순한 HTML 페이지라는 것은 명확합니다. 그렇다면, 어떻게 ASP.NET에서는 버튼이 클릭될 경우, 그 버튼의 Click 이벤트가 서버에서 일어날 수 있는 것일까요??? 의외로 간단합니다. 각각의 버튼은 HTML 결과로 생성될 경우, 모두 submit 버튼으로써 생성이 됩니다. 다시 말해서, 모든 ASP.NET의 버튼은 기본적으로 서브밋 버튼이라는 것이지요. 해서, 일단 사용자가 버튼을 클릭하면 버튼은 무조건 페이지를 서버로 서브밋합니다. 그리고, 서브밋과 함께 현재 어떤 버튼이 클릭되어져서 폼이 서브밋 되는지 그 버튼의 ID 정보도 같이 서브밋을 하지요...

서버는 그 ID 정보를 읽어와서, 그 ID에 해당하는 컨트롤의 Click 이벤트를 처리하는 것입니다. 쉽죠???? 그렇다면, 버튼이 아닌 링크의 경우에는 어떻게 처리될까요?? 예를 들면, 링크버튼(LinkButton)과 같은 경우는 말입니다. 링크 버튼은 모습은 하이퍼링크의 형태를 가지고 있습니다. 형태가 하이퍼링크이다보니 이는 결과 HTML 페이지 상에서 결코 서브밋 버튼으로 구성될 수는 없습니다. 하지만, 이 친구도 서버측의 이벤트를 아주 잘 수행하고 있지요...  ^^;  바로 이 부분에 편법이 숨어있는 것입니다.

결론적으로 말하면, 링크버튼이 폼에 포함된 경우는, ASP.NET이 자동으로 결과 HTML에 특별한 자바스크립트 함수를 하나 추가합니다. 잠시 뒤에 보겠지만, 그 함수는 __doPostback 라는 이름을 가지고 있지요. 그리고, 이 함수가 바로 폼을 서브밋하는 역할을 합니다. 그리고, 이 함수의 첫번째 인자로는 현재 이벤트를 일으킨 컨트롤의 ID가 자리하게 되지요. 내부적으로 이렇게 동작을 한다는 것입니다.

즉, 이 링크버튼이 만들어 내는 __doPostback 자바스크립트 함수를 잘만 이용하면, 우리는 개발자 맘대로 자바스크립트 함수에서 원하는 버튼 컨트롤의 서버측 Click 이벤트를 일으키게 만들 수 있다는 것입니다. __doPostback 함수의 첫번째 인자로 호출하고자 하는 컨트롤의 ID를 지정해서 말이지요 ^^;

프로그래밍 경험이 많으신 분들은 아마도 방법을 이해했을 것 같네요 ^^;

지금까지의 설명만으로는 이해가 잘 안갈 수 있습니다... 물론 그럴 수 있지요... 그렇다면, 한번 예제를 해보고 이야기를 계속해 보도록 하겠습니다. 예제를 위해서 doPostBackTest.aspx 라는 페이지를 하나 새로이 만들어 보도록 해요 ^^;

그리고, 웹 폼 위에다가 링크버튼(LinkButton)과 레이블(Label)을 각각 하나씩 올려보도록 합시다. 다음과 같이 말이죠 ^^;

그 다음, 링크버튼을 더블클릭해서 서버 측 Click 이벤트를 다음과 같이 작성해 보도록 해요.

    private void LinkButton1_Click(object sender, System.EventArgs e)
    {
        Label1.Text = "멋지게 클릭하셨구만요~~";
    }

호오... 멋진 코드죠???  (관중들 야유하기 시작한다~) 그렇습니다. -_-; 어쨌든, 이제 페이지를 실행해 보도록 하세요!!  그럼 다음과 같은 멋진 결과를 보실 수 있을 것입니다. ^^;

그렇습니다. 사실 결과야 뭐 대단할 것이 없지요. 클릭하면, 예상한 대로 레이블에 문자열이 출력되는 정도이니 말입니다. ^^; 실제로 중요한 것은 결과가 아니라, 이 경우에 생성된 HTML 태그들입니다. 그것이 매우 중요하지요. 현재 페이지의 HTML 소스를 확인해 보세요. 페이지를 보시면 상단에 다음과 같은 자바스크립트 함수가 추가되어져 있는 것을 보실 수 있을 것입니다.

__doPostBack 함수 내부의 코드들을 이 자리에서 조목조목 분석하기는 좀 그렇습니다만... 어쨌든 이 함수의 역할은 링크버튼이 클릭될 경우, 폼을 서버로 서브밋하고, 서버에서 해당 버튼의 Click 이벤트를 처리하게끔 하는 역할을 합니다. 밑 쪽의 소스를 잘 살펴보시면 링크버튼이 바로 이 __doPostBack 함수를 호출하는 하이퍼링크로 생성되어져 있는 것을 볼 수 있을 것입니다. 다음과 같이 말이죠~~

<a id="LinkButton1" href="javascript:__doPostBack('LinkButton1','')">LinkButton</a>

또한, 이 __doPostBack 함수는 웹 폼 안에 링크버튼이 있을 경우에만 자동으로 추가되는 코드라는 사실을 기억하시기 바랍니다. ^^;

자. 이제 여기에다가 재미있는 코드를 하나 추가해 보도록 하겠습니다. 이 코드는 일종의 fake 코드라고 할 수 있겠는데요. 서버 컨트롤도 아닌 녀석이 서버 컨트롤을 클릭한 것처럼 속임수를 부리는 코드가 되겠습니다.. 즉, 다음과 같은 단순한 하이퍼링크를 HTML에 추가하고, 이 하이퍼링크가 __doPostBack 함수를 호출하도록 지정하면 그러한 속임수를 부릴 수 있다는 것입니다. (단, 첫번째 인자로 대상이 될 서버 컨트롤의 ID를 기입해주어야 합니다)

코드 중 다음 부분이 제가 추가한 코드입니다. ^^;

<p>
<a href="javascript:__doPostBack('LinkButton1','');">Fake</a>
</p>

이렇게 추가했다면, 페이지를 다시 실행해 보시기 바랍니다. 그리고, 지금 추가한 Fake라는 하이퍼링크를 클릭해보도록 하세요. 재미있는 일이 벌어지고 있지요???????   그렇습니다. 마치 LinkButton이 클릭된 것처럼 동일한 일을 수행하고 있는 것입니다.

만일, 현재의 웹 폼에 다른 버튼 컨트롤들도 있다면, 이와 동일한 방법으로 __doPostBack 함수를 빌려씀으로써 그러한 버튼 컨트롤들에 대해서도 이러한 속임수 호출을 할 수가 있습니다. 단, 이를 위해서는 폼에 반드시 링크버튼이 최소 1개 이상이 존재해야 합니다. 그래야만, __doPostBack라는 함수가 생성될테니까요 ^^;

자. 그렇다면, 지금의 경우 우리는 어떻게 해야할까요? btnDelete 버튼을 링크버튼으로 바꾸는 것이 어쩌면 가장 바람직할 수도 있습니다만.. 그렇게 하면, 코드를 바꿀 것이 많아지니까요...   그 버튼은 그냥 그대로 두구요... 추가적으로 링크버튼을 하나 추가하고, Fake용 하이퍼링크를 하나 추가하도록 하겠습니다..  즉, 기존 코드에서 수정하거나, 삭제함없이 새로운 코드를 다음과 같이 추가하겠다는 것이지요(추가된 코드는 파란색으로 표기하였습니다)

            <tr height="1">
                <td colSpan="2" bgColor="#dadada" height="1"></td>
            </tr>
                <tr>
                    <td align="right" colSpan="2">
                        <asp:imagebutton id="btnList" runat="server" AlternateText="리스트로"
                            ImageUrl="images/b_list.gif" ImageAlign="AbsBottom"
                        </asp:imagebutton>
                        <asp:imagebutton id="btnReply" runat="server" AlternateText="답글달기"
                            ImageUrl="images/b_reply.gif" ImageAlign="AbsBottom"
                            CausesValidation="False"></asp:imagebutton>
                        <asp:TextBox Runat="server" ID="pwd" CssClass="input"
                            TextMode="Password"></asp:TextBox>
                        <asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"
                            ErrorMessage="비밀번호를 입력해 주세요" ControlToValidate="pwd"
                            Display="None"></asp:RequiredFieldValidator>
                        <asp:imagebutton id="btnEdit" runat="server" AlternateText="수정하기"
                            ImageUrl="images/b_edit.gif" ImageAlign="AbsBottom">
                            </asp:imagebutton>
                        <asp:imagebutton id="btnDelete" runat="server" AlternateText="삭제하기"
                            ImageUrl="images/b_delete.gif" ImageAlign="AbsBottom"
                            Visible="False"></asp:imagebutton>
                        <asp:LinkButton id="LinkButton1" runat="server"></asp:LinkButton>
                        <a href="javascript:__doPostBack('btnDelete','');">
                            <img src="images/b_delete.gif" border="0" align="AbsBottom"></a>
                    </td>
                </tr>
            </table>
            <asp:Label id="lblError" runat="server" CssClass="txt01" ForeColor="Red"
                 BorderWidth="1px" BorderStyle="Solid" BorderColor="Red" Width="520px"
                 Visible="False"></asp:Label><br>
            <asp:ValidationSummary id="ValidationSummary1" runat="server"
                ShowMessageBox="True" ShowSummary="False" DisplayMode="List">
            </asp:ValidationSummary>
        </form>
    </body>
</HTML>

링크버튼은 추가되었지만, 이는 어떠한 텍스트로 출력하지 않는 링크버튼이기에, 결과 HTML에서 조금의 공간도 차지하지 않을 것이며, 해서 마치 존재하지 않는 것처럼 취급될 것입니다. 그러나, 존재감은 확실하지요. 그러니깐, 다시 말하면, 이렇게 링크 버튼 컨트롤이 추가됨으로 해서, 이제 결과 HTML에는 __doPostBack 함수가 추가되어진다는 것입니다. 그리고, 링크 버튼 다음에 수동으로 입력한 하이퍼링크는 [삭제] 버튼인 btnDelete 버튼의 아이디를 인자로 사용하면서, __doPostBack 함수를 호출하고 있습니다. 이렇게 하면, 이 하이퍼링크가 마치 btnDelete 버튼이 클릭된 것처럼 동작할 것임을 추측할 수 있으시겠죠??? ^^;

그리고, 코드를 잘 보시면, 이미 btnDelete 이미지 버튼이 존재하고 있으므로, 그 버튼의 Visible을 false로 지정하여 눈에 보이지 않게 하고 처리하고 있음도 유심히 봐주어야 할 부분이랍니다. ^^;

자. 이렇게 작성하셨다면... 이제 페이지를 클릭하고 실행해 보도록 하세요. 어떤가요? [삭제] 이미지를 클릭하면 기존처럼 잘 동작하나요???  그럴 것입니다. 놀랍게도 무척이나 잘 동작하지요 ^^;

자. 이제 클라이언트 스크립트를 이용해서 서버측의 이벤트를 발생시킬 수 있는 기반을 만들었으니, 이제 우리가 원래 하려던 것을 작성해 보도록 해요. 즉, 별도의 스크립트 함수를 제작해서, 그 함수 안에서 "정말로 삭제하시겠습니까"를 물어본 다음, 사용자가 동의하는 경우에만 서버측의 이벤트를 부르는 일종의 Fake 기능인 javascript:__doPostBack('btnDelete','');를 호출하도록 하는 것이지요..

그러니깐, 간단하게 말하면, 다음과 같은 별도의 스크립트 함수를 하나 만들구요.

    <script>
    function DoDelete()
    {
        var b = confirm("정말로 삭제하시겠습니까?");
        if(b)
            __doPostBack("btnDelete", "");
        }
    </script>

그리고, 좀 전에 작성한 Fake용 하이퍼링크를 다음과 같이 변경하는 것이지요 ^^

<a href="javascript:DoDelete();">
        <img src="images/b_delete.gif" border="0" align="AbsBottom"></a>

핫핫핫~~~~ 나름대로는 간단하지 않습니까????

이제, 페이지를 다시금 실행하고, 글을 삭제해 보도록 하세요. 그러면 다음 그림과 같이, 정말로 삭제할 것인지를 물어보는 메세지 창이 나타날 것이고, [확인] 버튼을 누를 경우에만 삭제 처리가 진행될 것입니다. 물론, 비밀번호가 일치할 경우에 한해서만 말이지요 ^^

재미있지 않습니까??? 기초가 튼튼한 개발자일수록 이러한 트릭을 쉽게 이해할 수 있을 것이며, 나름대로 응용하여 수많은 기타 기능들을 구현할 수가 있을 것입니다. 해서, 기초가 매우 중요한 것이지요 ^^

이번 강좌에서는 게시판에서의 삭제기능을 구현해 보았구요. 적절한 수준으로 doPostBack 기능의 비밀에 대해서도 파헤쳐 보았습니다. 이미 중급의 실력을 가지고 있는 분들이라 할지라도 이러한 내부적인 이야기에 대해서 모르시는 분들이 많을 것이라 생각하기에, 이번 강좌가 더욱 더 유용한 강좌가 아니었나 하는 생각을 합니다...

이번 강좌는 아쉽지만, 이 즈음에서 정리가 될 것 같습니다요. (엇? 글의 수정은 왜 안하는 것이야~~?? 라고 독자들 야유를 부릴 듯 하다)

다음 강좌는 글의 수정을 주제로 하여 여러분을 찾아뵐 것인데요(-_-+++)..... 그렇습니다. 은근슬쩍.. 이번 강좌에서 해야할 내용은 다음으로 떠 넘기고 있는 것이지요...  죄송합니다. 그리고 다시 한번, 강좌가 늦은 점에 대해서 고개 숙여 사과드립니다. 현재 번역작업이 너무 고되다보니, 심적인 여유가 아무래도 부족하여... 강좌를 작성하는 것이 더딘 편이거든요... 부디 여러분의 바다와 같은 넓은 이해가 있으시기를 간절히 바라면서....

가급적 빨리 다음 강좌로 여러분을 찾아뵐 것은 약속드립니다.

(이때, 독자들은 못 미더운 표정을 짓지만, 한번 더 믿어볼 것처럼 보이는 야릇한 미소를 띄운다)

OK..컷. 여기까지~~~


authored by


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})