반응형

-- Wizard 컨트롤을 사용하다가 Backspace라던지 브라우저의 뒤로가기 버튼 등으로 인해서
    내가 원하는 데이터가 중복되어서 들어가거나 예상치 못한 오류가 발생하기도 하였다.

    국내 사이트에서는 이러한 방법에 대한 해결 방법이 나와있는 Article이 많이 없었다.
    결국 Googling을 통해서 발견한 사이트의 글이다.!!

Disable the Browser Back Button in your ASP.NET Applications

If you’ve just come to accept the Back button as a necessary evil, I’ve got a few simple solutions for you that prevent the user from backing up past a designated “one-time only” page in your application.

For example, if you have a wizard with multiple steps, it’s fine to let the user click the browser’s Back (and then Forward) buttons all they want as they navigate from page to page. But when they click Finish on the last page, and you save information to the database, you don’t want them to be able to click Back to the last wizard page and then click Finish again. This would result in repeating the server side processing (in this example, saving to the database again, but in another scenario this could mean charging a credit card multiple times). The proper approach would be for the user to start the wizard over from the beginning, if the intent is really to submit another new request that’s entirely separate from the last one.

Disabling the browser cache for the page is not a real solution (though I’ll show it anyway), because the user gets an ugly message when they click Back. In this post, I’ll show you how to add just a tiny bit of code to achieve an ideal solution that effectively disables the Back button.

Solution 1: Ask the user nicely and hope they listen

Most developers think there’s no way to disable the browser’s Back button and just don’t even try at something they believe to be futile. And that’s why you see messages like “Please don’t click the browser’s Back button after confirming your purchase as doing so may result in a duplicate charge to your credit card” on practically every e-commerce site on the Web. Surely there’s a better way…

Solution 2: Disable caching for the page

OK, so let’s just not cache the page with the Finish button, the one that does all the work that we don’t want repeated should the user click Back and then resubmit. We can do that by overriding the OnPreInit method (same thing as, but more efficient than, handling the PreInit event) and setting the various caching-related properties on the Response object to prevent the browser from caching the page:

protected override void OnPreInit(EventArgs e)
{
    base.OnPreInit(e);

    Response.Buffer = true;
    Response.ExpiresAbsolute = DateTime.Now.AddDays(-1d);
    Response.Expires = -1500;
    Response.CacheControl = "no-cache";
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
}

See http://forums.asp.net/t/1060173.aspx and http://www.codeproject.com/KB/aspnet/NoCaching.aspx for more information on these property settings.

One problem solved (no more risk that the user will click Finish twice), but a new problem is created (user gets “Webpage has expired” error if they click Back):

Expired

The screen shot above is from Internet Explorer; different browsers (Chrome, FireFox, etc.) handle the condition by prompting the user in different ways. But the bottom line is that this solution results in a degraded user experience because we’re not really disabling the Back button. We’re just preventing the page from being stored in the browser history, so that when the user does click the Back button, they get the expired error/prompt instead of the page they expected to go back to. Is there a way around this? You bet! Read on…

Solution 3: Disable the Back button completely

This is the simplest solution that disables the Back button completely. How simple? Just add onload=”window.history.forward();” to the <body> tag in the page(s) that you don’t want the user to be able to click Back to.

<body onload="window.history.forward();">

With this solution, the page tries to move forward in history as soon as it loads. Of course, for newly served pages this has no effect, since there’s no forward history. But when the user clicks the Back button to reload the same page from the browser history, the page immediately forces the browser to pop back to where the user came from, as though they clicked Forward right after clicking Back. But it happens before the previous page even has a chance to load because the ”forward” command is invoked on the onload event of the previous page. Including this in every page in your application will disable the Back button completely (for postbacks too), which may not be something you want. Since users do expect to be able to use the Back button, you should let them do so except when undesirable behavior results (such as charging their credit card more than once).

Solution 4: Use this “hidden field/script/postback” trick

This solution is a little more involved, but is more flexible and opens up other interesting possibilities (for example, it gives you greater control when server-side validation is involved).

The gist of it? — You can’t directly disable or otherwise control the behavior of the Back button. But you can deliver a page that always forces a redirect, which gets stored normally in the browser’s history, such that when the user clicks Back, the redirect will always be forced.

Here’s the recipe:

1) Add a hidden field

In the .aspx markup, add a hidden field server control to your page that starts off with no initial value:

<input type="hidden" id="hidIsCommitted" runat="server" />

This field will get set only when the code-behind performs the processing you don’t want repeated (e.g., database save, credit card charge) if the user clicks Back and then resubmits.

2) Just beneath the hidden field, add the following script:

<script language="javascript" type="text/javascript">
    if (document.getElementById('<%= this.hidIsCommitted.ClientID %>').value == '1')
    {
        location.href = 'ThankYouPage.aspx';
    }
</script>

This simple code tests the value of the hidden field, and if it is set, the code redirects the user to the Thank You page (the page the user is normally redirected to after clicking Finish). Of course, the hidden field is not initially set, since we added it above with no value and no code has set its value yet.

Note the importance of using both document.getElementById and the bee-sting <%= %> server-side replacement markup for the hidden field’s ClientID value. Using getElementById ensures cross-browser compatibility, and the ClientID property resolves to the actual ID generated for the hidden field in the DOM, which includes additional unique identifiers if the element is contained inside a templated control, content placeholder, or other naming container.

3) Just beneath the script, add the following server-side span element with another script block inside of it:

<span id="spnCommitScript" runat="server" visible="false">
    <script language="javascript" type="text/javascript">
        document.getElementById('<%= this.hidIsCommitted.ClientID %>').value = '1';
        var theForm = document.forms['form1'];
        if (!theForm) theForm = document.form1;
        theForm.submit();
    </script>
</span>

This code sets the hidden field value and then performs a postback, but because the script block is wrapped inside of a server-side span element named spnCommitScript whose visible property is set to false, this code is not actually sent to the client. Only when the span element is made visible by server-side code will this client script get sent to the client, and the server-side code will not make the span visible until after completing the processing that occurs when the user clicks Finish.

4) In the code-behind, just at the point in time when you have completed processing (saving to the database, charging the credit card, etc.), make the span visible. Basically, this is the same point in time that you would normally issue a Response.Redirect to the Thank You page. But instead, you just make the span visible:

protected void btnFinish_Click(object sender, EventArgs e)
{
    if (!this.PerformAdditionalValidation())
    {
        this.lblValidationErrorMessage.Visible = true;
        return;
    }

    // Update database, charge credit card, etc.
    this.spnCommitScript.Visible = true;
}

The result? When the page returns to the client, the hidden field value is still not set. So the initial JavaScript test still returns false and the user does not get redirected to the Thank You page yet. But right after that, additional JavaScript code executes that has never execute before because the span has always been invisible. And that JavaScript code goes ahead and sets the hidden field, and then invokes a postback. The page returned to the client after the postback is then stored in the browser’s history cache normally. But this version of the page has the hidden field value set which causes redirect to the Thank You page. So clicking Back from the Thank You page results in reloading a page that forces itself to redirect immedately back again to the Thank You page. If the user clicks the Back button all day long, they won’t be able to back up past the Thank You page. Even if they advance several pages forward in the application, they’ll be able to click Back only up until reaching the Thank You page, but no further back than that.

All of the markup in steps 1, 2, and 3 can be placed in a Master page, so that it can be shared by all Content pages. With this approach, you would implement the redirect page as a variable rather than hard-coded as ThankYouPage.aspx and thus achieve an extremely lightweight framework for handling the Back button in this manner across your entire application. Only the code in step 4 (modified to also set the desired redirect page name) needs to be applied whereever you’d normally code an ordinary Response.Redirect in your code-behind.

 Hope this information saves you some grief trying to cope with the Evil Back Button!



출처 : Lenni Lobel on .NET and SQL Server Development의 블로그!!

반응형
반응형

asp.net을 하다 부딪히게 되는 가장 큰 장애중 하나로

뒤로가기가 제대로 안되는 문제가 있습니다.

"이거 asp나 jsp로 할 때는 아무 문제도 아니었는데 말야..

닷넷 정말 좋은 거 맞는거야? " 라고들 생각하셨겠죠..

 

물론 javascript로 history.back() 하는 것보다는 복잡하지만

생각보다는 쉽게 구현할 수 있습니다.

원리는 간단합니다.

PostBack의 카운트를 세어서 그만큼 뒤로가기를 시켜주는 것입니다.

 

Page_Load 이벤트에 다음과 같이 코딩해주시면 됩니다.

if (!IsPostBack)
{
    ViewState["History"] = -1;   

}
else
{
    ViewState["History"] = Convert.ToInt32(ViewState["History"]) - 1;
}

btnList.Attributes["onclick"] = "history.go(" + ViewState["History"].ToString() + ");return false";

 

 

처음 그 페이지에 들어왔을 때에는 history.go(-1)을 해주면

뒤로 가니까 초기값을 -1로 주었습니다.

그리고 PostBack이 일어날 때마다 그 값을 하나씩 빼줍니다.

그 다음엔 돌아가야할 카운트를 되돌아가기 버튼에 할당해줍니다.

 

되돌아가기 이벤트를 서버 이벤트로 처리할 수도 있었지만

필요없는 네트웍 트래픽만 일으키게 되기 때문에

클라이언트쪽 이벤트로 처리해 보았습니다.

반응형
반응형

Repeater를 사용하여 해당하는 Row를 삭제시키고자 Row 제일 뒤에 Button을 하나 추가하였다.

<asp:Button ID="btnDelete" runat="server" CssClass="ButtonSmall" Text="Del" CommandArgument='<%# Eval("num") %>' CommandName="Delete"/>

- CommandName : Delete
- CommandArgument : DB 테이블에서 Unique한 Num값을 가져옴

페이지까지 만들고 "자 삭제 시켜볼까?"

'Del' Click Click Click!!!

"엥?? 아무런 반응이 없냐..ㅡㅡ;;"

Num값을 잘못 가져왔나 싶어서 몇번이고 디버깅 모드로 확인을 해봤지만

코드상 아무런 문제가 없었다.!!

미치고 팔짝 뛸 노릇이네..ㅡㅡ;; 물 내공은 손 발이 고생이다..!!

"자 그럼 구글링으로 고고고!!"

Search -- Repeater ItemCommand Error    __ Enter

....

무수히 많은 Article들이 올라온다.. 하지만 내가 원하는게 없네..

그러던 마침내 발견한 하나의 글 중 한 소절~~

"ItemCommand 이벤트는 Onclick 이벤트가 발생하고 이 후에 동작을 한다.....................

....................

....................

크아!~~~~~~~~~~~~~~~~

자자 Page_Load 함수를 보니..

역시나 Repeater를 Bind시키는 함수 한줄이 들어있다..ㅠㅠ

이놈아가 Repeater내의 버튼 클릭하게 되면 요것이 동작하면서 Reapeter를 다시 재 바인딩 시키는 것이 아닌가..킁..

살포시 if(!IsPostBack)을 씌워줬더니..

그제서야 삭제가..

음햐.. 1년동안 닷넷을 하면서 이런 동작 자체도 이해 못하고 있다는 내가

발가락의 때만큼의 못한 불쌍함이 들었다..크...

기초 기초 기초!! 세월이 가면 갈수록 느끼는 거는 무슨일이든 기초가 중요하다는거.!!

아우.. 끌쩍끌쩍 거리면서도 얼굴이 다 화끈거리네.

아까운 2시간을 훌라당 날려버리고 이제서야 전 퇴근 준비를 합니다.ㅠㅠ

반응형
반응형

Easy solution for default button

There is a free component that allows you to assign a button to the “enter-pressed” client side event of input controls. If you type some text in textbox and press Enter, the form will postback, and the serverside click event of your button is fired. You don’t need to write any code, but you only need to use this control’s “DefaultButton” property. It you are a beginner programmer this could be a life saver. More about MetaBuilders DefaultButtons Control you can find at http://www.metabuilders.com/Tools/DefaultButtons.aspx

Default buttons in ASP.NET 2.0 and ASP.NET 3.5

ASP.NET 2.0 makes this problems easier and introduce a concept of a “default button”. New defaultbutton attribute can be used with <form> or <asp:panel> control. What button will be “clicked” depends of where actually cursor is and what button is chosen as a default button for form or a panel.

Here is sample HTML code that contains one form and one panel control:

<form defaultbutton=”button1″ runat=”server”>
    <asp:textbox id=”textbox1″ runat=”server”/>
    <asp:textbox id=”textbox2″ runat=”server”/>
    <asp:button id=”button1″ text=”Button1″ runat=”server”/>
    <asp:panel defaultbutton=”button2″ runat=”server”>
        <asp:textbox id=”textbox3″ runat=”server”/>
        <asp:button id=”button2″ runat=”server”/>
    </asp:panel>
</form>

반응형
반응형

닷넷 내에서 데이터 다운로드 기능을 구축할때

a 링크를 통해서 많이들 적용시켜놓는데

보안성, 효율성 면에서 아주~~~~~ 떨어지는 방법이다.

다운로드 기능은 많이 사용하지 않아서 한번 쓰고 잊고 해서

항상 구글신을 통해서 기술을 습득하곤 했다.

아래의 링크는 MS에서 파일 다운로드 구축에 따른 article이다.

자세히 읽어보면 파일 다운로드에 대한 기본적인 이해를 시켜줄 수 있을것이다.^^

http://www.microsoft.com/korea/msdn/msdnmag/issues/06/09/WebDownloads/default.aspx#S1
반응형
반응형

1. WEB2.0 의 본질
ㆍ초기 WEB의 기술적 장벽 극복
ㆍ사용자 참여로 만드는 새로운 가치
ㆍ가치 창출을 위해 필요한 것들
   - Contents
   - Open API & Tools
   - UI Library


2. Mashup 트랜드
ㆍProgrammable Web
ㆍ지도 + 사진 이 절반, 쇼핑, 검색, 여행, 동영상, 뉴스, 부동산


3. 유용한 컨텐츠
ㆍ고품질 이미지 : flickr
   - 전세계 20억장의 이미지
   - 미국 의회 도서관 사진
ㆍ고해상도 위성지도
   - Yahoo, Google, MS
ㆍ검색 전자상거래
   - Naver, Daum, Auction
ㆍ공공정보
   - public.resource.org


4. Yahoo! Pipes
ㆍPipes
   - Rewire the web
   - 2007.2 월 등장
   - 모듈을 통한 시각적 매쉬업 지원


5. 매력적 인터페이스
ㆍYUI : 10명의 개발자
   - http://developer.yahoo.com/yui/
ㆍGoogle Chart aPI : URL 파라메터
   - http://code.google.com/apis/chart/
ㆍ위자드웍스 UI
   - http://www.wzdapi.com/styleguide


6. Open Trend 2008
ㆍ사진, 지도 매쉬업의 여전한 인기
ㆍ쉬운 Mashup 플랫폼, 도구 필요
   - MS Silverlight, MS POPFLY, Yahoo! Pipes
ㆍ다양한 컨텐츠 활용
   - 이미지, 동영상, 온라인 스토리지
ㆍ상용 Open API 등장
   - 통계, 보안, 모니터링 제공
ㆍUI 라이브러리 다양화

반응형
반응형

출처 : HOONS 닷넷

1.Refactoring 이란?

VS.NET 2005의 생산성을 높여주기 위해서 지원하게 된 기능입니다. 이름에서 느낄수 있듯이 바로 코드 자동화 기능이 추가 된 것이죠. 소스 코드에 있는 변수의 이름을 일관적으로 바꾸는 작업이나 프로세스를 자동화하는 등의 여러 자동화 작업등을 이용할 수 있습니다. 아래 그림을 살펴 봅시다.



닷넷2005 편집기에서 오른쪽 마우스를 눌러보면 Refactor라는 메뉴가 추가 되어있고, 오른쪽에 여러 기능들이 있습니다. 바로 추가된 코드 자동화 기능으로 정의 하셔도 크게 문제 없을것 같습니다. VS2005를 사용하면서 반드시 알아 두어야 할 기능 들로 생각이 듭니다.
이번 아티글에서는 Refactoring의 3가지 기능을 살펴보고 다음 아티글에서 나머지 기능을 알아보도록 하겠습니다.

2.Rename..
기능그 첫번째 기능으로 Rename 기능을 살펴 보도록 하겠습니다. 이 기능은 기존에 자주 사용해오던 [찾기]->[바꾸기]->[모두바꾸기]의 기능과 많은 연관이 있어 보입니다_-_ㅋ
Rename은 특정 변수의 변수명을 일괄적으로 변경해 줍니다.소스및 주석에서의 이름도 변경이 됩니다. 이것은 단순히 텍스트를 인식해서 바꾸는 것이 아닌 쓰여진 변수의 이름만 Rename 처리를 합니다.
아래 예제를 보면서 Rename 기능을 살펴 보도록 하겠습니다.
 
단축키Ctrl + R + R

DEMO

class Program
{
    public string strHoons = "Refatoring";

    static void Main(string[] args)
 
   {
        strHoons += " World!!";
        Console.WriteLine(strHoons);
    }
}

코드를 살펴보면 단순히 strHoons라는 변수를 사용하였고, strHoons를 출력 하였습니다.
그런데 왠지 Hoons라는 변수이름이 맞지 않는것 같습니다._-_; 우리는 여기서 strRefactor 라고 변경을 해보도록 합시다

이제 strHoons변수에서 오른쪽 마우스를 누릅니다. 그리고 Refactor를 선택해 봅시다.


Rename을 선택합니다.

 

NewName에 새로운 이름을 작성합니다. (strRefactor)


새로운 이름을 적게 되면 Preview 마법사가 실행되며, 적용 여부를 결정하게 됩니다.


3. Extract Method

기능Extract Method.. 조금 맘에 기능입니다.
이 Extract Method 기능은 자신이 원하는 코드를 Block으로 잡으면 그 부분을 메서드로 바꾸어 주는 것입니다.
이 Extract Method는 단순히 선택 Block을 Void형 메서드로 만들어 버리는 것이 아니라 코드 상황에 따라 특정 Return값을 뱉어 내는 메서드를 만들어 버립니다.

단축키Ctrl+R+M

DEMO



특정 블락을 드래그 하여 Extract Method를 실행합니다.


 
그리고 메소드명을 적습니다. 확인을 눌러 결과를 확인합니다.
 

 class Program
{
    public string strRefactor = "Refatoring";

    static void Main(string[] args)
    {
        WriteRefactor();
    }
 

    private static void WriteRefactor()
    {
        strRefactor += " World!!";
        Console.WriteLine(strRefactor);
    }
}

그럼 아래에 WriteRefactor() 메서드가 작성되어 지고,
기존 코드는 메서드쪽으로 옮겨 가게 되는것을 볼수 있을 것입니다.
이번에는 다른 예를 살펴 봤습니다.

 static void Main(string[] args)

{

    strRefactor += " World!!";

    Console.WriteLine(strRefactor);

}

 ▼ " World!!" 부분을 드래그 하여 Extract Method를 실행해 보았습니다.

static void Main(string[] args)

{

    strRefactor += ReturnStr();

    Console.WriteLine(strRefactor);

}

private static string ReturnStr()

{

    return " World!!";

}

결과를 보시면 이렇게 string 형을 리턴하는 메서드를 만들어 냅니다.



4. Encapsulate Field

기능Encapsulate Field!! 개인적으로 가장 맘에 드는 기능입니다. 자동 캡슐화!! public 공적 변수를 변환해 자동으로 프로퍼티를 생성해 줍니다.
잘 이해가 안되는 분들, 이제 눈으로 기능을 확인해 봅시다..^^

단축키
Ctrl + R + F (이 기능 만큼은 단축키를 외웁시다.)

기능
 


프로퍼티명을 적어 줍니다.



결과가 기대 됩니다.!! 두근두근
이제 결과를 살펴 봅시다.

 public string strRefactor = "Refatoring";

▼ 실행 결과

private string strRefactor = "Refatoring";

public
string StrRefactor
{

    get { return strRefactor; }
    set { strRefactor = value; }
}


놀랍지 않습니까?! 단순히 Ctrl+R+F를 실행한 결과로 자동으로 캡슐화 기능을 실행시켜 프로퍼티가 탄생합니다.



5. 정리
예전 닷넷 2002에서 2003이 발표되었던 때와는 전혀 분위기가 다르군요. 2005의 발표는 정말 많은 기대가 됩니다.
이번 아티글에서는 Refactory 3가지 기능에 대해서 알아 봤습니다. 다음 아티글에서는 Refactory의 나머지 기능에 대해서 다루어 보도록 하겠습니다.

반응형
반응형

회원이 비밀번호를 분실했을때 소정의 인증절차를 통과했을 경우 임의로 암호를 바꿔서 메일로 보내줄때 필
요해서 작성해봤습니다.
예전에도 이 게시판에 클래스 형태로 작성해서 올렸었는데 클래스 사용에 익숙치 않은분이 많은것 같아서 함
수로 정의했습니다.

생성되는 문자열 범위는 [a-zA-Z0-9]입니다.
함수의 인수에 얻고자하는 범위를 숫자로 입력해서 호출하면 됩니다.

// ASP.NET(C#) ----------------------------------------------
public string RandomString(int strLen)
{
  int rnum=0;
  int i, j;
  string ranStr = null;

  System.Random ranNum = new System.Random();

  for(i=0; i<=strLen; i++)
  {
    for(j=48; j<=122; j++)
    {
      rnum = ranNum.Next(48,123);
      if(rnum>=48 && rnum<=122 && (rnum<=57 || rnum>=65) && (rnum<=90 || rnum>=97))
      {
        break;
      }
    }

    ranStr += Convert.ToChar(rnum);
  }

  return(ranStr);
}
// use ex.: Label1.Text = RandomString(10);

반응형

+ Recent posts