'분류 전체보기'에 해당되는 글 317건

  1. 2012.01.10 Framework-based Development - 적용
  2. 2012.01.10 Framework-based Development - 개념
  3. 2012.01.10 닷넷 관련 개발 프레임워크
  4. 2012.01.10 DI
  5. 2012.01.10 서론.
  6. 2012.01.09 JSON 의 eval() 함수 사용의 문제
  7. 2012.01.09 JSON Text를 JSON Object로 변환하기
  8. 2012.01.08 jQuery 이벤트 정리
  9. 2012.01.08 [jQuery] Core , Selectors , Attributes , Manipulation, Events
  10. 2012.01.08 다른 라이브러리와 같이 쓰기
  11. 2012.01.08 jQuery Core
  12. 2012.01.08 [Jquery,CoffeeScript] 모질라 파이어폭스 Ajax. 한글 키 이벤트 처리.
  13. 2012.01.08 jQuery UI 테스트 2
  14. 2012.01.08 jQuery 이벤트 테스트 2
  15. 2012.01.08 jQuery 이벤트 테스트 1
  16. 2012.01.08 jQuery UI 테스트 2 1
  17. 2012.01.08 DataTable 수동으로 만들고 값넣기.
  18. 2012.01.08 C# <-> VB.net 코드 변환 사이트
  19. 2012.01.08 [ASP.NET] Repeater(리피터) 3
  20. 2012.01.08 [ASP.NET] Repeater(리피터) 2
  21. 2012.01.08 [ASP.NET] Repeater(리피터) 1
  22. 2012.01.08 [캐싱] 도넛 캐싱 구현 - ASP.NET 2.0 Output Cache Substitution
  23. 2012.01.08 [캐싱] Caching Process
  24. 2012.01.08 [캐싱] ASP.NET 캐싱 기능을 살펴보자.
  25. 2012.01.08 [캐싱] 웹사이트 캐싱전략
  26. 2012.01.08 [캐싱] 데이터 캐싱 Tips - Context.Cache
  27. 2012.01.08 [캐싱] 데이터 캐싱 - Response.Cache.XXX
  28. 2012.01.08 ASP.NET에서 오류 보고 페이지를 만드는 방법
  29. 2012.01.07 AJAX + JSON + ASMX & ASHX
  30. 2012.01.07 제네릭 처리기를 이용하여 자동가입방지 폼 구현
posted by 방랑군 2012. 1. 10. 03:13

안녕하세요. 코난 김대우 입니다.

이 개발 프레임워크 관련 내용은 http://kingcrap.com 블로그 장현춘님의 허락을 받고 가져온 글이며, 모든 저작권은 장현춘님께 있습니다. 
원본 출처 : http://kingcrap.com/entry/Framework-based-Development-적용


    
지난 포스팅에서는 프레임웍 기반 개발이라는 것이 개발자 영역에서의 자연스런 진화의 산물이며, 시장에 널려 있는 수많은 프레임웍 가운데 자사의 현실에 적합한 프레임웍들의 조합을 통해 프로젝트 전체를 관통하는 뼈대를 만들어 좀 더 나은 애플리케이션을 만드는 기법임을 알 수 있었다. 또한 이때 조합의 대상이 될 즉, candidate 프레임웍들로는 가급적 닷넷 개발 생태계의 산물인 오픈 프레임웍을 선정함이 바람직함을 얘기한 바 있다.

 

Framework-based Development – 개념 
Framework-based Development – 적용 
Framework-based Development – 종류 
Framework-based Development - 오픈 소스 적용 사례

 

이번 시간에는 프레임웍 기반 개발이라는 것이 일반적으로 어떠한 장점이 있는지, 그러한 것을 적용할 때 어떤 방법을 쓰는 것이 좋은지 살펴보도록 하자.

 

개발 프레임웍을 프로젝트에 도입하는 순간 기본적으로 프로젝트의 복잡성은 증가한다. 낯선 프레임웍에 대한 두려움과 새롭게 배워야하는 부담이 개발자들을 짓누르기도 한다. 라이브러리성 프레임웍의 경우 단순히 사용 방식을 익혀야 하는 수고가 더 든다는 정도에 그칠 수 있지만, 개발 프레임웍 즉, 애플리케이션의 컨트롤을 좌우하는 소위 Dependency Injection 등을 제공하는 컨테이너 형태의 프레임웍을 도입하게 되면 문제는 훨씬 복잡한 양상을 띈다. 늘 익숙한 방식의 직접 호출이 아닌 중간에 프레임웍이 위치하여 간접 호출이 일어난다는 것은 기본이고, 라이브러리를 사용할 경우 내가 주체가 되어 예측가능한 시간에 객체를 생성하고 예측가능한 방식으로 객체의 라이프싸이클을 관리할 수 있는 것과는 달리, DI 기능의 프레임웍을 도입할 경우 주객이 전도된다. 이것을 Inversion of Control이라고 부른다. 즉, 일단 DI 컨테이너로 넘어간 컨트롤은 내가 짠 코드와 무관하게 잘 짜여진 프레임웍의 규칙에 의거하여 진행하며 내가 짠 코드는 프레임웍이 정한 룰에 의해 필요시 불리어 객체가 생성되고 관리되며 소멸된다. 흔히 말하는 라이브러리성 프레임웍이 아닌 개발 프레임웍들을 도입하게 되면 일정정도 Inversion of Control이 일어나게 된다. 이 또한 처음 프레임웍을 접할 때 익숙치 않은 경험이 되며 직관적이지 않고 수많은 설정과 장치들을 파악하는 수고들이 번거롭게 느껴지기도 한다. 이렇듯 언뜻 보기에 프로젝트의 복잡성을 증가시키고 참여 인력들에게 낯선 것에 대한 두려움과 학습의 번거로움을 선사하는 프레임웍을 도입하면 어떠한 장점이 있을까 ?

 

clip_image001_98a7a532-42e5-4a33-8d9e-498de0cf28d8.png

오픈 프레임웍의 경우 시장에서 수많은 프로젝트라는 담금질을 거치면서 scalability, managebility, maintainability, performance 등등의 비기능적 요구사항들은 일정수준 이상의 수준에 도달하게 되고, 프레임웍이 제공하는 정형화된 호출 패턴을 준수하게 되어 코드가 일관성 있게 작성 유지되는 장점이 있다. 또한 프로젝트 규모가 커질수록 참여하는 조직이 다양해지고 참여 인력의 기술 수준 또한 다양할 수 밖에 없는데, 이처럼 다양한 수준의 개발자들에게 각종 품질 요소와 관련된 것들을 맡기는 것이 아니라 대부분을 프레임웍에게 맡겨 처리하게 함으로써 일정 수준 이상의 품질을 보장할 수 있게 된다. 반제품화된 프레임웍의 특성상 개발 기간 및 비용을 절감할 수 있으며, 참여 인력의 만족도 또한 증가하게 된다. 언뜻 이해되지 않는 대목일 수도 있으나 처음 프레임웍을 접하고 낯설었지만 개발에 적용하면서 익숙해져 결국 프로젝트가 끝날 무렵에는 이 큰 프로젝트에 시장에서 de-facto standard로 받아들여지는 프레임웍을 적용하여 개발했다는 자신감을 갖게되며, 또한 개인 이력서에도 멋지게 한 줄 올릴 수 있다. 닷넷에서는 아직 낯선 풍경이겠으나 자바 진영의 구인란을 보면 예를 들어, Struts+Spring+Hibernate 경험자 우대 등의 구체적인 프레임웍 경험을 중시하는 구인 광고를 흔히 볼 수 있다.

 

잠시 쉬어가는 코너로 오픈 프레임웍에 대해 거부감이 있는 독자를 위해 예전에 겪었던 경험을 잠시 써 보면... 
대략 4년 전쯤, 대법원이 국내 굴지의 SI 업체가 개발중이었던 시스템에 대해 Architecture Assessment를 한국 썬에 요청한 적이 있었다. 썬은 호주의 아키텍트 두 명과 국내 컨설턴트 두명(그중 하나 필자)을 파견하여 SI 업체가 개발 중인 시스템을 분석하고 참여자들과의 인터뷰를 통해 보고서를 제출하였다. 많은 지적 사항 가운데 프레임웍 관련된 부분만을 언급하면... 
SI 업체가 만들어 유지 보수하며 다년간 많은 프로젝트에서 사용하고 있는 자체 개발 프레임웍을 쓰지 말고 가급적 오픈 소스 기반의 프레임웍을 쓸 것을 추천하였다. 아이러니한 것은 그 당시 썬은 자사 상용 프레임웍인 Sun One Application Framework (“JATO”)를 팔고 있을 때였는데, 썬 직원이 아무런 주저없이 자사 솔루션이 아닌 오픈 소스 프레임웍을 추천하고 돌아간 것이다.....

 

시장에서 널리 쓰이는 프레임웍들을 조합하여 프로젝트의 전체 뼈대를 만들고자 할 경우 어떤 접근 방식을 취하는 것이 좋을까 ? 프로젝트가 시작되면 기본적으로 통합팀을 중심으로 각종 가이드가 만들어지고 참여 인력에 대한 각종 교육이 진행된다. 가령 단순하게는 naming convetion에서 방법론이라든지 신기술이라든지 적용할 프레임웍에 이르기까지... 
낯설지만 시장에서 각광받는 프레임웍들을 조합하여 진행할 때, 참여 인력 모두가 프레임웍에 대해 전문가가 될 필요는 없다. 아니 그럴 수도 없다. 많은 경우 함께 공부해가면서 책에 나와 있는 예제 중심으로 코드를 만드는데, 시일도 오래 걸리거니와 자칫 사소한(?) 것에 발목잡혀 낭패를 볼 수도 있다. 추천하는 것은 가급적 프로젝트 진행하는 팀 내에는 해당 프레임웍에 대한 전문가가 최소 한명이 있어야 한다. 이유는 프레임웍이라는 것이 개발 생태계에서 진화를 하면서 소위 “By Design”이라는 형태의 제약이나 의도된 설계가 있기 마련이다. 참여 인력 모두가 이런 것까지 학습할 시간적 여유가 없으며 누군가는 이러한 것들을 고려하여 개발자들이 사용할 가이드를 만들어 배포하여야 한다. 개발자에게 배포되는 가이드는 많은 것들을 고려하여 작성되었겠지만 실제 개발자에게 전달할 메시지는 아주 단순한 형태이어야 한다. 가령 개발 3단계, 첫째 맡고 있는 Use Case에서 추출한 명사로부터 대문자로 시작하는 클래스를 만들되 통합팀에서 배포한 BaseXXX를 상속받아 작성하고 둘째 반드시 XXX() 메소드를 오버라이드한다. 셋째 컴파일 한 후 특정 위치에 복사한 후 주어진 설정 파일에 등록하면 된다. 사용할 수 있는 소스 코드 탬플릿 양식과 샘플은 형상 관리 도구의 특정 branch에 있으니 참고하라는 식의... 물론 개발자들이 개발 과정에서의 갖게 되는 의문을 풀어주고 이해를 돕기위해 아키텍처 문서나 프레임웍 동작 원리 등을 제공하여 프로젝트를 거치면서 개발자들의 자연스런 성장을 돕는 것도 필요하다.

 

잠시 또 사례를 들면, 프레임웍에 대한 전문 인력이 없이 개발자들이 학습과 개발을 병행하며 프로젝트를 진행할때 발생했던 사례로써 역시 굴지의 국내 또 다른 SI 업체의 자바 솔루션 개발 경우이다.    
그룹사 전체에 특정 LOB 애플리케이션을 공급하는 SI 업체는 새 버전에 이전과 달리 Struts이라는 자바 진영의 그 당시 de-facto standard로 통했던, 현재에도 가장 많이 쓰이는 MVC 프레임웍이기도 한 프레임웍을 도입하기로 하고 참여 인력 내에서 책을 구입하여 개발과 학습을 병행하였는데, 아키텍처 자문을 해주는 과정에서 한가지 단순하지만 중요한 실수를 발견할 수 있었다. Struts이 관리(?)되고 있는 Apache 재단의 홈페이지에도 나와 있는 아주 단순한 원칙, “Action” 클래스는 같은 URI 요청에 대해 singleton으로 동작한다는 사실을 모르고 클래스를 작성하였던 것이다. 하여 개인이 테스트 할때는 별 탈이 없었지만 동시에 요청이 들어오면 thread-safe하지 않은 행동을 보이고 있었던 것.... Struts의 히스토리를 보면 원래는 singleton이 아니었는데 중간에 왜 singleton으로 바꾸게 되었는지 설명해 놓은 대목이 있다. 이런 것을 모든 개발자가 알 필요는 없지만 최소한 한 사람 누군가는 알고 이를 고려한 가이드나 설계가 제시되고 이를 통해 쓸데없이 시간과 정력이 낭비되는 것을 막아야 한다.

 

이런 유사한 사례는 신기술 혹은 새로운 프레임웍을 적용할 경우 흔히 볼 수 있다. 
다음 시간에는 현재 닷넷 개발 생태계내에서 만들어지고 발전되어 가고 있는 오픈 프레임웍들을 살펴보고 어떠한 것들이 시장에서 각광을 받고 있는지 함께 알아보는 시간이 되었으면 한다.

 

clip_image002_f4c091c4-816c-4caf-bda4-f38c530cb7b1.png

또한 참고로 예전 포스팅에서 정리했던 닷넷 개발 프레임웍 리스트를 보는 것도 도움이 될 것으로 생각한다.

 

[참고링크]

Framework-based Development - 개념

Framework-based Development - 적용

Framework-based Development - 종류

Framework-based Development - 오픈 소스 적용 사례

 


'PP > Framework' 카테고리의 다른 글

Framework-based Development - 오픈 소스 적용 사례  (0) 2012.01.10
Framework-based Development - 종류  (0) 2012.01.10
Framework-based Development - 개념  (0) 2012.01.10
닷넷 관련 개발 프레임워크  (0) 2012.01.10
자료들..  (0) 2012.01.04
posted by 방랑군 2012. 1. 10. 03:09

출처 :   http://www.sqler.com/bDevelopmentFramework/375059 

안녕하세요. 코난 김대우 입니다.

이 개발 프레임워크 관련 내용은 http://kingcrap.com 블로그 장현춘님의 허락을 받고 가져온 글이며, 모든 저작권은 장현춘님께 있습니다. 
원본 출처 : http://kingcrap.com/entry/Framework-based-Development 

 

 

프레임웍 기반 개발이라는 것은 말 그대로 엔터프라이즈 애플리케이션을 개발함에 있어서 기존에 만들어진 프레임웍의 조합을 통해 좀 더 빼르고 견고하게 원하는 결과물을 만들어 내는 것을 말하며, 이는 어느 특정 벤더의 개발 방법론도 아니고 개발 영역에서 자연스럽게 발전하여 체득된 개발 방식이다. SI 경험이 많은 대부분의 기업에게는 기업용 애플리케이션 개발에 있어서 경험으로 부터 다듬어져 프레임웍의 형태를 띄는 것들을 가지고 있다. 추상화 혹은 모듈화 정도의 차이가 있을 뿐, 혹은 대외적으로 홍보하는 이름이 있고 없을 뿐 대부분의 개발이 프레임웍 기반으로 진행되고 있다고 봐도 무방하다.

 

향후 몇 번에 걸쳐 프레임웍 기반 개발에 대해 살펴보기로 하자

Framework-based Development – 개념 
Framework-based Development – 적용 
Framework-based Development – 종류 
Framework-based Development - 오픈 소스 적용 사례

 

clip_image001_473d7c64-904a-4ce9-85ee-1d6a9b41885b.png

이처럼 많은 개발사 혹은 개발자들이 경험으로부터 선호하게 되는 프레임웍이라 것은 선조 프로그래머들의 지혜를 재활용하는 많은 방법 중에서 가장 개발자에게 직관적이고 현실적인 재사용 수단이다. 즉, 남들이 만들어 시장에서 다양한 곳에 적용되어 능력을 검증 받은 코드셋을 가져다 내 환경에, 나의 프로젝트에 맞게 약간의 변형을 가하고 설정을 변경하여 재사용할 수 있는 잘 만들어진 클래스 집합인 것이다. 프레임웍을 분류하는 방식은 프레임웍의 정의만큼이나 다양하나 일반적으로 블랙 박스 vs 화이트 박스 혹은 라이브러리성 vs 개발 프레임웍(컨트롤) 혹은 아주 간단하고 자주 쓰이는 오픈 (오픈 소스) vs 상용 프레임웍 등이 있다.

 

프레임웍 기반 개발이라는 것은 상용이든 오픈이든 용도에 맞는 가장 적절한 프레임웍들의 조합을 통해 전체 프로젝트를 관통하여 사용될 뼈대를 완성하고 개발자들로 하여금 비지니스 로직을 구현하여 이 뼈대가 제시하는 Contract에 맞게끔 개발하도록 만드는 정형화된 개발 방식이다. 이렇게 시장에서 검증된 프레임웍들의 조합을 통해 자연스럽게 흔히 얘기하는 비기능적 요구사항 (소위 QoS 요소)들을 달성하고 개발자들은 주어진 도메인에 집중하여 고객에게 전달할 가치 (기능적 요구 사항 포함)를 창출하도록 만드는 것이다. 이를 통해 개발자들의 창의성과 생산성을 기반 프레임웍 개발에 쓰여 낭비하지 않도록 하며 좀 더 나은 고객 가치를 전달하는데 사용케하자는 것이다.

 

여기서 생각해 볼 문제는 과연 어떤 프레임웍들을 조합의 대상으로 삼을 것인가 하는 점이다. 이 점에서 많은 부분 동의하지 못하는 분들도 있을 것 같은데, 필자는 가급적 오픈 (혹은 오픈 소스) 기반의 범용 개발 프레임웍들을 조합하길 권장하는 바이다. 흔히 말하는 범용 개발 프레임웍은 말 그대로 도메인에 특화된 로직을 품고 있지 않아서 대부분의 프로젝트에 쓰일 수 있는 기본 기능을 담고 있는 것들이다.

가령 로깅, 에러 처리등의 라이브러리들을 포함하여 객체 라이프 싸이클 관리, 모니터링 혹은 다른 레이어와의 인터페이스 모듈 등등 모든 프로젝트에서 항상 고민하는 것들이 포함된다. 세상에는 이미 나 혹은 내가 속한 팀, 더 나아가 우리 회사가 만들어 자랑스럽게 내세우는 프레임웍 보다 더 훨씬 더 잘 만들어 공개되어 우리 회사가 10년 아니 우리 회사가 망할때 까지 수행해도 다 못할 만큼의 전세계 수많은 프로젝트에서 다양한 환경에서 검증되어 발전해가는 즉, 닷넷의 개발 생태계 내에서 태어나 성장하는 뛰어난 범용 개발 프레임웍들이 널려 있다. 이제는 이러한 것들을 함께 공유하고 이러한 개발 생태계내에 우리도 일원으로 참여하여 생태계를 키우고 그로 인한 열매를 함께 향유하는 것이 필요하다.

 

오해하지 말 것은 필자가 범용 개발 프레임웍이라고 칭하는 부분이다. 도메인에 특화된 비지니스 프레임웍들을 여전히 상용으로 판매되고 있다. 가령 금융 패키지 혹은 코어 뱅킹, 제조 패키지 등등 도메인에 특화되어 있기에 닷넷에 대한 개발 노하우가 있다고 누구나 만들 수 있는 것도 아니며 도메인 지식이 풍부해야 진입할 수 있는 영역이기에 개발 생태계가 관장하기에는 아직 닷넷 개발 생태계가 성장하기 못한 면이 있다. 하지만 마음만 먹으면 누구나 만들 수 있는 범용 개발 프레임웍은 사정이 다르다. 전세계가 유사한 기능을 하는 비슷비슷한 프레임웍이 나타나는 이유는 간단하다. “난 쟤들 거 이런 이런 점이 맘에 안들어...” 이거다. 이렇게 만들어진 것이 대중의 사랑을 받게 되면 개발 프레임웍에 있어 de-facto standard로 자리잡아 칭송을 받게 되는 것이다.

 

고객이 입장에서 보면 오픈을 써야하는 이유는 더 극명하다. 벤더 종속적인 프레임웍을 도입하였을 경우 기반이 되는 .NET의 발전에 맞추어 유지보수해야 하는 문제며, 소스 코드를 포함한 소유권 문제 등도 있고, 프레임웍 개발사가 증명할 수 있는 각종 QoS 수준과 전세계 닷넷 개발 생태계가 증명할 수 있는 수준과의 신뢰성 등 고객은 이미 오픈 혹은 오픈 소스에 대해 많은 것을 알고 있다. 개발자들의 자유로운 접근과 사용, 그리고 그 과정에서 주고 받는 Q&A 및 피드백을 통해 오픈 프레임웍은 자연스럽게 생태계속에 편입되어 발전하게 되는 것이다.

 

다음 시간에는 현재 우리가 사용할 수 있는 프레임웍들에는 어떤 것이 있고 어떤 점을 고려하여 선정하여야 하는지 더 나아가 적용할 때 고민해야 할 부분등에 대해 함께 알아보도록 하자.

 

clip_image002_4b15f2f2-fd45-40a1-b9f7-146ed7230ce0.png

 

 

[참고링크] 

Framework-based Development - 개념

Framework-based Development - 적용

Framework-based Development - 종류

Framework-based Development - 오픈 소스 적용 사례

  

'PP > Framework' 카테고리의 다른 글

Framework-based Development - 종류  (0) 2012.01.10
Framework-based Development - 적용  (0) 2012.01.10
닷넷 관련 개발 프레임워크  (0) 2012.01.10
자료들..  (0) 2012.01.04
프레임워크를 이해하기 위한 패턴 언어  (0) 2012.01.04
posted by 방랑군 2012. 1. 10. 03:09

출처 :  http://www.sqler.com/bDevelopmentFramework/375007 

안녕하세요. 코난 김대우 입니다.

이 개발 프레임워크 관련 내용은 http://kingcrap.com 블로그 장현춘님의 허락을 받고 가져온 글이며, 모든 저작권은 장현춘님께 있습니다.
원본 출처 : http://kingcrap.com/entry/닷넷-관련-개발-프레임웍-Beta

일부 내용에 변경이 있는 부분은 명시 후 수정합니다.

 

 

 

닷넷 프로젝트에서 사용할 수 있는 프레임웍을 한눈에 볼 수 있도록 정리해보자 
프레임웍을 구분하는 방법은 여러가지이나 간단하게 티어별로 구분하도록 한다. 

프리젠테이션 티어 (웹) 
1. ASP.NET MVC - ASP.NET 기반의 MVC 프레임웍. 마이크로소프트 제공 
2. MonoRail - 오픈 소스 Castle 프로젝트에서 만든 Rail와 유사한 MVC 웹 프로임웍 
3. Maverick.NET - 자바 Maverick의 닷넷 버전으로 오픈 소스 MVC 웹 프레임웍, 업데이트 안됨 
4. DotNetNuke - 포털 프레임웍에 가까움. 오픈 소스 

비지니스 티어 (DI Container) 
1. Spring.NET - 오픈 소스. 자바 Spring의 닷넷 버전. 대표적인 DI Container. 
2. ObjectBuilder - Enterprise Library(EntLib)에 들어 있으며, EntLib, Composite UI Application Block 등에 사용된 DI Container 
3. Unity - Enterprise Library 4.0 버전에 사용될 DI Container로 ObjectBuilder 후속작. EL과 별개로 사용될 수 있도록 별도 프로젝트로 진행중이며 Codeplex에 현재 2008년 2월 CTP 공개. 
4. Windsor Container - 오픈 소스 Castle 프로젝트 일환 
5. StructureMap - 닷넷에서 가장 오래된 DI Container. Jeremy D. Miller가 만들고 유지보수하고 있는 오픈 소스 프레임웍
6. NInject - "Lightning-fast dependency injection for .net"을 표방한 오픈 소스 DI Container. 닷넷 프레임웍 3.5 및 Compact Framework 3.5 지원, Silverlight 지원 등이 특징

데이터 티어 
1. ADO.NET 
2. LINQ to SQL - .NET Framework 3.5 이상의 기본 기능(2011년 5월 현재 4.0). 엔티티와 테이블의 1:1 매핑. VS2008 이상 툴 지원 
3. ADO.NET Entity Framework (LINQ to Entity) 
4. NHibernate - 자바 Hibernate의 닷넷 버전. 오픈 소스 
5. iBatis.NET - 자바 iBatis의 닷넷 버전. 오픈 소스 
6. Active Record - 오픈 소스 Castle 프로젝트의 일환. Active Record 패턴을 구현. NHibernate 기반이나 Configuration을 XML이 아닌 Attribute을 이용 
7. LLBLGen Pro - 상용. 
8. WilsonORMapper - 상용. 
9. LightSpeed - 상용. 
10. Codus - 상용. 
11. Sooda - 폴란드에서 만든 오픈 소스 ORM 으로 폴란드에서는 구직시 도움되는 기술. 
12. SubSonic - 오픈 소스 ORM. ASP.NET 3.5 Extension에 포함된 ASP.NET Dynamic Data 기능 구현에 사용됨.
13. NConstruct - 상용 / 무료, NHibernate 용 코드 자동 생성(HBM, Entity 등), VS용 project 파일 생성 등

All-in-one
1. DotNetNuke - 복잡한 웹 싸이트 구축, CMS에 까깝다고 할 수 있음
2. Oxite - ASP.NET MVC를 사용, 블로그 엔진, Mix Online 싸이트 운영

기타 범용 프레임웍 (혹은 라이브러리) 
1. Enterprise Library - MS patterns and practices(PnP) 팀이 Codeplex를 통해 제공. 캐싱, 로깅, 암호화 등등 
2. NVelocity - 템플릿 엔진. 진전이 없어 Castle 프로젝트에서 별도 진행 
3. NUnit - 단위 테스트 
4. NAnt - 빌드 
5. log4net - 로깅 

6. CruiseControl.NET - 통합 빌드, ThoughtWorks에서 개발한 오픈 소스 

'PP > Framework' 카테고리의 다른 글

Framework-based Development - 적용  (0) 2012.01.10
Framework-based Development - 개념  (0) 2012.01.10
자료들..  (0) 2012.01.04
프레임워크를 이해하기 위한 패턴 언어  (0) 2012.01.04
프레임워크 리팩토링 정리  (0) 2012.01.04

DI

posted by 방랑군 2012. 1. 10. 00:06

spring.NET

스프링 닷넷은 자바 진영에서 매우 다양한 곳에서 쓰이고 있는 유명한 프레임워크 스프링의 닷넷 버전이다. 아래의 그림을 보면 알 수 있듯이 단순한 컨버젼이 아니라 스프링이 가지고 있는 개념을 닷넷에 가장 어울리도록 최적화한 것이라고 볼 수 있다.

springnet.png

여기서는 이런 다양한 스프링 닷넷 프레임워크 중 DI에 대해서 간략하게 알아보겠다.(이 부분은 코어에 소속된 부분이다. 즉 스프링의 다양한 개념 중에서도 매우 중요하며 기초적인 부분이다.)

DI

먼저 DI라는 개념을 먼저 파악해야 한다. DI는 Dependency Injection의 약자로서 번역하면 의존성 주입 정도가 된다. 간략하게 설명하자면 하나의 클래스에서 다른 클래스의 객체를 사용할 경우에 직접 객체를 생성해서 사용하지 않고 사전에 설정해 둔 바에 따라서 객체를 가져와 사용할 수 있게 한다는 개념이다.

이렇게 할 경우의 가장 큰 장점은 가져오는 객체의 구조나 생성방식이 바뀌더라도 설정파일을 바꾸는 것만으로 그에 무관하게 사용할 수 있다는 점이다.

아래의 간단한 예를 보면 쉽게 이해가 되리라 생각한다.


스프링 닷넷에서 DI의 사용

먼저 사전작업으로 Spring.Net 프레임워크를 다운받아 설치해두는 작업이 필요하다.(이는 스프링닷넷 프레임워크 사이트에서 다운받아 설치만 하면 되므로 생략)

그리고 Spring.Core 어셈블리 파일을 참조추가해둔다. 이로서 사전 작업은 끝

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Context;
using Spring.Context.Support;

namespace SpringNET
{
class Program
{
static void Main(string[] args)
{
IApplicationContext ctx = ContextRegistry.GetContext();
Hello hello = (Hello)ctx.GetObject("MyHello");
string name = "lee";
string result = hello.SayHello(name);
Console.WriteLine(result);
Console.Read();
}
}
class Hello
{
public string SayHello(string name)
{
return "Hello!, " + name;
}
}
}


위와 같이 소스코드를 하나 작성한다. 다른 부분은 간단하므로 설명하지 않고 DI가 실제로 일어나는 붉은 색부분만 설명하면 첫번째 줄은 현재 어셈블리의 설정파일로 부터(아래에 작성해 볼 것이다.) 어플리케이션 컨텍스트를 가져온다. 둘째줄은 가져온 컨텍스트에서 MyHello라는 이름의 Object를 가져오도록 하는 것이다.

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>

<spring>
<context>
<resource uri="config://spring/objects" />
</context>

<objects xmlns="http://www.springframework.net">

<object name="MyHello" type="SpringNET.Hello, SpringNET">
</object>
</objects>
</spring>
</configuration>


위의 파일은 해당 어셈블리의 설정파일과 같은 것이다. 여기에 스프링에 관한 설정도 넣을 수 있다.

다른 부분은 무시하고 핵심적인 부분만 설명하면 붉은 색의 코드 한 줄이 의존성 주입이 가능하도록 해주는 부분이다. 객체의 이름은 MyHello, 클래스형은 SpringNET.Hello이며 해당 객체가 들어있는 어셈블리의 이름은 SpringNET라는 이야기이다.

간단히 스프링 닷넷의 DI를 살펴보았다. 좀더 자세한 것은 스프링 닷넷의 다른 기능을 봐가며 살펴보도록 하겠다.


참고자료: spring-net-reference.pdf Spring.NET_guide_ensoa_v.0.2.pdf

'PP > SPRING.NET' 카테고리의 다른 글

일반 구성 설정(ASP.NET)  (0) 2012.01.13
Spring .Net 활용 가이드  (0) 2012.01.12
서론.  (0) 2012.01.10
posted by 방랑군 2012. 1. 10. 00:00
출처 :   http://dncblog.tistory.com/53 

Spring은 이미 오래전부터 자바진영에서 각광받고 있는 프레임웤으로서, 닷넷버전으로도 공개가 되었습니다. 
그것이 바로, Spring.NET인데요,   
Spring.NET은 닷넷기반의 엔터프라이즈 어플리케이션을 구축하기 위한 어플리케이션 프레임웤  이라고 정의할 수 있습니다. 



Spring.NET의 각 모듈의 구성을 보시면, 하단 우측의 AOP 기반으로, ASP.NET,  Web Serivce, ORMapping, DataAccess, NUnit, Remoting, COM+ 등의 다양한 코어 모듈 기반의 프레임웤입니다. 

AOP(Aspected Oriented Programming) 란  관점 지향 프로그래밍이라고 해석되는데요, 
이는, 프로젝트를 진행할때,  개발자가 고민해야하는 비지니스 로직을 핵심관심사라 보고, 그외의 인증/권한/예외처리/로깅/트랜젝션관리 등에 대한 것을 횡단관심사로 보아, 관심의 분리를 일컷습니다. 
이는, 개발자는 핵심관심사에 치중하며, 횡단관심사는 프레임웤의 각 컨테이너가 제공을 해주게 됩니다. 
그리고 각 컨테이너는 IOC(Inversion Of Control) 형태로 구성되어있는데요,  
기존에 개발방법론에서는 작성되어있는 프레임웤은 Library로서의 기능이 강했습니다. 
개발자는  비지니스 로직에 집중하면서,  횡단 관심사에 대한 호출이 필요한 경우에는 작성되어있는 프레잌웤 라이브러리를 호출해서 사용하였었지요. 
그러나, IOC 형태로 구성된 컨테이너 들은  프레잌웤 코드가 전체 어플리케이션의 처리흐름을 제어하며, 특정한 이벤트가 발생할 시마다 다형성을 통해, 어플리케이션이 확장한 메소드를 호출함으로서, 결과적으로는 제어가 프레임웤에서 어플리케이션으로 거꾸로 흐르게 되는 방법을 말합니다. 
그리고 객체가 참조하고 있는 다른 객체를 스스로가 new로 create하지 않고, 인터페이스를 통해서 Assing받아 사용하는 방식을 따르고 있습니다.

[예제1]  
App.config 
    <objects xmlns="http://www.springframework.net" >
       <object id="MyHello" type="DI.Hello, DI"></object>
    </objects>

Interface 
    interface IHello
    {
        string sayHello(string str); 
    }

Class 
    class Hello : IHello
    {
        public string sayHello(string str)
        {
            return str; 
        }
    }

MainApp
        static void Main(string[] args)
        {
            IApplicationContext ctx = ContextRegistry.GetContext();  //app.config에 설정된 object를 가져옵니다. 
            IHello hello = (IHello) ctx.GetObject("MyHello"); //  MyHello object를 노출된 interface 를 통한 Assign 
            string str = "안녕";
            string result = hello.sayHello(str);  
            Console.WriteLine(result);
        }

MainApp에서 Hello 클래스의 객체를 직접 create하지 않고, IHello 인터페이스를 도입함으로서, MainApp와 Hello와의 종속성이 제거되었습니다.  여기서 Hello가 컴퍼넌트 역할을 하게됩니다.
configuration에 사용하고자 하는 컴퍼넌트를 명시하고,  MainApp에서는  해당 컴퍼넌트를 사용할수 있도록 interface를  제공한 것입니다. 
위와 같은 프로그래밍 모델을  IOC, DI 라고 부릅니다. 


Spring.NET에서는 AutoProxy기능이 지원되는데요,  이는 특정 메소드가 호출될때, configuration에 define된 룰에 따라, 메소드호출을 intercept하여, 흐름의 제어를 할수 있게 되는것입니다. 

[예제2]
 
 
Configuration
<!--AutoProxy 설정-->
      <object id="MyServiceCommand" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
        <property name="ObjectNames">
          <list>
            <value>K*</value>
          </list>
        </property>
        <property name="InterceptorNames">
          <list>
            <value>Interceptor</value>
          </list>
        </property>
      </object>
  <!-- Intercept시 호출된 클래스정보-->
  <object id="Interceptor" type="ConsoleApplication2.Interceptor, ConsoleApplication2"/>
  
 <!--Object-->
      <object id="English" type="ConsoleApplication2.HelloWorldSpeaker, ConsoleApplication2">
        <property name="Language" value="English"/>
      </object>
     <object id="Korean" type="ConsoleApplication2.HelloWorldSpeaker, ConsoleApplication2">
        <property name="Language" value="Korean"/>
      </object>
  
interface
    public interface IHelloWorldSpeaker
    {
        void SayHello();
    }

Class 
   public class HelloWorldSpeaker : IHelloWorldSpeaker
    {
       public void SayHello()
        {
            switch (language)
            {
                case Language.English:
                    Console.WriteLine("영어");
                    break;
                case Language.Korean:
                    Console.WriteLine("한국어");
                    break;
            }
        }
    }

Interceptor 
 public class Interceptor : IMethodInterceptor
    {
        public object Invoke(IMethodInvocation invocation)
        {
            Console.WriteLine("실행전");
            object rval = invocation.Proceed();
            Console.WriteLine("실행후");
            return rval;
        }
    }

또한 before/After/Around 등의 Advice를  configuration에 세팅하게되면, 메소드의 실행전후에 특정 흐름을 끼워넣을수도 있게 됩니다. 

Spring.NET에서는 Quart.NET을 이용한  스케줄러 구현을 지원합니다.일반적으로, 기존에 우리 스케줄러를 작성하기 위해서는 쓰레드개념을 생각 안할 수가 없는데요, 
이때, Threadpool을 관리함에 있어서 여러가지 고민해야될것들이 많았습니다 
Pool의 count , 객체 소멸시점, 특정 시간에만 동작하기 위한 Timer .. 외에도 여러가지 존재할것 같습니다. 
그렇다면, Spring.NET에서는 이 모든것들에 대해서 어떻게 구현하게 될까요.. 
이제부터 직접 스케줄러를 구현해 보도록 하겠습니다. 

1. configuration  
2. scheduler
3. trigger 
4. jobDetail 

configration을 작성해야 하는데요, 이는 app.config에 작성할 수도 있고, 따로 xml파일로 뺼수도 있습니다. 
configuration에는 스케줄에 해당하는 object와, 스케줄에 대한 반복적인 주기를 뜻하는 트리거, 그리고 마지막으로 각 트리거가 수행하는 Job에 대해서 명시해야합니다. 

[예제3]
 
Scheduler
<object id="quartzSchedulerFactory"  type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
    <property name="SchedulerName" value="quartz1"/>
    <property name="triggers">
      <list>
        <ref object="CronTrigger" />
        <ref object="SimpleTrigger" />
       </list>
    </property>
  </object>

Trigger  
<object id="SimpleTrigger"  type="Spring.Scheduling.Quartz.SimpleTriggerObject, Spring.Scheduling.Quartz">
    <!-- see the example of method invoking job above -->
    <property name="JobDetail" ref="SchedulerJob" />
    <!-- 10 seconds -->
    <property name="StartDelay" value="10s" />
    <!-- repeat every 10 seconds -->
    <property name="RepeatInterval" value="10s" />
  </object>
  <object id="CronTrigger" type="Spring.Scheduling.Quartz.CronTriggerObject, Spring.Scheduling.Quartz">
    <property name="JobDetail" ref="SchedulerJob" />
    <!-- 5초마다의 interval Fire -->
    <property name="CronExpressionString" value="0/5 * * * * ?" />
  </object>

Job
<object name="SchedulerJob" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
    <property name="JobType" value="Publisher.SchedulerJob, Publisher" />
    <property name="JobDataAsMap">
      <dictionary>
        <entry key="Timeout" value="5" />
       </dictionary>
    </property>
  </object>

모든 object는 Id(Name)와 Type을 지정해주어야합니다. 
그리고, 각 오브젝트마다 가지는 프로퍼티가 조금씩 다른데요, 
스케줄에서는 해당 스케줄에 대한 반복적인 주기를 뜻하는 트리거를 지정하게됩니다. 
저는 simpleTrigger와 cronTrigger라는 두개의 트리거를 지정했는데요,  몇분에 한번씩. 처럼 간단한 작업주기인경우에는 simpleTrigger를, 일중일 중에서 토/일을 제외한 매일 아침 10시부터 12시까지 20분간격으로. 라는 조금은 복잡해보이는 반복주기인경우에는 crontrigger를 사용하면 됩니다. 
그리고 각 트리거에서는 수행할  Job에 대해서 명시를 해야하는데요, 
JobType이라는 프로퍼티를 통해, 수행할 Task의 Type을 지정하게됩니다 Type은 어셈블리명, 네이스페이스명으로 지정하시면 됩니다.
위의 configration는 Publisher.SchedulerJob을 하나는 10초마다, 하나는 5초마다 반복 수행하는 스케줄러임을 알수 있게됩니다. 
config세팅이 끝나면, 이제 Publisher.SchedulerJob을 작성해 보겠습니다. 

[예제4]
 class SchedulerJob : QuartzJobObject
    {
        protected override void ExecuteInternal(JobExecutionContext context)
        {
                 Console.WriteLine("Excute..."); 
         }
    }


SchedulerJob은 QuartzJobObject를  상속받아, 예약되어있는 ExecuteInternal메소드를 오버라이딩 하면 됩니다 
파라메터인 JobExecutionContext타입의 context에는 configration에서 작성한 해당 Job의 정보를 모두 알 수 있습니다. 
위와 같이 QuartzJobObject를 상속하여, Job을 수행하는 방식 외에, 직접 TargetMethod를 지정할 수도 있습니다.

스케줄 트리Listener를 등록해 놓으면, 트리거가 Fire될때, 혹은 misFire되거나 실행이 완료되었을때의 이벤트를 Listen할 수가 있습니다.

[예제5]
   
 public class TriggerListener : ITriggerListener
    {
        
public void TriggerFired(Trigger trigger, JobExecutionContext context)
        {
            Console.WriteLine("TriggerFired");
        }

         public void TriggerMisfired(Trigger trigger)
        {
            Console.WriteLine("TriggerMisfired");
        }

        public void TriggerComplete(Trigger trigger, JobExecutionContext context,
                                    SchedulerInstruction triggerInstructionCode)
        {
            Console.WriteLine("TriggerComplete");
        }
    }

작성된 스케줄러를 실행시켜보겠습니다. 
[실행결과]

5초마다 Crontrigger가, 10초마다 simpleTrigger가 수행되고 있으며, 각 이벤트가 Fire될때마다 Trigger를 Listen하고 있습니다.

지금까지 간략하게나마, Spring.NET을 이용하여 스케줄러를 만들어 보았는데요,, 
잘 동작하네요 :)  

읽어주셔서 감사합니다.   

'PP > SPRING.NET' 카테고리의 다른 글

일반 구성 설정(ASP.NET)  (0) 2012.01.13
Spring .Net 활용 가이드  (0) 2012.01.12
DI  (0) 2012.01.10
posted by 방랑군 2012. 1. 9. 03:00

상품등록 화면을 ajax로 처리하다 보니
데이터의 자료구조를 잘 만들어야 할 필요가 있다.

그래서 json 의 사용..

배열과 크게 다를건 없지만 걍 객체지향 냄새가 좀더 난다는거..
그리고 배열 요소(인덱스) 처리하느라 골머리 썩지 않는 점은 참 좋다. 직관적이기도 하고..

그런데 json 데이터를 객체화 하기 위해 자바스크립트의 eval! 메소드를 사용해야 하는데..

이게 악성코드를 실행시킬 위험이 있단다.

그래서

json.org/json2.js 배포파일이 필요하게 됬다.

더 상세한건
http://blog.outsider.ne.kr/257 요분의 포스팅이 참 도움이 된다.
땡큐베리 감사...

어찌됬든
eval!(o.responseText) 가 아닌 JSON.parse(o.responseText)로 객체화 하자

'PP > JSON' 카테고리의 다른 글

JSON Text를 JSON Object로 변환하기  (0) 2012.01.09
Json / JQuery (Ajax)/ Asp.net 3가지를 연동하여 데이터 가져오기  (0) 2012.01.07
JSON 개요 및 예제  (0) 2012.01.04
DATASET - > JSON  (1) 2012.01.04
JSON.NET  (0) 2012.01.04
posted by 방랑군 2012. 1. 9. 02:59
JSON 은 써보면 써볼수록 유용한 것 같다. 간결하고 편하고 직관적이다. 어쨌든 JSON Text를 Object로 변환해야 할 때가 있다. 여기서 JSON Text라는 것은 형태는 JSON의 형태이지만 자바스크립트에서 이걸 Object가 아닌 그냥 텍스트로만 인식하고 있다는 것이다. 이걸 Object로 바꾸어야만 그안의 값을 불러다가 사용할 수 있다.

가장 흔한 예가 Ajax를 사용할 경우이다. Ajax로 호출을 하고 결과값으로 받은 req.responseText로 JSON을 받았을 경우에는 그냥 Text이기 때문에 Object로 변환해 주어야 한다.

{ id:'Outsider', sex:'male' }

Ajax에서 리턴받을 JSON의 형태가 위와 같이 되어 있을 경우에는 

?
1
2
var obj = eval("("+returnValue.responseText+")");
alert(obj.id);  // Outsider

위의 코드처럼 eval을 해주면 JSON 오브젝트로 변환할 수 있다.

[ { id:'Outsider', sex:'male' },
  { id:'Zziuni', sex:'male' } ]

JSON이 위의 형태처럼 배열로 되어 있을 경우에는

?
1
2
var obj = eval(returnValue.responseText);
// -> { id:"Outsider", sex:"male" }

그냥 eval을 해주면 JSON 오브젝트로 변환할 수 있다.

다만 이렇게 변환할 경우 eval()은 빠르기는 하지만 단순히 그안의 스트링을 그대로 실행시켜 주는 것이기 때문에 리턴값으로 자바스크립트 명령문이 온다면 그대로 실행시켜버리기 때문에 보안이슈가 발생할 수 있다.  

이렇게 리턴받은 소스를 신뢰하기 어려울 때는 JSON.org 에서 제공하는 JSON parser을 사용해야 한다. JSON parser는 오직 JSON text만 받아들이고 다른 스크립트는 거부하고 eval()만큼이나 빠르다.

?
1
2
var obj = JSON.parse(returnValue.responseText);
// -> { id:"Outsider", sex:"male" }

JSON.parse()의 목적대로 JSON 텍스트 외에는 거부해야하기 때문에 JSON문법을 정확히 지켜주지 않으면 SyntaxError 예외가 던져진다. 그렇기 때문에 키와 값을 모두 쌍따옴표(")로 묶어주는 문법을 정확하게 지켜주어야 한다.(물론 이 경우는 값들이 스트링이기 때문에 쌍따옴표로 묶어주는 것입니다.) 아래처럼....

{ "id":"outsider", "sex":"male" }

여기서 JSON.parse()를 사용하기 위해서는 Douglas Crockford 가 만든 json2.js 가 필요하다. json2.js는 더글라스 크록포드가 JSON의 편리한 사용을 위해 만든 JSON API의 새버전이다.(그래서 2가 붙어있다.) 이 API에는 2개의 메서드가 들어있는데 JSON.stringify()와 JSON.parse()이다. JSON.stringify()는 JSON.parse()와는 완전히 반대로 JSON 객체를 주면 JSON 텍스트로 만들어서 준다. 필요할때 갖다 쓰면 된다. (John Resig 이 이전버전보다 새버전의 API가 훨씬 좋다고 꼭 이걸 쓰란다.)

'PP > JSON' 카테고리의 다른 글

JSON 의 eval() 함수 사용의 문제  (0) 2012.01.09
Json / JQuery (Ajax)/ Asp.net 3가지를 연동하여 데이터 가져오기  (0) 2012.01.07
JSON 개요 및 예제  (0) 2012.01.04
DATASET - > JSON  (1) 2012.01.04
JSON.NET  (0) 2012.01.04
posted by 방랑군 2012. 1. 8. 21:36

출처 : http://snowple.tistory.com/355

+ 이벤트 등록(live)
.live() 은 .bind()를 기초로 엘리먼트에 이벤트 핸들러 함수를 연결할 때 몇가지 기능을 추가한 함수.
보통 Ajax등으로 동적으로 생성된 엘리먼트에 대해서는 .bind()함수를 통해 이벤트를 추가해 주지 못한다. 따라서 live() 함수는 동적으로 생성된 엘리먼트에 대해서도 이벤트를 추가해 주는 기능을 가지고 있다.

$('#id').live('click', function(e) {

/* TODO */

});


등록할 수 있는 이벤트 타입
- click
- dblclick
- keydown
- keypress
- keyup
- mousedown
- mousemove
- mouseout
- mouseover
- mouseup


+ 이벤트 등록(bind)

$('#id').bind('click', function(e) {

/* TODO */

});




jQuery 셀렉터 정리


+ 선택

$('div') /* 문서 안의 모든 div를 선택 */
$('#myid') /* id="myid" 인 유일한 엘리먼트를 선택 */
$('.myclass') /* 클래스가 class="myclass" 인 엘리먼트를 선택 */
$('p#myid') /* id가 myid 이면서 p 태그인 유일한 엘리먼트를 선택 */
$('a img') /* <a> 엘리먼트의 하위 엘리먼트들 중에서 <img> 를 가진 엘리먼트를 선택 */
$('#main p') /* id가 main인 하위 엘리먼트들 중에서 <p> 태그를 가진 엘리먼트를 선택 */
$('li > ul') /* <li> 엘리먼트의 하위 엘리먼트들 중에서 <ul>인 엘리먼트들을 선택 */
$('[name=myname]') /* name의 속성값이 myname인 엘리먼트를 선택 */
$('a[href=address]') /* <a>를 가진 엘리먼트에서 속성 href가 address인 것을 선택 */



+ 폼 셀렉터

$(':input') /* 모든 폼 엘리먼트(<input>, <select>, <textarea>, <button>)을 선택 */
$(':text') /* 모든 텍스트 필드(<input type="text">) 를 선택한다. */
$(':radio') /* 모든 라디오버튼 필드(<input type="radio">) 를 선택한다. */
$(':checkbox') /* 모든 체크박스 필드(<input type="checkbox">) 를 선택한다. */
$(':checked') /* 체크된 체크박스 또는 라디오버튼 엘리먼트를 선택 */



+ 사용자 정의 셀렉터

$('li').filter(':even').css('background-color', 'red') /* <li> 태그 중에서 짝수번째 라인은 빨간색 배경 지정 */
$('li:eq(2)') /* 3번째 <li>를 선택 */
$('.myclass:eq(1)') /* 클래스명이 myclass인 엘리먼트 가운데 2번째 엘리먼트를 선택 */
$('li').eq(2).css('background-color', 'red') /* <li> 태그중에서 2번째 태그에 배경을 빨간색을 지정 */



+ 찾기

$('#conditions').find('li') /* id가 conditions인 하위 모든 엘리먼트들 중에서 <li> 태그를 가진 것 선택 */
$('li').prev() / $('li').prevAll()
$('li').next() / $('li').nextAll()



+ 체크박스의 값을 콤마(,)로 만들기

$(':checkbox').map(function() {

return this.id;

}).get().join(',');
>> 4,5,8




DOM 처리


+ 기본속성 설정

$('#check_input').attr('checked', false) /* 체크해제 */
$('#check_input').attr('title', 'mytitle') /* id가 check_input인 엘리먼트의 title 속성을 "mytitle"로 변경 */
$('#check_input').attr({

alt: 'test',
title: 'test'

});
if ($('#save').prop('checked') == true) {

/* id가 save인 엘리먼트가 체크된 상태 */

}
.width() /* 길이 설정 */



+ 객체 생성

var odv = $(document.createElement('div'));
odv.attr('id', 'test');
odv.addClass('ui-state-condition');



+ 입력과 선택

.html()
.text()
.val()

$('input:text.item').val(function() {

return this.value;

});
.index() /* 몇번째 엘리먼트인지 숫자로 반환 */




AJAX


+ ajax

$.ajax({

type: "POST",

url: "histogram.php",
data: {key : value, key1: value1},
dataType: "html",
beforeSend: function() { },
success: function(res, textStatus) {

$('#id').html(res);

}

});



+ load

$('#id').load('condition.php', {key: value, key1: value1}, function() {

/* 로딩 성공했을 때 */

}); 
posted by 방랑군 2012. 1. 8. 21:28
1. jQuery 개요
라이브러리다운로드 - www.JQuery.com
특징 : DOM 엘리먼트 셀렉터
       DOM : HTML, XML을 제어
       Ajax지원
       Plugin 지원
       단순화된 이벤트처리
       브라우저별 호환성


사용법
헤드태그안에 삽입
<script type="text/javascript" src="<%=cp%>/data/js/jquery-1.6.2.min.js"></script>
//src=라이브러리를 추가한 곳
<script type="text/javascript">
//작성

</script>






2. Core

태그접근 : $("a"), $("div")
클래스접근 : $(".클래스명), $("태그.클래스명")
ID접근 : $("#id")   ---> document.getElementById("id")  와 같음
중첩구조 : $("#id").find("li") => $("#id li")으로 가능



3. Selectors(선택자)

기본선택자
* 모든 요소와 매칭
E 모든 E요소와 매칭
E F E의 자손이고 F인 요소와 매칭
E>F E의 자식이고 F인 요소와 매칭
E+F E의 바로 다음형제인 F요소와 매칭
E~F E가 바로 이전형제인 F요소와 매칭
E:has(F) F를 최소 하나의 자손으로 가지고 있는 E요소와 매칭
E.c c라는 클래스를 가진 E요소와 매칭 (*.c나 .c와 같음)
E#i i라는 아이디를 가진 E요소와 매칭 (*#i나 #i와 같음)
E[@a]
a라는 속성을 가진 E요소와 매칭
E[@a=v] a속성값이 v인 E요소와 매칭
E[@a^=v]  a속성값이 v로 시작하는 E요소와 매칭
E[@a$=v] a속성값이 v로 끝나는 E요소와 매칭
E[@a*=v] a속성값이 v를 포함하는 E요소와 매칭

위치형선택자 : 기본선택자뒤에 쓰인다.
B:first 첫번째 B요소와 매칭
B:last 마지막 B요소와 매칭
B:first-child 첫번째 B요소와 매칭
B:last-child 마지막 B요소와 매칭
B:only-child B요소가 하나일 경우 B요소와 매칭
B:nth-child(n) n번째 B요소와 매칭(n:one-based)
B:nth-child(odd|even) 홀/짝수 B요소와 매칭
B:nth-child(Xn+Y) X배수 + Y인 B요소와 매칭(n:zero-based)
B:even 짝수 B요소와 매칭
B:odd 홀수 B요소와 매칭
B:eq(n) n+1번째 B요소와 매칭(n:zeno-based)
B:gt(n) n+1번째 초과 B요소와 매칭
B:lt(n) n이하 B요소와 매칭


사용자정의형 선택자
B:animated jQuery 애니메이션 메서드로 애니메이션이 활성화된 B요소와 매칭
B:button 버튼 형태(button, input[@type=submit], input[@type=reset], input[@type=button])의 B요소와 매칭
B:checkbox input[@type=checkbox]인 B요소와 매칭
B:enabled 활성화 상태인 B요소와 매칭
B:file input[@type=file]인 B요소와 매칭
B:header h1~h6인 B요소와 매칭
B:hidden 비가시 상태 또는 input[@type=hidden]인 B요소와 매칭
B:image input[@type=image]인 B요소와 매칭
B:input 입력 요소(input, select, textarea)인 B요소와 매칭
B:not(f) :(콜론)으로 시작하는 f를 제외한 B요소와 매칭
B:parent 자식요소가 있는 B요소와 매칭
B:password input[@type=password]인 B요소와 매칭
B:radio input[@type=radio]인 B요소와 매칭
B:reset input[@type=reset]인 B요소와 매칭
B:selected option요소 중 현재 선택된 B인요소와 매칭
B:submit input[@type=submit]인 B요소와 매칭
B:text input[@type=text]인 B요소와 매칭
B:visible 가시 상태인 B요소와 매칭


 ###$( html ) 
    태그를 바디안에 삽입하기
       $("<div><i>안녕하세요</i></div>").appendTo("body");

 ###eq(pos)
    선택된  pos번째 태그 선택.
    $("tr:eq(6)").css("color", "silver"); // 6번째 tr태그 색깔변경 

 ###gt(pos)
    선택된 pos이후의 모든 태그선택
    $("tr:gt(3)").css("color", "red");  // 인덱스가 3이후인것들 모두 색깔변경

 ###lt(pos)
    선택된 JQuery 오브젝트중  pos보다 앞에있는 오브젝트들을 선택.
    $("tr:lt(3)").css("color", "red");  // 인덱스가 3이전인것들 모두 색깔변경 


 ###index(subject)
    subject의 위치.
    var index = $("div").index($("div:contains('jquery')"));  //div안에서 jquery라는 element 찾기


 ###each(callback)
    
    매치되는 모든 요소에 대하여 callback 메소드 실행(루프)
    $("div").each(function(args){           <!-- div에 해당되면 -->
if(this.style.color!='blue')
this.style.color='blue';
else
this.style.color='';
    });


 ###length
    선택된 요소의 갯수.
    var n = $("div").length;  //div태그의 개수리턴

 ###size()
    선택된 요소의 갯수.
    alert( 'Size: ' + $('li').size() ); // <li>의 개수를 리턴한다.

 ###$.fn.extend( prop ) 
  플러그인만들기.
  //check, uncheck함수를 이용한 플러그인
$.fn.extend({   
check:function(){
return this.each(function(){  //each
this.checked=true;
});
},
uncheck:function(){
return this.each(function(){
this.checked=false;
});
}
});


 $("li:first").css("background", "#CCCCCC");

 $("li:first-child").css("background", "#CCCCCC");





4. Attributes(속성)
.attr() 
속성값 가져오기 : .attr(attributeName)
속성값 병경하기 : .attr(attributeName, value)
$("img").attr("src", "img/ii.jpg"); //img 요소의 src속성을 img/ii.jpg으로 변경


.removeAttr()
속성값제거
$("#name").removeAttr("disabled");


.val() 선택된 요소값 가져오기
var name = $(“#txtName”).val(); //입력된 값 가져오기
$(“#txtName”).val(“새로운 값 입력”); //값 입력하기






5. Manipulation(조작)

내용변경관련
html()        일치된 요소의 html 내용을 가져옴
html(val)      일치된 요소의 html 본문을 val 값으로 설정
text()        일치된 모든 요소의 텍스트를 가져옴.
text(val)      모든 일치된 요소의 텍스트를 val 값으로 설정
예)var text = $("div").text();
   var html = $("div").html();   

추가관련(내부) 
append(content)         일치된 요소의 내부에 content를 추가
appendTo(selector) 일치된 요소를 selector에 의해 일치된 모든 요소들 내부에 추가 
prepend(content) append(content)와 동일하며, 다만, 내부 앞쪽에 추가
prependTo(selector) appendTo(selector)와 동일하며, 다만, 내부 앞쪽에 추가

예)$("b.link").append("(클릭)");

추가관련(외부)
after(content) 일치된 요소 뒤에 content를 삽입
efore(content) 일치된 요소 앞에 content를 삽입
insertAfter(selector) 일치된 요소를 selector에 의해 일치된 모든 요소들 뒤쪽에 삽입
insertBefore(selector) insertBefore(selector)와 같으나, 요소 앞쪽에 삽입

예)$("a").after("<font>(클릭)</font>");
-><a href="http://naver.com">네이버</a><font>(클릭)</font>






6. Events

bind : 이벤트 추가
unbind : 이벤트 제거
click : 마우스 클릭시...
change : <input />, <textarea />, <select /> 요소의 값 변경시 발생하는 이벤트
dbclick : 마우스를 더블클릭 했을 경우 발생하는 이벤트
focus : 요소에 포커스 되었을 때 발생하는 이벤트
keydown : 키 입력 시 발생되는 이벤트이며, 모든 키에 대해 적용
keyup : 키 입력 후 발생되는 이벤트 입니다.
keypress : keydown 이벤트와 동일하게 키 입력 시 발생이 되지만 enter, tab등의 특수키에는 이벤트가 발생되지 않음
mousedown : 마우스 클릭 시 발생하는 이벤트
mouseenter :  선택한 요소의 영역에 마우스가 위치했을 때 발생되는 이벤트
mouseleave : 선택한 요소의 영역에서 마우스가 벗어 났을 때 발생되는 이벤트
mousemouse : 선택한 요소에 마우스를 클릭하면 발생하는 이벤트
mouseout : 선택한 요소의 영역에서 마우스가 벗어 났을 때 발생되는 이벤트
mouseover : 마우스를 올려놓으면 발생
mouseup : 마우스 클릭 후 발생되는 이벤트
scroll : HTML 문서가 스크롤 되었을 때 발생하는 이벤트ㅋ
select : 선택한 개체를 마우스를 통해 선택 하였을 때 발생하는 이벤트
submit : Submit이 일어날 때 발생하는 이벤트
hover() : 마우스가 요소 위에 위치했을 때 발생하는 이벤트
blur() : 요소에서 포커스를 잃을 경우에 발생하는 이벤트

'PP > Jquery' 카테고리의 다른 글

jQuery 이벤트 정리  (0) 2012.01.08
다른 라이브러리와 같이 쓰기  (0) 2012.01.08
jQuery Core  (0) 2012.01.08
[Jquery,CoffeeScript] 모질라 파이어폭스 Ajax. 한글 키 이벤트 처리.  (0) 2012.01.08
jQuery UI 테스트 2  (0) 2012.01.08
posted by 방랑군 2012. 1. 8. 21:27

출처 :  http://findfun.tistory.com/entry/jQuery-%EC%89%BD%EA%B2%8C%ED%95%98%EA%B8%B0-%EB%8B%A4%EB%A5%B8-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%EC%99%80-%EA%B0%99%EC%9D%B4-%EC%93%B0%EA%B8%B0 

Javascript Library 들이 출현하면서 자바스크립트의 중요성은 비약적으로 높아졌습니다. Rich UI 를 구현함에 있어서 이 라이브러리들의 기여도는 결정적이였습니다. 풍부해진 사용자 경험(UX)을 바탕으로 웹 어플리케이션이란 용어도 등장하기 시작했습니다. 아마 앞으로는 웬만한 어플리케이션은 웹 기반이 되지 않을까 합니다.

많아진 Javascript Library 들을 같이 사용해야 하는 경우가 있습니다. 이에 jQuery는 다음과 같은 권고 사항을 제시하고 있습니다.

원문을 보시려면 여기를 클릭하세요.

GENERAL : 개요

jQuery 라이브러리와 Plugin 들은 jQuery 네임스페이스안에 종속되어 있습니다. 만약 여러분이 jQuery 외의 Prototype, MooTools, YUI 등과 같은 다른 라이브러리와 같이 사용하길 원하면 jQuery의 "전역(global)" 객체들은 jQuery 네임스페이스 안에서 사용해야 합니다.

jQuery 에서는 다음과 같이 경고(권고) 합니다. jQuery의 '$' 를 'jQuery' 로 바꿔 사용하십시요.

완전 직역이네요. ^^;; 쉽게 설명드리자면 jQuery하고 Prototype을 같이 쓰실 경우가 생기시면 jQuery의 $ 를 jQuery 라고 바꿔 쓰라는 얘기입니다. Prototype에도 $ 가 있으니까요. 아래 구체적인 예시들이 있습니다.

 

OVERRIDING THE $-FUNCTION : $ 함수를 재정의 하세요.

jQuery.noConflict() 함수를 사용한 후 그 이후부터는 $ 대신 jQuery 사용할 수 있습니다. 아래는 예제코드입니다.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<head>
  <script src="prototype.js"></script>
  <script src="jquery.js"></script>
  <script>
    jQuery.noConflict();
     
    // Use jQuery via jQuery(...)
    jQuery(document).ready(function(){
      jQuery("div").hide();
    });
     
    // Use Prototype with $(...), etc.
    $('someid').hide();
  </script>
</head>
<body></body>
</html>

6라인 이후에는 $ 대신에 jQuery 라고 사용하신 것을 보실 수 있습니다. 14라인의 $ 는 Prototype의 $ 가 됩니다. $를 Prototype에게 양보한다는 거네요. 참 착한 jQuery입니다. ^^

그런데 $ 라고 쓰다가 jQuery 라고 쓰려니 타자의 압박이 있습니다. 그래서 jQuery 는 아래와 같이 대체어(alternate names)를 사용할 수 있게 했습니다.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<head>
  <script src="prototype.js"></script>
  <script src="jquery.js"></script>
  <script>
    var $j = jQuery.noConflict();
     
    // Use jQuery via $j(...)
    $j(document).ready(function(){
      $j("div").hide();
    });
     
    // Use Prototype with $(...), etc.
    $('someid').hide();
  </script>
</head>
<body></body>
</html>

6라인을 보시면 $j 라고 변수선언을 했습니다. 그 아래 부터 jQuery 가 아닌 $j 로 사용하실 수 있습니다. $j 말고도 사용하고 싶은 대체어를 만드시면 됩니다. $findfun 이나 $jq 와 같이 말이죠.

그럼에도 불구하고 "아~ 나는 무조건 $를 써야겠다" 라고 하시는 분들을 위해서 jQuery는 또 하나의 방법을 제시합니다.(이 방법은 별로인거 같습니다.)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
  <script src="prototype.js"></script>
  <script src="jquery.js"></script>
  <script>
    jQuery.noConflict();
     
    // Put all your code in your document ready area
    jQuery(document).ready(function($){
      // Do jQuery stuff using $
      $("div").hide();
    });
     
    // Use Prototype with $(...), etc.
    $('someid').hide();
  </script>
</head>
<body></body>
</html>

9라인과 같이 jQuery 네임스페이스 안에 속한 내용들은 이전 처럼 $ 를 사용하실 수 있습니다. 11라인을 보세요. 그대로 $ 를 사용했습니다. 하지만 썩 좋은 코드는 아닌 것 같습니다.

jQuery.noConflict() 함수가 기억이 나지 않거나 실수로 기술하지 않았을 경우에는 에러를 찾기 힘들 수 있습니다. 아래 내용을 보시면 해결 방법이 있습니다.

 

INCLUDING JQUERY BEFORE OTHER LIBRARIES : jQuery 라이브러리 인클루드를 다른 라이브러리 보다 위쪽에 하세요.

jQuery 라이브러리 인클루드를 항상 제일 위쪽에 하시면 jQuery.noConflict() 함수를 기억하지 않으셔도 됩니다.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<head>
  <script src="jquery.js"></script>
  <script src="prototype.js"></script>
  <script>
    // Use jQuery via jQuery(...)
    jQuery(document).ready(function(){
      jQuery("div").hide();
    });
     
    // Use Prototype with $(...), etc.
    $('someid').hide();
  </script>
</head>
<body></body>
</html>

3,4 라인을 보시면 jquery.js 가 위쪽입니다. 그리고 코드 상에 jQuery.noConflict() 가 없는 것을 보실 수 있습니다.

 

결론적으로 jQuery 라이브러리와 다른 라이브러리들 같이 사용하시려면 아래와 같이 사용하시는 것을 적극 권장합니다.

  •  jQuery 라이브러리 인클루드를 다른 라이브러리 보다 위쪽에다 할 것.
  •  
  •  var $j = jQuery; 와 같이 대체어를 사용할 것.

 

두 가지 이상의 라이브러리를 동시에 같은 프로젝트에 사용할 일은 거의 없어 보입니다. 하지만 그런 일이 없으란 법은 없겠죠. 그런 경우를 대비해서 한번 읽고 넘어가는 것도 좋겠네요. jQuery 의 세심한 배려에 박수를 보냅니다.

자 이번 포스팅은 여기 까지입니다. 그럼 모두들 즐프하세요~. 
posted by 방랑군 2012. 1. 8. 21:23

출처 :  http://findfun.tistory.com/67 

API(Application Program Interface, 응용프로그램 인터페이스)란 어떤 응용프로그램에서 제공한 메소드들의 모음입니다. 사전적으로 해석을 해보자면 "응용 프로그램과 대화하기" 가 되겠습니다. 사람사이의 대화방법은 몸짓, 말, 글을 사용합니다. 이것들을 인터페이스라고 할 수 있습니다. 단, 서로 의미가 통해야 합니다. 즉, 사전에 정의된 해석방법으로만 대화가 가능하죠. 고개 숙여 인사를 하는 박찬호를 보고 이상하게 생각했다는 미국인들과 같이 해석의 방법이 미리 정의되지 않은 대화방법으로는 오해 또는 소통이 불가하게 됩니다.

프로그램에서도 어떤 응용프로그램에 접근하기 위해 사전에 정의된 함수들의 모음이 존재하고, 이 모음을 외부에 노출하기 위해 정리한 것이 API 라고 할 수 있습니다. 즉, API 는"내가 만든 프로그램을 사용하고 싶으면 이런저런 약속을 지켜서 사용하고, 어떤 행동을 일으키고 싶을때 사용하는 함수들을 알려줄테니 그걸로 써라"라는 문서가 됩니다.

jQuery 와 같이 잘 정리된 라이브러리는 개발자들에게 천국입니다. API 가 어렵지 않으며 관련 자료도 많은 jQuery는 문제가 발생했을 때 빠른 시간안에 해결을 할 수 있게 됩니다. 일전에 잘 사용하지 않은 산업용 PDA 에 Windows-CE 기반 프로그램을 하다가 아주 고생했던 기억이 납니다. 다시 겪고 싶지 않은 경험입니다. ^^;.

사설이 길었네요. 자~ 이제 드디어 API 를 할 수 있게 되었네요. API 에 대해 모두 쓸 예정이지만 때에 따라서는 생략도 하게 될 것 같습니다. 그나저나 얼마나 길어지게 될지.. 좀 두렵기도 한데요 ^^;;. 자 시작합니다.

Core

jQuery 의 핵심입니다. 우리가 $() 로 사용하고 있는 것에 대한 설명입니다. 실제로는 jQuery() 라고 사용해야 하지만 축약어로 $() 로 사용하고 있는 jQuery 코어에 대한 설명입니다.

원문 링크  http://api.jquery.com/category/core/

함수 목록

  • 일치하는 요소들(elements)를 사용하기 위해 CSS 선택자(selector)와 같은 문자열을 사용합니다.
  • jQuery 의 $ 변수 사용을 포기합니다.

jQuery()

함수들

 jQuery( selector, [ context ] )
  • jQuery( selector, [ context ] )
  • jQuery( element )
  • jQuery( elementArray )
  • jQuery( jQuery object )
  • jQuery()
 jQuery( html, [ ownerDocument ] )
  • jQuery( html, [ ownerDocument ] )
  • jQuery( html, props )
 jQuery( callback )
  • jQuery( callback )

jQuery( selector, [ context ] )Returns : jQuery

개요 : CSS 선택자(selector)와 일치하는 요소들(elements)을 사용하기 위한 문자열을 사용합니다.

  • jQuery( selector, [ context ] )
  • selector 선택자(selector)를 문자열로 표현
  • context DOM 요소, 문서(Document) 또는 문맥상에서 사용되는 jQuery
  • jQuery( element )
  • element jQuery 객체에 속한 DOM 요소
  • jQuery( elementArray )
  • elementArray jQuery 객체에 속한 DOM 요소들의 배열
  • jQuery( jQuery object )
  • jQeury object 복사를 위한 jQuery 객체
  • jQuery()

jQuery() - $() 로 사용하고 있는 - 는 제공된 선택자(selector)를 검색하고 그 요소(elements)를 jQuery 객체화 합니다. 직역이 어렵네요. 즉, 우리가 제시한 선택자를 문서상에서 찾아서 jQuery() 객체로 만들어 줍니다. 그래야 jQuery 의 함수와 속성들을 사용할 수 있으니까요. 아래와 같이 선택자(selector)를 문자열로 적어주면 해당 문서에서 이 문자열과 일치하는 요소들(elements)을 찾아 jQuery 객체로 만들어 준다는 얘기입니다.

$('div.foo');

 Selector Context : 선택자 사용방법

기본적으로 선택자를 찾기 위해서 문서의 처음부터 검색을 합니다. 하지만 때에 따라서는 원하는 부분만 찾을 필요도 있습니다. 성능이 최우선이기 때문이죠. 이런 경우를 위해서 $() 함수의 2번째 인자를 이용할 수가 있습니다. 아래 예제는 div.foo 가 클릭되었고 그 요소의 태그가 span 일 경우 bar 라는 클래스를 span 에 추가하는 구문입니다.

$('div.foo').click(function() {
  $('span', this).addClass('bar');
});

원하는 부분만 선택해서 검색할 수 있는 기능이 있다는 얘기입니다. 위 예제 중 $('span', this) 는 $(this).find('span') 과 같은 의미입니다. 즉, find() 함수를 사용하여 원하는 요소를 찾아서 어떤 일을 진행할 수 있습니다. 실제로 전체 문서를 다 찾아서 처리하는 방식은 지양해야 하는 방식입니다. 하지만 꼭 써야 할 경우도 생길수도 있지만 가급적이면 다른 방법을 강구해야 할 것 같습니다.

 Using DOM elements : DOM 요소 사용하기

이미 찾은 DOM 요소(element) 또는 요소들(elements)을 이용하여 jQuery 객체를 만드는 방법은 2~3가지 방법을 사용할 수 있습니다. 시스템 이벤트에 의해 호출되는 함수(callback function)를 통해 전달된 그 요소(an element)를 이용하여 jQuery 함수들을 쉽게 사용하려면 "this" 키워드를 사용하면 됩니다. 아~ 영어 무지 딸립니다. 죽겠습니다. ㅜ,.ㅡ;; 유추해 보자면, 기본적으로 DOM 요소가 가진 특정 콜백함수들이 호출되면 그 이벤트를 전달한 요소(element)를 알아낼 수 있는데요. 그 요소(element)로 jQuery 함수를 사용하고 싶다면 "this" 키워드를 사용하면 된다라는 얘기인 것 같습니다. 그럴 듯 한가요? ㅎㅎ;;; 아래 예제를 보시죠.

$('div.foo').click(function() {
  $(this).slideUp();
});

위 예제는 'div.foo' 요소 클릭이라는 시스템 콜백함수가 호출되면 그 요소를 slideUp() 이라는 jQuery 함수를 사용해서 표현하라 라는 의미입니다. slideUp() 이 뭐하는 함수인지는 일단 제껴두고, 이 클릭 이벤트가 발생된 요소를 그 slideUp() 을 하기 위해서 $(this) 를 사용했다는 점을 봐달라는 겁니다. 여기에서 this 가 바로 $('div.foo') 로 찾아낸 DOM 요소의 jQuery 객체가 된다는 얘기입니다. 와~ 말 무지 어렵습니다. 에혀~. 원문에서는 아래의 부가 설명이 있습니다.

이 예제는 어떤 요소가 클릭(clicked) 되었을 때 슬라이딩 에니메이션(sliding animation)을 발생시킨다는 의미가 내포되어 있습니다. 이 조정자(handler receives : 클릭된 요소를 의미)는 순수한 DOM 요소(element)이며 이 요소를 $(this)를 이용하여 jQuery 객체화를 하게 됩니다. 이 요소(위에서 조정자)가 jQuery 의 함수를 사용하기 위해서는 jQuery 객체화가 되어야 합니다. 즉, 순수 DOM 요소는 jQuery 함수를 사용할 수 없기 때문이죠.

또한, XML 데이터를 Ajax 를 통해서 전달 받은 뒤, $() 함수를 이용해서 쉽게 jQuery 객체화가 가능합니다. jQuery 객체화가 이루진 후에는 이 XML 구조(structure)에서 우리는 찾고자 하는 요소를 jQuery 의 .find() 함수나 DOM 의 검색 함수들을 이용해서 쉽게 찾아 낼 수 있습니다.

예 제
p 태그를 하위 요소로 가지고 있는 div 를 찾아서 테두리에 선을 그린다.

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-1.4.4.js"></script>
</head>
<body>
  <p>one</p> <div><p>two</p></div> <p>three</p>
<script>$("div > p").css("border", "1px solid gray");</script>

</body>
</html>

미리보기

jQuery( html, [ ownerDocument ] )Returns : jQuery

개요 : 순수한 HTML(raw HTML) 문자열을 이용하여 동적인(on the fly) DOM 요소를 만듭니다.

  • jQuery( html, [ ownerDocument ] )
  • html 동적인 HTML 문자열입니다. XML 이 아닌 HTML 만 분석합니다.
  • ownerDocument 만들어진 새 요소(new elements)가 위치한 문서
  • jQuery( html, props )
  • html 단독, 독립적인 HTML 요소로 정의할 수 있는 HTML 태그 문자열 (예 : <div/> 또는 <div></div>)
  • props 만들어진 새 요소의 속성, 이벤트, 함수들

HTML 문자열을 가지고 DOM 요소를 만들어 낼 수 있습니다.

 Creating New Elements : 새 요소 만들기

만약 당신이 $() 함수에 문자열을 전달했다면, jQuery 는 그 문자열에 태그의 요소(<tag...> 와 같은)가 있는지 확인해 봅니다. 없다면 위의 예처럼 선택자 표현(selector expression)이라 판단하고 처리를 하게 됩니다. 하지만 문자열에 HTML 태그가 있다면 jQuery 는 그 태그에 해당하는 DOM 요소를 만들어 문서에 추가하게 됩니다. 추가된 요소(elements)는 jQuery 객체 형태를 유지하기 때문에 jQuery 의 많은 함수들을 쉽게 사용할 수 있게 됩니다. 아래 예제와 같은 구문도 jQuery 객체로 인식하여 jQuery 함수들을 사용할 수 있게 됩니다.

$('<p id="test">My <em>new</em> text</p>').appendTo('body');

위 예제와 같이 속성이 없는 하나의 태그가 아닌 복잡한 수준이라면 마치 innerHTML 을 사용하는 것과 같이 동적으로 요소를 추가하게 됩니다. 더 들여다 보자면, jQuery 는 전달된 HTML 태그들을 <div>를 만들어서 그 안에 innerHTML 을 이용하여 위치(sets) 시키게 됩니다. 즉, div 태그를 임의로 만들고 그 안에 전달된 태그 문자열을 DOM 요소로 추가한다는 얘기입니다. 만일 단순한 하나의 태그로 구성된 문자열 - $('<img />> 또는 $(<a></a>) 와 같은 - 이라면 jQuery 는 JavaScript의 createElement() 함수를 이용하여 새 요소를 만들어 내게 됩니다.

복잡한 수준의 HTML 태그를 추가해야 할 일이 생기기도 하지만 HTML 소스가 정확하게 복사되지 않는 브라우져들도 있습니다. 예를 들어 인터넷 익스플로러 8 이전의 버젼들은 모든 절대 경로(absolute URLs)를 href 속성으로 만들어 버리고 IE 9 이전 버젼들은 HTML5 의 신규 요소들을 정확하게 처리하지 못합니다.

따라서 안전하게 크로스 브라우징이 되려면 웹 표준(well-formed)을 지켜야만 합니다. 태그들은 반드시 닫는 태그와 함께 사용해야 합니다.

$('<a href="http://jquery.com"></a>');

반드시 위와 같이 사용하거나 아래와 같이 사용해야 합니다.

$('<a/>');

jQuery 1.4 이후부터는 두번째 인자를 통해서 속성들을 부여할 수 있습니다. 이 인자에는 .attr() 함수에서 전달할 수 있는 인자를 포함한 속성 집합을 모두 사용할 수 있습니다. 게다가 사용자 이벤트 외에도 val, css, html, text, data, width, height, offset 과 같은 jQuery 의 함수도 추가할 수 있습니다. 참고로 인터넷 익스플로러에 input 태그를 추가한 후에 그 타입을 속성으로 변경 처리할 수는 없습니다. 즉, 체크박스를 추가하고 싶다면 반드시 '<input type="checkbox" />'와 같이 사용해야 합니다.(라고 되있지만 제가 테스트해 결과 모두 다 정상적으로 되더군요. 이 부분 해석을 발로 해서 뭔가 잘못된 것 같습니다. 혹시 관련해서 알려주실 분 있으시면 대 환영입니다. lol )

예 제
div 태그와 그 안의 모든 내용들이 동적으로 만들어 지고, body 요소에 추가됩니다. 내부적으로 이런 요소가 만들어지고 그 안에 innerHTML 속성을 사용해 마크업이 됩니다. 그러니까 이것은 꽤 유연하지만 한계도 같이 지니고 있습니다.(무슨 소리인지 모르겠습니다. ^^;;)

$("<DIV>
<P>Hello</P></DIV>").appendTo("body")

예 제
2번째 인자인 속성 맵을 이용하여 DOM 요소 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$("<div/>", {
  "class": "test",
  text: "Click me!",
  click: function(){
    $(this).toggleClass("test");
  }
}).appendTo("body");
 
$("<input>", {
  type: "text",
  val: "Test",
  focusin: function() {
    $(this).addClass("active");
  },
  focusout: function() {
    $(this).removeClass("active");
  }
}).appendTo("form");

미리보기

위 소스를 보시면 1라인에 <div/> 라고 되어 있는 걸 보실 수 있습니다. 이렇게 하던가 <div></div> 이렇게 사용해야 한다는 겁니다. 그리고 속성들과 메소드들을 얼마든지 추가할 수 있습니다. 위 "Click me" 는 jQuery 의 toggleClass 함수를 사용하여 글자색을 클릭 시마다 변경하는 함수를 집어 넣었습니다. 아래 input 은 포커스가 들어오면 active 클래스를 토글하게 됩니다. 참 유용한 내용입니다.

jQuery( callback )Returns : jQuery

개요 : 문서가 모두 읽혀지면(finished loading) 호출될 함수를 지정합니다.

  • jQuery( callback )
  • callback 이 함수는 DOM 이 준비가 되면 실행됩니다.

이 함수는 $(document).ready() 와 같은 동작을 합니다. 혹시 $() 함수가 잘 동작되지 않을 때를 대비하여 사용하면 좋습니다. 즉, $(document).ready() 함수가 동작하지 않았을 때를 대비하여 jQuery( function($) {}); 와 같이 사용하시면 됩니다.

jQuery.noConflict()

이 함수는 jQuery() 의 별칭인 $() 의 사용을 더 이상 하지 않을 때 사용하게 됩니다. 이 내용은 이전 포스팅으로 대체하겠습니다.

http://findfun.tistory.com/entry/jQuery-쉽게하기-다른-라이브러리와-같이-쓰기  [새창으로] [바로이동]

 

우와 이번 포스팅 진짜 깁니다. 게다가 이 글을 쓰는 동안 베타버젼의 메소드가 하나 더 추가되었더 군요. ㅡ,.ㅡ;; jQuery.addClass() 라는 녀석입니다. 아직 베타여서 기술하지 않았습니다. 힘들어서 안한거 아닙니다. 절대로. 너무 길어서 나누어 할까 하다가 같은 페이지에서 볼 수 있어야 겠다고 생각이 들었습니다. 너무 길어져 버려서 스크롤 내리는 데만도 한참이네요. ㅡㅡ;;

어찌됬든 jQuery 의 핵심(core)를 들여다 봤습니다. 실제 사용하는데 있어서 이 내용을 몰라도 관계 없습니다. 그래도 관심있게 본 거랑은 다르겠죠. 휴우~ 다음번 부터는 내용이 좀 짧았으면 하네요.

그럼 즐프하세요. 
posted by 방랑군 2012. 1. 8. 20:56

출처 :   http://www.dorajistyle.pe.kr/2011/12/jquerycoffeescript-ajax.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+DelightOnTheSimpleLife+%28%EC%9B%94%ED%92%8D%EB%8F%84%EC%9B%90%28%E6%9C%88%E9%A2%A8%E9%81%93%E9%99%A2%29+-+Delight+on+the+Simple+Life.%29 

[Jquery,CoffeeScript] 모질라 파이어폭스 Ajax. 한글 키 이벤트 처리.

모질라 파이어폭스에서 Ajax 한글 키 이벤트를 처리하는 Jquery,커피스크립트 코드입니다.

모질라 파이어폭스 Ajax. 한글 키 이벤트 처리.(Jquery Mozilla Force Keyup CoffeeScript module)

저는 주 브라우저로 모질라 파이어폭스를 사용합니다.
Ajax 모듈을 만드는데, 한글을 입력하면 못 알아듣더군요.
http://javascript.info/tutorial/keyboard-events에서 키 이벤트 체크를 해 봤습니다.
한글 키가 눌리면 Keydown(Keycode=229) 이벤트가 한 번만 발생하고,
Keyup 이벤트는 발생하지 않습니다.
중국어,일본어를 테스트 해보니 이 역시 같은 현상이군요.
한글과 다름없이 229키 코드가 딱 한번 발생합니다.
아마도 다른 블록형 문자 또한 같은 이벤트를 발생 시킬 거라 예상됩니다.
모질라에서 한글 키 이벤트를 부드럽게 처리하는 커피 스크립트 모듈을 만들었어요.
모질라 파이어폭스 이용자도 한글을 편하게 쓸 권리가 있으니까요.
필요하신 분은 마음껏 가져다 쓰세요.

커피스크립트 버전(Jquery Mozilla Force Keyup module  - Coffeescript version)



  
# Mozilla Force Keyup CoffeeScript module
# by 月風(http:://dorajistyle.pe.kr)
# How to use
# mozillaForceKeyup(”inputid”)
# in HTML.
# <input id=”input
id”>
mozillaForceKeyup = (targetId) ->
  if jQuery.browser.mozilla
    isIntervalRunning = null
    target = '#'+targetId
    $(target).bind 'keydown',(e) ->
      if e.which == 229
        forceKeyup = () ->
          $(target).trigger('keyup')
        if not isIntervalRunning
          isIntervalRunning = setInterval forceKeyup, 100

    $(target).bind 'blur',(e) ->
      if isIntervalRunning
        clearInterval isIntervalRunning
        isIntervalRunning = null



자바스크립트 버전(Jquery Mozilla Force Keyup module - Javascript version)



// Mozilla Force Keyup Javascript module
// by 月風(http:://dorajistyle.pe.kr)
// How to use
// mozillaForceKeyup(”inputid”)
// in HTML.
// <input id=”input
id”>

mozillaForceKeyup = function(targetId) {
var isIntervalRunning, target;
if (jQuery.browser.mozilla) {
isIntervalRunning = null;
target = '#' + targetId;
$(target).bind('keydown', function(e) {
var forceKeyup;
if (e.which === 229) {
forceKeyup = function() {
return $(target).trigger('keyup');
};
if (!isIntervalRunning) {
return isIntervalRunning = setInterval(forceKeyup, 100);
}
}
});
return $(target).bind('blur', function(e) {
if (isIntervalRunning) {
clearInterval(isIntervalRunning);
return isIntervalRunning = null;
}
});
}
};

 

'PP > Jquery' 카테고리의 다른 글

다른 라이브러리와 같이 쓰기  (0) 2012.01.08
jQuery Core  (0) 2012.01.08
jQuery UI 테스트 2  (0) 2012.01.08
jQuery 이벤트 테스트 2  (0) 2012.01.08
jQuery 이벤트 테스트 1  (0) 2012.01.08
posted by 방랑군 2012. 1. 8. 20:54

1. test8.jsp

01 <%@ page contentType="text/html; charset=UTF-8"%>
02 <%
03 String cp = request.getContextPath();
04 %>
05 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
06 <html>
07 <head>
08 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
09 <title>Insert title here</title>
10
11 <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
12 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
13 <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
14
15 <script>
16 $(document).ready(function() {
17 $("#accordion").accordion();
18 });
19 </script>
20
21 </head>
22 <body style="font-size:62.5%;">
23 <h1>jQuery 테스트</h1>
24
25 <div id="accordion">
26 <h3><a href="#">Section 1</a></h3>
27 <div>
28 <p>
29 Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer
30 ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit
31 amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut
32 odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.
33 </p>
34 </div>
35 <h3><a href="#">Section 2</a></h3>
36 <div>
37 <p>
38 Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet
39 purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor
40 velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In
41 suscipit faucibus urna.
42 </p>
43 </div>
44 <h3><a href="#">Section 3</a></h3>
45 <div>
46 <p>
47 Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.
48 Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero
49 ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis
50 lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.
51 </p>
52 <ul>
53 <li>List item one</li>
54 <li>List item two</li>
55 <li>List item three</li>
56 </ul>
57 </div>
58 <h3><a href="#">Section 4</a></h3>
59 <div>
60 <p>
61 Cras dictum. Pellentesque habitant morbi tristique senectus et netus
62 et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in
63 faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia
64 mauris vel est.
65 </p>
66 <p>
67 Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus.
68 Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
69 inceptos himenaeos.
70 </p>
71 </div>
72 </div>
73 </body>
74 </html>

실행 결과

[출처] jQuery UI 테스트 1|작성자 엄보

'PP > Jquery' 카테고리의 다른 글

jQuery Core  (0) 2012.01.08
[Jquery,CoffeeScript] 모질라 파이어폭스 Ajax. 한글 키 이벤트 처리.  (0) 2012.01.08
jQuery 이벤트 테스트 2  (0) 2012.01.08
jQuery 이벤트 테스트 1  (0) 2012.01.08
jQuery UI 테스트 2  (1) 2012.01.08
posted by 방랑군 2012. 1. 8. 20:49

1. test2.jsp

01 <%@ page contentType="text/html; charset=UTF-8"%>
02 <%
03 String cp = request.getContextPath();
04 %>
05 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
06 <html>
07 <head>
08 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
09 <title>Insert title here</title>
10
11 <!-- jQuery 사용시 jquery-1.X.X.min.js 파일 연결 필수 -->
12 <script type="text/javascript" src="<%=cp%>/js/jquery-1.6.1.min.js" ></script>
13
14 <script type="text/javascript">
15 //jQuery는 $(선택자) 또는 jQuery(선택자)로 시작한다.
16 //$() 또는 $(document).ready()는
17 //문서가 사용 가능한 시점에 자동으로 인식해서 실행됨.
18 //$(function() { })와
19 //$(document).ready(function() { })는 같은 표현
20 $(document).ready(function() {
21 alert("Hello, JavaScript");
22 });
23 $(document).ready(function() {
24 alert("Hello, jQuery");
25 });
26 </script>
27
28 </head>
29 <body>
30 <h1>jQuery 테스트</h1>
31 jQuery에서 동일한 이벤트 등록시 둘 다 실행됨.
32 </body>
33 </html>

실행 결과



posted by 방랑군 2012. 1. 8. 20:48
01 <%@ page contentType="text/html; charset=UTF-8"%>
02 <%
03 String cp = request.getContextPath();
04 %>
05 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
06 <html>
07 <head>
08 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
09 <title>Insert title here</title>
10
11 <!-- jQuery 사용시 jquery-1.X.X.min.js 파일 연결 필수 -->
12 <script type="text/javascript" src="<%=cp%>/js/jquery-1.6.1.min.js" ></script>
13
14 <script type="text/javascript">
15 //익명 함수
16 //동일한 이벤트가 동시에 있는 경우 나중에 작성한 부분만 실행됨.
17 window.onload=function() {
18 alert("Hello, JavaScript");
19 };
20 window.onload=function() {
21 alert("Hello, jQuery");
22 };
23 </script>
24
25 </head>
26 <body>
27 <h1>jQuery 테스트</h1>
28 자바스크립트에서 동일한 이벤트 등록시 나중에 작성한 부분만 실행됨.
29 </body>
30 </html>

실행 결과

posted by 방랑군 2012. 1. 8. 20:46
01 <%@ page contentType="text/html; charset=UTF-8"%>
02 <%
03 String cp = request.getContextPath();
04 %>
05 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
06 <html>
07 <head>
08 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
09 <title>Insert title here</title>
10
11 <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
12 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
13 <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
14
15 <script>
16 $(document).ready(function() {
17 $("#dialog").dialog();
18 });
19 </script>
20
21 </head>
22 <body style="font-size:62.5%;">
23 <h1>jQuery 테스트</h1>
24
25 <div id="dialog" title="Dialog Title">A dialog is a floating window that contains a title bar and a content area.
26 The dialog window can be moved, resized and closed with the 'x' icon by default.
27 If the content length exceeds the maximum height, a scrollbar will automatically appear.
28 A bottom button bar and semi-transparent modal overlay layer are common options that can be added.
29 A call to $(foo).dialog() will initialize a dialog instance and will auto-open the dialog by default.
30 If you want to reuse a dialog, the easiest way is to disable the "auto-open" option with: $(foo).dialog({ autoOpen: false }) and open it with $(foo).
31 dialog('open'). To close it, use $(foo).dialog('close'). A more in-depth explanation with a full demo is available on the Nemikor blog.
32 </div>
33
34 </body>
35 </html>

실행 결과

[출처] jQuery UI 테스트 2|작성자 엄보

posted by 방랑군 2012. 1. 8. 01:36

 급하게 테스트시 dataset 을 만들기 위해 xml 이나 db 로딩 말고 수동으로 만들때가 있다..

private DataTable GetDT()
        {
            DataTable dtdataTable = new DataTable();

            DataColumn col = new DataColumn("SEQ", typeof(Int32));

            col.AutoIncrementSeed = 1;
            col.AutoIncrement = true;
            col.AutoIncrementStep = 1;
            col.Caption = "Value ID";
            dtdataTable.Columns.Add(col);

            DataColumn[] Keys = new DataColumn[2];
            Keys[0] = col;
            dtdataTable.PrimaryKey = Keys;

            col = new DataColumn("TITLE", typeof(string));
            dtdataTable.Columns.Add(col);

            col = new DataColumn("CONTENTS", typeof(string));
            dtdataTable.Columns.Add(col);

            //col = new DataColumn("Value", typeof(string));
            //col.MaxLength = 50;
            //dtdataTable.Columns.Add(col);

            //col = new DataColumn("DateTime", typeof(Int32));
            //dtdataTable.Columns.Add(col);

            ArrayList ar = new ArrayList();
            ar.Add(1);
            ar.Add("a");
            ar.Add("b");

            dtdataTable.LoadDataRow(ar.ToArray(), true);

            ar.Clear();
            ar.Add(2);
            ar.Add("c");
            ar.Add("d");

            dtdataTable.LoadDataRow(ar.ToArray(), true);

            return dtdataTable;
            
        } 
posted by 방랑군 2012. 1. 8. 01:16


VB.NET 코드를 C# 코드로 변환해주는 사이트

사이트 #1 http://www.developerfusion.co.uk/utilities/convertvbtocsharp.aspx

사이트 #2 http://converter.telerik.com/Default.aspx

+단, 에러가 있으면 변환불가.

'PP > 번외' 카테고리의 다른 글

코딩에 도움이 되는 사이트들  (0) 2012.01.07
C# VS JAVA ~!~!~!  (0) 2012.01.04
posted by 방랑군 2012. 1. 8. 00:50

  Repeater.aspx 코딩부분....  ==> 두번째 이야기 에 코딩 덧붙인 것입니다..;;;

 <button id="btnTest_button" name="btnTest_button"

       onclick="return fn_Test(); runat="server">Toggle Button</button>
 <input type="button" id="btnTest" name="btnTest"

                     onclick="return fn_Test();" value="Toggle Button_2" />
 <input type="hidden" id="hdnAllValue" name="hdnAllValue" />
 <asp:HiddenField ID="hdnServerValue" runat="server" />

 Repeater.aspx - 자바스크립트 코딩 부분

 <script type="text/javascript">
  function fn_Test() {

   // 테이블 id ==> tblObj
   var tmpObj = document.getElementById("tblObj");
   // 토클효과를 주기 위한

   var objVisible = tmpObj.style.display;

   // 초기화         
    document.getElementById("hdnAllValue").value = "";            
    var tblRowCnt = tmpObj.rows.length;
            
    for (var i = 1; i < tblRowCnt; i++) {
            document.getElementById("hdnAllValue").value +=

            document.getElementById("txtValue_" + i.toString()).value + "^";

    // 값 축적 ==> 
            }

   document.getElementById("hdnServerValue").value =

                                 document.getElementById("hdnAllValue").value;

    //

   if ("none" == objVisible) {
        tmpObj.style.display = "block";}
   else {  tmpObj.style.display = "none";}

   return false;
  }
</script>

 Repeater.aspx .cs

 protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DataBindings();
    }

    // 값이 같게 나와야되요..!! 전 저장을 제때못해서..;; 같게나와야정상임.
    string tmp = Request["hdnAllValue"];

    //==> 
    string tmp_1 = hdnServerValue.Value;

    //==> 
}

 

posted by 방랑군 2012. 1. 8. 00:50

Repeater 바인딩 예제
 ==> 이 그림의 예제는 리피터 콘트롤 바인딩 예제로 준비 한 것입니다.^^

 RptTest_1.aspx : 코딩

 <%@ Page Language="C#" AutoEventWireup="true"

                         CodeFile="RptTest_1.aspx.cs" Inherits="RptTest_1" %>

  ........

 <html xmlns="http://www.w3.org/1999/xhtml">
 <head id="Head1" runat="server">
 </head>
 <body>
  <form id="form1" runat="server">
   <div>
    <asp:Repeater ID="Rpt_1" runat="server">
    <HeaderTemplate>
     <table id="tblObj" border="1px">
      <tr>
       <th>번호</th>
       <th>제목</th>
       <th>내용</th>
       <th>비고</th>
      </tr>
    </HeaderTemplate>
    <ItemTemplate>
     <tr> 
     <td style="text-align:center;"><%# PlusNum(Eval("SEQ"))%></td>
     <td><%# Eval("TITLE")%></td>
     <td><%# Eval("CONTENTS")%></td>
     <td> <input type="text" id="txtValue_<%# Eval("SEQ")%>"

                             name="txtValue_<%# Eval("SEQ")%>" size="30" />
     </td>
     </tr>
    </ItemTemplate>
    <FooterTemplate>
  </table>
    </FooterTemplate>
 </asp:Repeater>
 </div>
 </form>
 </body>
 </html>

 RptTest_1.aspx.cs : 코딩

 public partial class RptTest_1 : PageBase
 {
   protected void Page_Load(object sender, EventArgs e)
   {
     if (!IsPostBack)
     {
      DataBindings();
     }
   }

 private void DataBindings()
 {

   SqlConnection con = new SqlConnection(constr);
   con.Open();

   SqlCommand com = new SqlCommand();
   com.Connection = con;
   com.CommandType = CommandType.StoredProcedure;
   com.CommandText = "USP_TEST_BOARD";
   SqlDataAdapter ad = new SqlDataAdapter(com);
   DataSet ds = new DataSet("NOVITEST");
   ad.Fill(ds, "TEST_BOARD");

   DataTable dt = ds.Tables["TEST_BOARD"];
   int rowCnt = dt.Rows.Count;
   for (int i = 0; i < rowCnt; i++)
   {
    dt.Rows[i]["TITLE"] = TestMethod(dt.Rows[i]["TITLE"].ToString());
   }

    this.Rpt_1.DataSource = dt;
    this.Rpt_1.DataBind();

    con.Close();
  }

  private string TestMethod(object strObj)
  {
    return strObj.ToString() + " - New Add Test String";
  }

  public string PlusNum(object objTmp)
  {
    return (Convert.ToInt32(objTmp) + 100).ToString();
  }
}

예제 설명

 1] <%# PlusNum(Eval("SEQ"))%> ==> 함수를 만들어서 바인딩한 예제

 2] id="txtValue_<%# Eval("SEQ")%>" 이런식으로 각 고유 아이디 가능 하다

 3] private string TestMethod(object strObj) ==> 코드 안딴에서 함수 처리

 ※ 참고

 DataSource에 배열을 바인딩 할 경우
  ==> <%# Container.DataItem %>

posted by 방랑군 2012. 1. 8. 00:49

리피터 컨트롤

 1] 데이터를 반복해서 보여주는 컨트롤

 2] 템플릿을 통해 행에 보여줄 형식을 지정

 템플릿 종류

 ItemTemplate

  - 데이터 항목을 보여줄 템플릿

  - 반드시 정의^^

 AlternatingItemtemplate

  - 열을 변경하면서 열의 색깔을 다르케 나오케 한다던가....

  - 반드시 지정 - X

 HeaderTemplate

  - 말그대로 머리 / 제목 부분

 FooterTemlate

  - 데이터 항목 리스트를 다 보여준 후에 보여질 것들 표시

  - 바닥영역

 SeparatorTemplate

  - 데이터 항목과 항목 사이에 보여줄 분리 템플릿

 기본 리피터 정의 형식

 <asp:Repeater ID="Rpt_1" runat="server">
  <HeaderTemplate>
   <table id="tblObj" border="1px" style="display:none;">
    <tr>
     <th>번호</th>
     <th>제목</th>
     <th>내용</th>
     <th>비고</th>
     </tr>
  </HeaderTemplate>
  <ItemTemplate>

   <%# Eval("CONTENTS")%>

  </ItemTemplate>

 sqlDataSource를 이용한 간단한 예제

 <asp:Repeater ID="rpt1" runat="server" DataSourceID="sql1">
 <HeaderTemplate>
 <table border="1px">
 <tr>
    <th>제목</th>
    <th>내용</th>
    <th>글쓴이</th>
    <th>기타</th>
    <th>글번호</th>
    <th>수정날</th>
 </tr>
 </HeaderTemplate>
 <ItemTemplate>
  <tr>
    <td><%# Eval("TITLE")%></td>
    <td><%# Eval("CONTENTS")%></td>
    <td><%# Eval("WRITE_DT")%></td>
    <td><%# Eval("ETC")%></td>
    <td><%# Eval("SEQ")%></td>
    <td><%# Eval("MODI_DT")%></td>
  </tr>
 </ItemTemplate>
 </asp:Repeater>
 <asp:SqlDataSource ID="sql" runat="server" 
    ConnectionString="<%$ ConnectionStrings:TIS %>" 
    SelectCommand="SELECT [SEQ], [TITLE], [CONTENTS],

                    [WRITE_DT], [MODI_DT], [ETC] FROM [TEST_BOARD]">
 </asp:SqlDataSource>

posted by 방랑군 2012. 1. 8. 00:46

출처 :  http://blog.naver.com/guruby?Redirect=Log&logNo=140031649144 

 이 글은 ASP.NET 개발을 책임지고 있는 Scott Guthrie의 블로그에서 가져온 글입니다.

원문은 http://weblogs.asp.net/scottgu/archive/2006/11/28/tip-trick-implement-donut-caching-with-the-asp-net-2-0-output-cache-substitution-feature.aspx에서 보실 수 있습니다.

 

이번 글은 좀 길어서 제대로 번역했는 지 의심스럽기도 합니다..
"번역은 반역이다"라는 말을 실감하고 있습니다..

 

-------------------------------------------------------------------------------


도넛 캐싱 구현 - ASP.NET 2.0 Output Cache Substitution

 

약간의 배경지식:
ASP.NET에서 매우 강력하지만 아직은 덜 사용되고 있는 것 중의 하나로 캐싱이 있다.
ASP.NET 캐싱 기능은 반복적인 사용자 요청에 대해 반복적으로 수행되는 것을 피할 수 있게 한다.
일단 한번 html 내용이나 data를 만들고 나서는 작업 결과를 저장해 놓았다가 재사용한다.
이것은 애플리케이션의 성능을 드라마틱하게 향상시킬 수 있다.
그리고 데이터베이스같은 중요한 자원의 부담을 줄일 수 있다.

 

Steve Smith는 ASP.NET 1.1에서의 캐싱에 대해 몇년 전 MSDN에 좋은 기사를 썼다.
그 기사는 ASP.NET 1.1 캐싱 기능의 몇가지 기본 사항과 사용방법에 대한 글이다.
만일 ASP.NET 캐싱 기능을 전에 사용해본 적이 없다면, 한번 시도해 볼 것을 권한다.
ASP.NET 2.0은 캐싱에 두가지 매우 중요한 기능을 추가했다.

 

1) SQL 캐쉬 무효화 지원 (SQL Cache Invalidation Support)
이것은 데이터베이스의 테이블이나 로우가 수정되면 자동적으로 캐쉬가 무효화되게 한다.
예를 들어 전자상거래 사이트의 제품 목록 페이지가 캐쉬되고 있는 상태에서
언제라도 가격을 바꾸면 바로 반영된다. (옛날 가격을 보여주지 않는다)

 

2) 출력 캐쉬 대체 (Output Cache Substitution)
내가 "도넛 캐싱"이라고 부르는 이 재치있는 기능은 출력 캐쉬된 페이지에서 일부분만 변하게 할 수 있다.
이것은 전체 페이지 출력 캐싱을 좀더 적극적으로 사용할 수 있게 한다.
부분 캐싱을 위해서 페이지를 여러개의 .ascx 사용자 컨트롤로 나눌 필요가 없다.
아래 팁은 이 기능을 만들게 된 동기와 구현 방법에 대해 설명한다.

 


실제 세계에서의 시나리오:

정해진 제품 카테고리로부터 제품 목록을 보여주는 페이지를 만들고자 한다.
제품목록 페이지인 Products.aspx 에는 <asp:datalist> 컨트롤이 있는데

middle-tier의 product data에 바인딩되어 있다.
이 페이지를 출력 캐쉬하면 매번 같은 요청에 대해 데이터베이스를 사용하지 않을 수 있다.
구현은 쉽다. 그저 페이지 맨위에 <%@ OutputCache %> 지시를 추가하면 된다.

 

아래 페이지에서 출력 캐쉬가 어떻게 설정되어 있는 지 보라.
100,000초 동안 캐쉬되고 있다가 northwind의 제품테이블이 수정되면 다음 요청부터 페이지가 즉시 갱신된다.
출력캐쉬 지시에 "VaryByParam" 속성이 있다. 이것은 ASP.NET이 categoryID별로 페이지를 따로 캐쉬하게 한다.
(예를 들어 Products.aspx?categoryId=1과 Products.aspx=2는 따로 저장된다.)

 

Products.aspx:

 

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Products.aspx.vb" Inherits="Products" %>
<%@ OutputCache Duration="100000" VaryByParam="CategoryID" SqlDependency="northwind:products" %>

 

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div class="catalogue">
    <asp:DataList ID="DataList1" RepeatColumns="2" runat="server">
        <ItemTemplate>
            <div class="productimage">
                <img src="images/productimage.gif" />
            </div>
            <div class="productdetails">
            
                <div class="ProductListHead">
                    <%#Eval("ProductName")%>
                </div>
                
                <span class="ProductListItem">
                    <strong>Price:</strong>
                    <%# Eval("UnitPrice", "{0:c}") %>
                </span>
            </div>
        </ItemTemplate>
    </asp:DataList>
    <h3>Generated @ <%=Now.ToLongTimeString()%></h3>
</div>
</asp:Content>

 


Products.aspx.vb:

 

Partial Class Products
    Inherits System.Web.UI.Page

    Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim products As New NorthwindTableAdapters.ProductsTableAdapter

        DataList1.DataSource = products.GetProductsByCategoryID(Request.QueryString("categoryId"))
        DataList1.DataBind()

    End Sub

End Class


브라우저에서 접근하면 아래와 같이 보인다.


 


 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

아래쪽의 timestamp를 주의깊게 봐라.
이 timestamp는 100,000초가 지나거나 product 테이블의 데이터가 수정되면 바뀐다.
이 페이지는 모든 HTTP 요청에 대해 캐쉬된 것을 보여준다.
이 방법은 서버가 초당 1000여번의 요청 처리를 가능하게 하고 데이터베이스는 사용하지 않게 한다.
(그래서 무지하게 빠르다)

 

 

문제점:

위 예제의 한가지 문제점은 환영 메시지와 사용자 이름에서 발생한다. (위쪽 빨간 동그라미 참조)
이것은 ASP.NET 2.0 <asp:loginname> 컨트롤을 사용해서 Site.Master 페이지에서 생성되는 메시지이다.

 

<div class="header">
    <h1>Caching Samples</h1>
            
    <div class="loginstatus">
        <asp:LoginName FormatString="Welcome {0}!" runat="server" />
    </div>        
</div>

 

문제는 전체 페이지를 캐쉬하기 때문에 발생한다.
이 페이지에 접근하는 첫번째 사용자의 이름이 캐쉬되어서 다른 사용자에게 잘못된 환영 메세지를 보여주게 된다.
(이건 더 안좋은 상황이다..)

 


해결책:


이 방법을 해결하는데 두가지 방법이 있다.

 

첫번째 방법은 페이지를 전면 개편해서 사용자 컨트롤로 도배하는 것이다.
캐쉬될 필요가 있는 내용을 사용자 컨트롤 안에 넣고

각 .ascx 사용자 컨트롤의 맨 위에 <%@ OutputCache %>을 추가한다.
이 방법 역시 매번 데이터베이스에 접근하는 것을 피하고 사용자 이름도 정확하게 나오도록 한다.
이것은 ASP.NET 1.1에서 사용하는 방법인데 당연히 ASP.NET 2.0에서도 된다.


출력 캐쉬 대체 블럭 - <asp:substitution> 컨트롤 사용:
출력 캐쉬 대체 블럭은 전체가 캐쉬된 페이지에서 변경될 수 있는 부분을 표시할 수 있게 한다.
(예를 들면 위의 예제에서 사용자 이름이 그렇다)
나는 때때로 이것을 "도넛 캐싱 기능"이라고 부른다.
왜냐하면 페이지의 바깥 부분은 캐쉬되고 안쪽의 몇몇 구멍이 동적으로 변하기 때문이다.

이것은 사용자 컨트롤을 사용한 페이지 부분 캐쉬와 정확히 반대되는 개념이다.
페이지 부분 캐쉬는 페이지 전체가 동적으로 변하고 일부분이 캐쉬된다.

출력 캐쉬 대체는 (정확히 위의 Products.aspx 예에서 처럼) 페이지 전체를 출력 캐쉬해서 구현할 수 있다.
페이지 중에서 동적으로 변경되는 부분만 <asp:substitution> 컨트롤로 표시하면 된다.

 

<div class="header">
    <h1>Caching Samples</h1>
    
    <div class="loginstatus">
        <asp:Substitution ID="Substitution1" runat="server" MethodName="LoginText" />
    </div>
</div>

 

예를 들어 위 시나리오에서 환영 메세지를 동적으로 만들고 싶다면,
아래 메서드를  Site.Master 코드 비하인드 파일에 넣고 부르면 된다.

 

Partial Class Site
    Inherits System.Web.UI.MasterPage

    Shared Function LoginText(ByVal Context As HttpContext) As String
        Return "Hello " & Context.User.Identity.Name
    End Function

End Class

 

이제 전체 페이지 중에서 <asp:substitution> 컨트롤 부분만 빼고 출력 캐쉬되었다.

만일 쇼핑 카트같은 추가적인 개인 정보를 넣고 싶다면 당연히 그럴 수 있다.
좋은 점은 페이지의 다른 부분은 모두 캐쉬되었서 페이지를 생성하기 위해서
더이상 데이터베이스에 접근하지 않아도 된다는 것이다.
(이것이 의미하는 것은 한대의 서버로도 초당  수천번의 페이지 요청을 처리할 수 있다는 것이다)

사실은 요청을 처리하는 동안 어떠한 컨트롤도 생성되지 않는다. 단지 위의 static 메서드만 불린다.
그래서 모든 것이 무지 빠르다..

 


출력 캐쉬 대체 블럭 - Response.WriteSubstitution 메서드를 사용:

<asp:substitution>로 바뀌는 부분을 표시하는 방법 외에도 Response.WriteSubstitution를 사용하는 방법도 있다.

이 메서드는 HttpResponseSubstitutionCallback 위임 개체를 전달인자로 가진다.
그래서 애플리케이션 어디에서나 구현 가능하다.

(code-behind 클래스의 static 메서드에서 가능한 것이 아니다)

<asp:substitution> 도 내부적으로는 이 메서드를 사용해서 code-behind 클래스의 delegate와 연결한다.
같은 방법으로 당신의 사용자 컨트롤이나 페이지에서 사용할 수 있다.


결론:

아직도 캐쉬기능을 사용하지 않는 ASP.NET 애플리케이션을 발견하고 있다.
ASP.NET은 전체 페이지 출력 캐쉬, 페이지 부분 출력 캐쉬, 그리고 이제는 "도넛 캐싱"을 지원한다.
이것은 파라미터나 로직에 따라 캐쉬된 내용이 바뀔 수 있고 데이터베이스가 바뀌면 자동으로 내용을 갱신하게 한다.
일정 수준 이상의 애플리케이션이라면 캐쉬를 사용하지 않는 애플리케이션을 찾기 힘들 것이다.

 

나는 강력히 모든 ASP.NET의 캐쉬 기능을 알아 볼 것을 권한다.
다른 캐쉬 사용 예를 보기 원한다면 내 Tips/Tricks talk from the recent ASP.NET Connections event을

다운로드하길 바란다.
이 발표에서 나는 어떻게 전체 페이지 캐싱, 페이지 부분 캐싱, 대체 블럭 캐싱, SQL 캐쉬 무효화를 하는지 보여준다.
그리고 추가적인 ASP.NET 팁들 보려면 내 ASP.NET Tips, Tricks and Resources page를 보기 바란다.

 

이 글이 도움이 되기를
Scott

'PP > ASP.NET' 카테고리의 다른 글

[ASP.NET] Repeater(리피터) 2  (0) 2012.01.08
[ASP.NET] Repeater(리피터) 1  (0) 2012.01.08
[캐싱] Caching Process  (0) 2012.01.08
[캐싱] ASP.NET 캐싱 기능을 살펴보자.  (0) 2012.01.08
[캐싱] 웹사이트 캐싱전략  (0) 2012.01.08
posted by 방랑군 2012. 1. 8. 00:44

출처 : http://blog.naver.com/jeeh001?Redirect=Log&logNo=90117520240 

1. 캐싱(Caching) ?

  : 이미 처리된 데이터를  캐시에 넣는 행위를 말한다.

 

    (1) 캐싱기능

       ㄱ. 출력캐싱 - 페이지 처리 결과를 출력 캐시에 저장하고 사용자가 페이지를 다시 요청할때

                           페이지를 다시 처리하는 대신 출력 캐시에 저장된 결과를 다시 사용하는 캐싱기법

           - 출력캐싱기법 

              a. 전체페이지 캐싱 - 페이지 전체를 캐싱하는 기법 

                        <%@ OutputCache Duration="10" VaryByParam="none"&>

                         => .aspx 페이지를 10초간 출력 캐시에 저장하며, 매개변수를 통한 출력캐시는

                              사용하지 않겠다

                   @ OutputCache :  Duration, VaryByParam 특성을 지정해 줘야 한다.

 

              b. 부분페이지 캐싱 - 페이지의 일부분을 캐싱하는 기법

            

         ㄴ. 데이터 캐싱 - 사용자가 생성한 데이터 자체를 저장하는 캐싱기법

                               - 응용 프로그램 캐싱이라고도 한다.

 

    (2) 캐싱이 일어나는 순서

      1. .asp페이지를 최초로 요청하면 파서에 의해 .asp 페이지 구분을 분석하는 파싱 작업이

           일어난다.            

      2. 중간언어(IL)로 만드는 컴파일 작업이 일어난다.

      3. 생성된 중간언어는 어셈블리 캐시에 저장되고  메모리가 올려진 중간언어는 CLR에 의해

          실행된후 그 결과가 사용자에게 웹 페이지 형식으로 렌더링된다.

 

2. 캐시

  : 문맥상 명사(저장소) 또는 동사(저장하다)의 형태로 사용될수 있으므로 상황에 따라 캐싱과 동일한

    의미를 가진다.

  : 빠른 데이터 처리를 위해 이미 처리된 데이터를 임시적으로 저장해 두는 장소를 말한다.

 

[출처] ASP.NET - 캐싱(Caching)|작성자 수빈이

 
posted by 방랑군 2012. 1. 8. 00:43
출처 :  http://blog.naver.com/wml?Redirect=Log&logNo=100003581528 

고성능을 빌드하는 데 가장 중요한 요소 중 하나는 데이터 개체, 페이지, 페이지 부분 등의 항목이 처음으로 요청될 때 확장 가능한 웹 응용 프로그램이 해당 항목을 메모리에 저장할 수 있어야 한다는 점입니다. 이러한 항목은 웹 서버나 요청 스트림의 다른 소프트웨어에 저장할 수 있습니다(예: 프록시 서버 또는 브라우저). 이 기능을 사용하면 이전 요청을 충족하는 정보, 특히 막대한 프로세서 시간을 소비하는 정보나 그 밖의 리소스를 만들 때 서버에서 이를 다시 만들지 않아도 됩니다. 캐싱이라고도 하는 이 기능을 사용하면 수많은 기술을 사용하여 HTTP 요청을 통해 페이지 출력이나 응용 프로그램 데이터를 저장했다가 다시 사용할 수 있습니다. 이로 인해 서버는 정보를 다시 만들지 않아도 되므로 시간과 리소스가 절약됩니다.

 

ASP.NET은 고성능 웹 응용 프로그램을 만드는 데 사용할 수 있는 두 가지 형식의 캐싱을 제공합니다. 첫째 형식은 출력 캐싱입니다. 이 형식에서는 동적 페이지 및 사용자 정의 컨트롤의 응답을 원래 서버에서 요청 브라우저로의 출력 스트림에 있는 HTTP 1.1 캐시 사용 장치에 저장할 수 있습니다. 이후 요청에 대해서는 이 페이지나 사용자 정의 컨트롤 코드가 실행되지 않고, 대신에 캐싱된 출력이 사용되어 요청을 충족시킵니다. 둘째 형식은 기존의 응용 프로그램 데이터 캐싱입니다. 이 캐싱을 사용하면 데이터 집합과 같은 임의의 개체를 서버 메모리에 체계적으로 저장하여 응용 프로그램이 이 개체를 다시 만드는 데 소요되는 시간 및 리소스를 절약할 수 있습니다.


 
posted by 방랑군 2012. 1. 8. 00:42

출처 :  http://blog.loveciel.kr/23 


 안녕하세요 ^^ 간만에 글을 쓰는 Ciel 입니다.

웹사이트를 구축하고 , 그 사이트를 서비스 하는데 있어서 가장 비용이 많이 드는 작업이 

바로 데이터 바인딩인데 , 반복적인 데이터 바인딩을 피해서, 더 적은 비용으로 

더 빠른 사이트를 운영하기 위해 사용하는 방법이 바로 웹사이트 캐싱입니다.

이번 시간에는 실무에서 사용되는 캐싱 기법중 몇가지를 소개하고자 합니다.


제가 이번에 소개해 드릴 캐싱 전략은 두가지로써, 둘다 실무에 빈번히 쓰이는 기법입니다.




좌측에 보이는 WebRequest는 대규모 사이트에 주로 적합한 방식이지만 , 빈번히 데이타의 내용이 바뀔때는 

그다지 효율적이지 않을수 있습니다.  그에 비해 Cache 를 이용하는방식은 간편하지만 ,  WebRequest 방식보다는

다소 비용이 더 소비 됩니다. 이 두가지 기법을 소개하고 , 두가지의 장단점을 살펴보도록 하겠습니다.





1.WebRequest Stream 을 이용한 캐싱 



첫번째로 소개해 드릴 기법은 WebRequest 객체를 사용해서 캐싱을 구현하는 기법입니다.

이 기법은 데이터 바인딩이 된 페이지의 html 파일을 저장하고 , 기본 호출시에 , 저장된 html 파일을 출력함으로써 , 

반복적인 데이터 바인딩을 피하는 기법입니다.

이 기법은 주로 자료의 양이 많은 포털 사이트등의 메인 페이지에서 널리 사용됩니다.

이 기법을 도식화 하면 다음과 같습니다. 

WebRequest 객체는 HttpRequest 를 수행할 객체를 생성합니다.

그후, 이 객체를 HttpResponse 객체를 이용해 HttpRequest 가 수행된 리턴값을 받아 옵니다.

즉 , Http 통신을 객체를 이용하여 내부적으로 행하는것인데 , 이 방법을 통해서 , 

결과 페이지 Html 을 GetResponseStream()으로 받아와서 저장하면, 모든 준비가 끝난겁니다.^^

다음번 호출부터는 저장된 페이지를 호출함으로써 , 데이터 바인딩을 행하지 않는 완벽한 클론 페이지를 만들수 있게 되는것이죠.

다음은 구현 부분입니다.

설명은 좀 길고 어떻게 보면 난해할수도 있는데(OTL) 코드는 허무하리라 만큼 간단합니다 ^^


1. Request 객체 생성 
2. 생성된 객체로 호출한 결과값 전달받음 
3. 전달받은 객체의 Stream 을 저장


3단계만 기억하면 간단합니다.

그러나 이 기법도 단점이 존재합니다. 웹사이트를 통째로 저장하기 때문에 , ViewState 의 변경상태를 저장하기가 힘들고, 

이는 ASP.NET 의 최대 장점인 ViewState 를 사용하기 힘들다는 헛점으로 이어지게 됩니다.

또,파일 핸들링 자체가 어느정도 비용이 큰 작업이기 때문에 빈번히 파일을 쓸수 없고 , 

이는 일반 게시판 같이 빈번하게 바뀌는 게시물에 대응하기가 힘들다는 단점으로 요약될수 있습니다.

그렇기 때문에 이 기법은, 사용자 게시물이 메인 페이지에 없고  운영자의 취향대로 대문 페이지를 구성해야 하는 

대형 서비스 사이트에 어울리는 기법이라고 할수 있겠습니다.





2. HttpRuntime.Cache


두번째 소개해드릴 기법은 ASP.NET개발을 해보셨다면 누구나 들어보셨을만한 기법인 HttpRuntime.Cache 입니다.

이 객체는 어떠한 닷넷 객체도 캐싱이 가능함으로써 , 상당한 유연함을 지니고 있습니다. 

사용방법도 아주 간단하죠. 그러나 서버자원을 계속해서 사용함으로써, 어느정도 메모리를 

지속적으로 점유해야 하는 리스크를 안고 있습니다.

이 객체를 사용하기에 적합한 예는 , 호출이 빈번하며 , 데이터의 내용이 잘 바뀌지 않는 경우 입니다. 

그리고 만료 시간을 정해줌으로써, 주기적으로 데이터를 가져오거나 , CacheDependency 를 이용해서 Cache를 

Runtime 시에 컨트롤 할수 있습니다. 


다음 코드는 Cache를 이용해서 데이터 테이블을 바인딩 하는 예제를 보여줍니다.


위와 같이 캐쉬를 설정하고 , 캐쉬디펜던시를 설정하게 되면 , 캐쉬디펜던시에 따라서 , 캐쉬가 삭제되게 됩니다.



캐쉬의 장점은 닷넷의 어떠한 객체도 캐싱이 가능하다는점입니다. 

그러나 서버의 리소스를 계속해서 점유하게 되고 , 서비스를 하는 사람 입장에서 , 

이 캐쉬를 지우는것외에 변조가 힘들게 됨으로써 , 이전에 보여드린 WebRequest방식보다는 

다소 유연함이 떨어진다고도 할수 있겠습니다.

 

 

 

마무리.

서비스 하는 사이트가 커짐에 따라 신경써야 할 부분도 많아지고 , 

웹서버의 한계를 극복하기 위한 여러 기법들도 점차로 발전하고 있는 지금 , 

이번에 소개해드린  캐싱 전략은 현재 서비스 하는 사이트의 유지비용을 줄여주는데 

어느정도 힌트가 되어줄수 있다고 생각합니다.

두가지 캐싱기법에 대해 잘 숙지하시고 적재적소에 활용하신다면

사이트 유지에 있어서 큰 이득을 보실수 있을거 같습니다. ^^


 
posted by 방랑군 2012. 1. 8. 00:38

출처 :  http://weblab.tistory.com/218 

웹페이지 전체 혹은 일부 페이지 내에 쓰이는 데이터의 캐싱은 가상화와 더불어 비싼 서버자원을 효율적으로 사용하기 위한 훌륭한 방법 중 하나입니다.

그래서 이번에 살펴보고 적용한 코드를 메모해두려고 합니다.

ASP.NET에서 캐싱은 크게 세 가지 방식으로 나눠집니다.
  1. 페이지 단위 캐싱
    - 페이지에 세션값에 따른 분기가 있다면 캐싱된 데이터가 그대로 뿌려지므로 동작하지 못합니다.
  2. 데이터 단위 캐싱
    - 고정적으로 출력할 데이터만 콜렉션에 관리하므로 세션값이나 기타 파라미터에 따라 페이지 내 동적인 요소를 관리할 수 있습니다.
  3. 컨트롤 단위 캐싱
    - 사용자가 작성한 컨트롤 단위로 캐싱을 선언할 수 있습니다.
먼저 페이지 단위 캐싱은 누가 접속하더라도 동일한 출력물을 표시할 때 유용합니다.

<%@ OutputCache Duration="60" VaryByParam="None" %>

요렇게 선언적으로 프로그래밍하시거나

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);

요렇게 C# 코드로 작성하셔도 됩니다.

그리고 좀 더 자주 쓰지 않을까 싶은 데이터 단위 캐싱을 하려면 Context.Cache 객체에 의존해야 합니다.

//using System.Web.Caching

Cache cache = Context.Cache;
cache.Insert("Pls-Remember-Me", "캐시에 담을 객체 - 지금은 스트링", null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromHours(4));

이렇게 저장해두면 4시간 동안은 IIS가 데이터를 보관해둡니다.

(String)cache["Pls-Remember-Me"]

처럼 접근해서 데이터를 가져올 수 있습니다. 간편하죠? ^^a

사용자 정의 컨트롤의 경우 System.Web.UI.UserControl을 상속받았으면 [PartialCaching(120)]처럼 선언적 프로그래밍이 가능합니다만, 필요에 따라 골라 쓰시면 되겠습니다.

 
posted by 방랑군 2012. 1. 8. 00:34

출처 :  http://blog.naver.com/PostView.nhn?blogId=alfustnals&logNo=140143354888&categoryNo=0&parentCategoryNo=20&viewDate=&currentPage=1&postListTopCurrentPage=1&from=search

 데이터 캐싱을 하는 이유 

 프로젝트를 하면 캐싱을 사용하여 더 효율적으로 자원을 활용한다.

 캐싱은 웹페이지 전체 혹은 일부 페이지 내에 쓰이는데 가상화와 비싼 서버자원을

 효율적으로 사용을 위해 사용 한다.

 뭐 여튼 좋은것이다..;;;

 데이터 캐싱의 3가지 방법

 1] 페이지 단위 캐싱
 2] 데이터 단위 캐싱
   고정적으로 출력할 데이터만 컬렉션에서 관리

   : 세션값이나 기타 파라미터에 따라 페이지 내 동적인 요소를 관리할 수 있다.
 3] 컨트롤 단위 캐싱

 페이징 단위 캐싱 방법

 Response.Cache.SetExpires(DateTime.Now.AddSeconds(0));
 Response.Cache.SetCacheability(HttpCacheability.NoCache);
 Response.Cache.SetValidUntilExpires(true);
 프로젝트에서 이 세구문이 궁금해서 공부 한 것이다. 근데 위에 선언문에다...

 <%@ OutputCache Duration="60" VaryByParam="None" %>

 이런식으로 옆에다 붙여 놓아도 된다고 한다..;;

 데이터 단위 캐싱 방법

 Context.Cache.Insert("MyData", dataset의로도);

 cache.Insert(키,캐쉬에담을객체,의존성,시간);

 Context.Cache.Insert("key",ds);

 Cache.Insert("", ds, null, DateTime.Now.AddMinutes(10), Cache.NoSlidingExpiration);

  ==> 10분 동안 IIS가 데이터를 보관

  ==> (String)cache["키값"] 으로 값을 가져 올 수 있다

 Sliding Expiration -  명시된 기간만큼 접근하지 않으면 만료되어지게 하는 것

 null - 항목과 파일시스템 객체사이의 의존성에 따라...

 사용자 정의 컨트롤 캐싱 방법

 [PartialCaching(20)] : 이런식으로 선언하여 사용

 캐싱 사용 예제 : http://msdn.microsoft.com/ko-kr/

 [PartialCaching(20)]
 public partial class ctlMine : UserControl
{
 protected void Page_Load(Object Src, EventArgs E)
 {
  DataSet ds = new DataSet();
  FileStream fs = new FileStream(Server.MapPath("schemadata.xml"),

                                                    FileMode.Open, FileAccess.Read);
  StreamReader reader = new StreamReader(fs);
  ds.ReadXml(reader);
  fs.Close();

  DataView Source = new DataView(ds.Tables[0]);
  LiteralControl myLiteral = new LiteralControl();
  myLiteral.Text = "<h6><font face=verdana>Caching an XML Table: " +

                                        Source.Table.TableName + " </font></h6>";
  MyDataGrid.DataSource = Source;
  MyDataGrid.DataBind();

  TimeMsg.Text = DateTime.Now.ToString("G");

 }
}

[출처] [ASP.NET] 데이터 캐싱 - Response.Cache.XXX|작성자 도망노비 

'PP > ASP.NET' 카테고리의 다른 글

[캐싱] 웹사이트 캐싱전략  (0) 2012.01.08
[캐싱] 데이터 캐싱 Tips - Context.Cache  (0) 2012.01.08
[asp.net] ashx 이미지 섬네일  (0) 2012.01.06
[asp.net] 이미지 섬네일  (0) 2012.01.06
C# 이미지 섬네일  (0) 2012.01.06
posted by 방랑군 2012. 1. 8. 00:22

ASP.NET의 새 기능

ASP.NET은 오류를 처리하고 응답하는 방법에서 여러 가지 고급 기능을 제공합니다. 기존 ASP에서는 "On Error Resume Next"(또는 JScript의 try-catch 블록)로 오류를 처리합니다. 또는 Microsoft Internet Information Services(IIS) 5.0을 실행하는 경우 ASPError 개체를 사용하여 사용자 지정 오류 보고 페이지를 만듭니다. 그러나 이러한 방법에는 제한이 있습니다.

ASP.NET은 ASP.NET 응용 프로그램을 실행할 때 발생할 수 있는 오류를 처리하고 응답하는 방법을 여러 수준으로 제공합니다. ASP.NET은 오류가 발생할 때 오류를 잡고 응답할 수 있는 세 가지 기본 메서드인 Page_Error 이벤트, Application_Error 이벤트 및 응용 프로그램 구성 파일(Web.config)을 제공합니다.

이 문서에서는 ASP.NET 응용 프로그램의 새 기능을 사용하는 방법을 보여 줍니다. 이 문서에서는 ASP.NET과 직접 관련이 있는 사용자 지정 오류 페이지와 일반 오류 보고를 제공하는 방법을 설명하지만 try-catch-finally 블럭과 CLR(공용 언어 런타임) 예외 시스템 같은 기타 오류 처리 방법은 설명하지 않습니다.


Page_Error 이벤트를 사용하는 방법

Page_Error 이벤트는 페이지 수준에서 발생하는 오류를 잡는 방법을 제공합니다. 다음 예제 코드처럼 간단히 오류 정보를 표시하거나 이벤트를 기록하거나 다른 동작을 수행할 수 있습니다.

이 예제는 null 예외를 발생시켜 Page_Load 이벤트에서 강제로 오류가 발생하도록 합니다. 다음 절차에 따라 Page_Error 이벤트를 테스트하는 초기 페이지를 만듭니다.
  1. 다음 단계에 따라 PageEvent.aspx라는 이름의 새 파일을 프로젝트에 추가합니다.
    1. Microsoft Visual Studio .NET을 엽니다.
    2. 솔루션 탐색기에서 프로젝트 노드를 마우스 오른쪽 단추로 누르고 추가를 가리킨 다음 Web Form 추가를 누릅니다.
    3. 이름 텍스트 상자에 PageEvent.aspx를 입력한 다음 열기를 누릅니다.
  2. 아래 코드를 PageEvent.aspx에 추가합니다.
    <script language=C# runat="server">
         void Page_Load(object sender, System.EventArgs e)
         {
              throw(new ArgumentNullException());
         }
    
         public void Page_Error(object sender,EventArgs e)
         {
              Exception objErr = Server.GetLastError();
              string err = "<b>Error Caught in Page_Error event</b><hr><br>" + 
                  "<br><b>Error in: </b>" + Request.Url.ToString() +
                  "<br><b>Error Message: </b>" + objErr.Message.ToString()+
                  "<br><b>Stack Trace:</b><br>" + 
              Server.GetLastError().ToString();
              EventLog.WriteEntry("MyWebform.aspx",err,EventLogEntryType.Error);
              Server.ClearError();
              Response.Redirect("ErrorPage");
         }
    </script> 
  3. 파일 메뉴에서 PageEvent.aspx 저장을 누릅니다.
  4. 페이지를 마우스 오른쪽 단추로 누른 다음 브라우저에서 보기를 눌러 페이지를 실행합니다. 코드 사양에 따라 오류가 발생하고 보고됩니다.
코드는 Server.ClearError를 호출합니다. 이렇게 하면 Application_Error 이벤트를 계속 처리하는 오류가 방지됩니다.

참고: .aspx 페이지에서 Page_Load 이벤트와 같은 이벤트를 사용할 때 AutoEventWireup 특성 설정을 알고 있어야 합니다. Visual Studio .NET을 사용하는 경우 Visual Studio .NET이 기본적으로 추가하는 템플릿 코드에 이 특성이 @ Page 지시문과 함께 나열됩니다. AutoEventWireup 특성은 기본적으로 False로 설정됩니다. AutoEventWireupTrue로 설정되어 있지 않으면 Page_Load 코드는 절대 호출되지 않으며 그 결과 브라우저는 빈 페이지를 렌더링합니다.

또한 @ Page 지시문에서 Inherits 특성을 주목해야 합니다. Inherits가 설정된 경우 페이지를 탐색하기 전에 프로젝트를 빌드해야 합니다. 먼저 프로젝트를 빌드하지 않으면 다음과 같은 오류 메시지가 나타납니다.

"Project.PageEvent"는 유효한 형식이 아닙니다.

Application_Error 이벤트를 사용하는 방법

Page_Error 이벤트와 비슷하게 Application_Error 이벤트를 사용하여 응용 프로그램에서 발생하는 오류를 잡을 수 있습니다. 이벤트가 적용되는 응용 프로그램의 범위가 넓으므로 응용 프로그램 오류 정보를 기록하거나 다른 응용 프로그램 수준 오류를 처리할 수 있습니다.

다음 예제는 앞의 Page_Error 이벤트 코드 예제를 기반으로 하며 Page_Error 이벤트가 Page_Load 이벤트의 오류를 잡지 못하는 경우 실행됩니다. Application_Error 이벤트는 응용 프로그램의 Global.asax 파일에 지정됩니다. 이 절에서는 간단하게 새로운 페이지를 만들어 예외를 발생시키고, Global.asax 파일의 Application_Error 이벤트에서 오류를 잡고, 이벤트 로그에 기록하는 절차를 설명합니다. 다음 단계는 Application_Error 이벤트를 사용하는 방법을 보여 줍니다.

  1. AppEvent.aspx라는 이름의 새 파일을 프로젝트에 추가합니다.
  2. 아래 코드를 AppEvent.aspx에 추가합니다.
    <script language=C# runat="server">
        void Page_Load(object sender, System.EventArgs e)
        {
             throw(new ArgumentNullException());
        }
    </script>
  3. 파일 메뉴에서 AppEvent.aspx 저장을 누릅니다.
  4. Application_Error 이벤트를 Global.asax 파일에 추가하여 AppEvent.aspx 페이지의 Page_Load 이벤트에서 발생하는 오류를 잡습니다. 이벤트 로그를 사용하려면 System.Diagnostics 네임스페이스에 대해 다른 using 문을 Global.asax에 추가해야 합니다.

    아래 코드를 Global.asax 파일에 추가합니다.
    using System.Diagnostics;
    
    protected void Application_Error(object sender, EventArgs e)
    {
         Exception objErr = Server.GetLastError();
         string err = "<b>Error Caught in Application_Error event</b><hr><br>" + 
     "<br><b>Error in: </b>" + Request.Url.ToString() +
     "<br><b>Error Message: </b>" + objErr.Message.ToString()+ 
     "<br><b>Stack Trace:</b><br>" + 
     Server.GetLastError().ToString();
          EventLog.WriteEntry("Project.AppEvent.aspx",err,EventLogEntryType.Error);
          Server.ClearError();
    }
  5. Global.asax 파일을 저장합니다.
  6. Visual Studio .NET의 빌드 메뉴에서 빌드를 누릅니다.
  7. 페이지를 마우스 오른쪽 단추로 누른 다음 브라우저에서 보기를 누릅니다. 오류 메시지가 Application_Error 이벤트를 참조하고 이전 Page_Error 이벤트 예제와는 약간 다른 스택 추적을 표시합니다.


Web.config 파일을 사용하는 방법

Server.ClearError를 호출하지 않거나 Page_Error 또는 Application_Error 이벤트에서 오류를 잡지 않은 경우 오류는 Web.config 파일의 <customErrors> 구역에 있는 설정에 따라 처리됩니다. <customErrors> 구역에서 리디렉션 페이지를 기본 오류 페이지(defaultRedirect)로 지정하거나 발생하는 HTTP 오류 코드를 기반으로 특정 페이지를 지정할 수 있습니다. 또한 나타나는 오류 메시지를 사용자 지정할 수 있습니다.

오류가 발생하였는데 응용 프로그램의 이전 수준에서 잡지 못한 경우 사용자 지정 페이지가 표시됩니다. 이 절에서는 Server.ClearError가 절대 호출되지 않도록 Global.asax 파일을 수정하는 방법을 보여 줍니다. 결과적으로 오류를 잡는 마지막 지점인 Web.config 파일에서 오류가 처리됩니다.
  1. 이전 예제에 나타난 Global.asax 파일을 엽니다.
  2. Server.ClearError 줄을 주석으로 처리하여 Web.config 파일에 오류가 발생할 수 있도록 합니다.
  3. 변경 내용을 Global.asax에 저장합니다. 이제 코드는 다음과 비슷하게 나타납니다.
    using System.Diagnostics;
    
    protected void Application_Error(object sender, EventArgs e)
    {
         Exception objErr = Server.GetLastError();
         string err = "<b>Error Caught in Application_Error event</b><hr><br>" + 
               "<br><b>Error in: </b>" + Request.Url.ToString() +
               "<br><b>Error Message: </b>" + objErr.Message.ToString()+ 
               "<br><b>Stack Trace:</b><br>" + 
               Server.GetLastError().ToString();
         EventLog.WriteEntry("Project.AppEvent.aspx",err,EventLogEntryType.Error);
         //Server.ClearError();
    }
  4. 다음 코드를 <customErrors> 구역에 추가하여 사용자를 사용자 지정 페이지로 리디렉션합니다.
    <customErrors defaultRedirect
    ="http://hostName/applicationName/errorStatus.htm" mode="On"> </customErrors>
    참고: 관련 웹 서버와 응용 프로그램 이름을 참조하도록 defaultRedirect 특성에서 파일 경로를 수정해야 합니다.
  5. 이 수준에서 잡힌 오류는 기본 오류 페이지로 보내지기 때문에 ErrorStatus.htm이라는 이름의 오류 페이지를 만들어야 합니다. 사용자에게 표시하는 내용을 제어하기 위해 이 방법을 사용하는 것이므로 이 예제에서는 오류 페이지로 .htm 페이지를 사용합니다. 다음 코드를 ErrorStatus.htm에 추가합니다.
    <HTML>
    <HEAD>
    <TITLE></TITLE>
    <META NAME="GENERATOR" Content="Microsoft Visual Studio 7.0">
    </HEAD>
    <BODY>
         <b>Custom Error page!</b>
         <br>
         You have been redirected here from the &lt;customErrors&gt; 
    section of the Web.config file. </BODY> </HTML>
  6. 코드를 테스트하려면 파일을 저장하고 프로젝트를 빌드한 다음 브라우저에서 AppEvent.aspx를 봅니다. 오류가 발생하면 ErrorStatus.htm 페이지로 리디렉션됩니다.
<customErrors> 구역에 있는 defaultRedirect 특성의 값으로 기본 오류 페이지를 참조할 수 있지만 HTTP 오류 코드를 기반으로 하는 특정 페이지로 리디렉션하도록 지정할 수 있습니다. <error> 자식 요소는 이 옵션을 허용합니다. 예를 들면 다음과 같습니다.
<customErrors 
defaultRedirect="http://hostName/applicationName/errorStatus.htm" mode="On"> <error statusCode="404" redirect="filenotfound.htm" /> </customErrors>
참고: <customErrors> 구역의 defaultRedirect에 지정된 페이지는 .htm 파일입니다. Page_ErrorApplication_Error 예제 처럼 .aspx 페이지에서 GetLastError를 사용하려면 리디렉션이 발생하기 전에 세션 변수나 다른 방법에서 예외를 저장해야 합니다.

<customErrors> 구역은 On으로 설정된 mode 특성을 포함하고 있습니다. mode 특성은 오류 리디렉션이 발생하는 방법을 제어하는 데 사용됩니다. 예를 들어, 응용 프로그램을 개발 중이라면 대부분 사용자에게 익숙한 오류 페이지로 리디렉션되는 것보다 실제 ASP.NET 오류 메시지를 표시하는 것이 더 낫습니다. mode 특성을 다음과 같이 설정할 수 있습니다.
  • On: 처리되지 않은 예외는 지정된 defaultRedirect 페이지로 사용자를 리디렉션합니다. 이 모드는 주로 프로덕션 환경에서 사용됩니다.
  • Off: 예외 정보가 표시되고 defaultRedirect 페이지로 리디렉션되지 않습니다. 이 모드는 주로 개발 환경에서 사용됩니다.
  • RemoteOnly: localhost를 사용하여 로컬 컴퓨터에 있는 사이트에 액세스하는 사용자에게만 예외 정보가 표시됩니다. 다른 모든 사용자는 defaultRedirect 페이지로 리디렉션됩니다. 이 모드는 주로 디버깅에 사용됩니다.

출처: 닷넷 (.NET) 프로그래머 모임 (http://cafe.daum.net/aspdotnet)

posted by 방랑군 2012. 1. 7. 22:04




1. 
    <script type="text/javascript">
        $(document).ready(function () {
            $("#button").click(function () {
                $.ajax({
                    type: "post",
                    url: "Service1.asmx/GetDataset",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    dataFilter: function (data) {
                        //debugger
                        alert(data);
                        var msg;
                        if (typeof (JSON) !== 'undefined' && typeof (JSON.parse) === 'function') {
                            msg = JSON.parse(data);
                        } else {
                            msg = eval('(' + data + ')');
                        }
                        if (msg.hasOwnProperty('d')) {
                            return msg.d;
                        } else {
                            return msg;
                        }
                    },
                    success: function (data) {
                        //debugger
                        alert(data);
                        $("#groupName").text(data.groupName);
                        $("#memberList").text(data.memberList);
                    }
                });
            });
        });
    </script>

2.
    // ASP.NET AJAX를 사용하여 스크립트에서 이 웹 서비스를 호출하려면 다음 줄의 주석 처리를 제거합니다. 
    [System.Web.Script.Services.ScriptService]

.
.
 
        [WebMethod]
        public string GetDataset()
        {            
            DataSet ds = GetDS();
            JavaScriptSerializer jss = new JavaScriptSerializer();
            DataSetConverter dsc = new DataSetConverter();
            IDictionary<string, object> retVal = dsc.Serialize(ds, jss);
            string result = jss.Serialize(retVal);
            return result;
        } 
        private DataSet GetDS()
        {
            DataSet ds;

            VTFramework.DB.vCS_DB_MSSQL db = new VTFramework.DB.vCS_DB_MSSQL("data source='localhost';initial catalog='REQUEST_MANAGE';password='simple2009';user id='sa';");

            db.mLoad();

            ds = db.mGetEx("SELECT * from [REQUEST_MANAGE].[dbo].[USER_MANAGE]");

            db.mDispose();

            return ds;
        }

3.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Web.Script.Serialization;
using System.Data;
using System.Collections;
using System.Collections.ObjectModel;

namespace AjaxWithJson
{
    public class DataSetConverter : JavaScriptConverter
    {
        public override IEnumerable<Type> SupportedTypes
        {
            //Define the DataTable as a supported type.
            get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(DataSet) })); }
        }
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            Dictionary<string, object> dtDic = new Dictionary<string, object>();
            DataSet ds = obj as DataSet;
            foreach (DataTable dt in ds.Tables)
            {
                // Create the representation.
                Dictionary<string, object> rowDic = new Dictionary<string, object>();
                int i = 0;
                foreach (DataRow row in dt.Rows)
                {
                    //Add each entry to the dictionary.
                    Dictionary<string, object> colDic = new Dictionary<string, object>();
                    foreach (DataColumn col in row.Table.Columns)
                    {
                        colDic.Add(col.ColumnName, row[col]);
                    }
                    rowDic.Add("row" + (i++).ToString(), colDic);
                }
                dtDic.Add(dt.TableName, rowDic);
            }
            return dtDic;
        }
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");
            if (type == typeof(DataTable))
            {
                // Create the instance to deserialize into.
                DataTable list = new DataTable();
                // Deserialize the ListItemCollection's items.
                ArrayList itemsList = (ArrayList)dictionary["Rows"];
                for (int i = 0; i < itemsList.Count; i++)
                    list.Rows.Add(serializer.ConvertToType<DataRow>(itemsList[i]));
                return list;
            }
            return null;
        }
    }
}


4. ASHX

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Web.SessionState;

namespace AjaxWithJson
{
    /// <summary>
    /// ConfirmBitmapHandler의 요약 설명입니다.
    /// </summary>
    public class ConfirmBitmapHandler : IHttpHandler, IRequiresSessionState 
    {

        public void ProcessRequest(HttpContext context)
        {
           // context.Response.ContentType = "text/plain";
           // context.Response.Write("Hello World");

                context.Response.ContentType = "image/jpeg";
               // 이미지 사이즈
               int lenX = 80, lenY = 30;     
               Bitmap bm              = new Bitmap( lenX, lenY );
               Graphics g             = Graphics.FromImage( bm );
               // 배경으로 그라데이션 처리
               LinearGradientBrush bgGr = new LinearGradientBrush(
                       new Point(0,0),
                       new Point(lenX, lenY),
                       Color.Blue,
                       Color.Black);                             

               g.FillRectangle( bgGr, 0, 0, lenX, lenY );              

               // 5자리 숫자의 난수를 발생하여 텍스트를 만든다  
               string text = string.Empty;
               Random rnd = new Random();
               for(int i=0; i<5; i++)
               {
                       text += rnd.Next(9).ToString();
               }

               // 텍스트를 그린다.
               Brush textBrush        = new SolidBrush( Color.White );
               g.DrawString( text, new Font("굴림", 15), textBrush, 10, 5, StringFormat.GenericDefault );              

               // 스트림에 비트맵을 쓴다.
               bm.Save( context.Response.OutputStream, ImageFormat.Jpeg );               

               // 5자리 숫자를 세션에 담는다.
               context.Session["ValidateString"] = text;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }



-------------------------------------------------------
 
posted by 방랑군 2012. 1. 7. 21:56

출처 : http://blog.naver.com/umjunil?Redirect=Log&logNo=140035839239

정말 간만에 다시 글을 쓰게 되었네여~

세월아~ 네월아~~

오늘은 자동가입방지, 또는 자동댓글/글쓰기 방지를 위해 뭐좀 하나 만들어 보았습니다.

이번 방법은 제네릭 처리기를 이용하려고 합니다.

우선 다음과 같이 제네릭 처리기를 새항목 추가 합니다.

제네릭 처리기가 뭘까 해서 MSDN 을 보니…. 안나왔더군요~

우선 제네릭 처리기를 생성해 보기로 하겠습니다.

<![endif]>

.. 단순히 IHttpHandler 를 상속하였네요~

친절하게도 Hello World 와 함께 말이져~

요놈은 IIS C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll 과 같이 매핑이 되어있으며, C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\Web.Config

<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory"

validate="true" /> 과 같이 핸들러가 등록 되어 있군요~,

결론은 IHttpHandler 를 구현하라는 것이네요.

그럼 ConfirmBitmapHandler.ashx 의 소스를 보여드립니다.

<%@ WebHandler Language="C#" Class="ConfirmBitmapHandler" %>

using System;

using System.Web;

using System.Drawing;

using System.Drawing.Imaging;

using System.Drawing.Drawing2D;

using System.Web.SessionState;

public class ConfirmBitmapHandler : IHttpHandler, IRequiresSessionState {

public void ProcessRequest (HttpContext context) {

context.Response.ContentType = "image/jpeg";

// 이미지 사이즈

int lenX = 80, lenY = 30;

Bitmap bm = new Bitmap( lenX, lenY );

Graphics g = Graphics.FromImage( bm );

// 배경으로 그라데이션 처리

LinearGradientBrush bgGr = new LinearGradientBrush(

new Point(0,0),

new Point(lenX, lenY),

Color.Blue,

Color.Black);

g.FillRectangle( bgGr, 0, 0, lenX, lenY );

// 5자리 숫자의 난수를 발생하여 텍스트를 만든다

string text = string.Empty;

Random rnd = new Random();

for(int i=0; i<5; i++)

{

text += rnd.Next(9).ToString();

}

// 텍스트를 그린다.

Brush textBrush = new SolidBrush( Color.White );

g.DrawString( text, new Font("굴림", 15), textBrush, 10, 5, StringFormat.GenericDefault );

// 스트림에 비트맵을 쓴다.

bm.Save( context.Response.OutputStream, ImageFormat.Jpeg );

// 5자리 숫자를 세션에 담는다.

context.Session["ValidateString"] = text;

}

public bool IsReusable {

get {

return false;

}

}

}

그럼 이제 우리가 만든 ConfirmBitmapHandler.ashx 를 브라우져 보기를 통해 실행해 보십시오

실행결과>>>

<![endif]>

오오~~~~~ 짝짝짝~~ 잘 실행이 되었네여~

그럼 다음으로 방금 만든 전처리기를 이용하여 웹어플케이션을 만들어 봅시다.

소스 ( Default.aspx )

<%@ 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">

private void Page_Load(object sender, EventArgs e)

{

}

protected void lnkValidate_Click(object sender, EventArgs e)

{

string validateString = (string)Session["ValidateString"] ?? string.Empty;

if (txtValidateString.Text == validateString )

lblResult.Text = "오케이~~ 통과~!";

else

lblResult.Text = "틀렷삼~~~~~ ";

}

</script>

<script type="text/javascript">

function checkEnter()

{

if( event.keyCode == 13 )

{

__doPostBack('lnkValidate','');

}

else

return true;

}

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>제목 없음</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<img src="ConfirmBitmapHandler.ashx" />

<p></p>

<asp:TextBox ID="txtValidateString" runat="server" onkeypress="return checkEnter()"></asp:TextBox>&nbsp;&nbsp;&nbsp;

<asp:LinkButton ID="lnkValidate" runat="server" OnClick="lnkValidate_Click">확인</asp:LinkButton>

<p></p>

<asp:Label ID="lblResult" runat="server"></asp:Label>

</div>

</form>

</body>

</html>

이 소스는 대부분 어렵지 않게 보실 수 있을 것 같아서 특별히 주석은 안달았습니다.

[출처] 제네릭 처리기를 이용하여 자동가입방지 폼 구현|작성자 땡초