웹사이트가 로드되면 Web.config의 appSetting정보가 메모리 상으로 올라가게 되고 그 값을 읽고 올라간 정보를 변경 할 수도 있다.

1. appSetting값 읽기

string value = System.Web.Configuration.WebConfigurationManager.AppSettings.Get("appValue");

또는

string value = System.Web.Configuration.WebConfigurationManager.AppSettings["appValue"];

2. appSetting값 변경

System.Web.Configuration.WebConfigurationManager.AppSettings.Set("appValue", "test");

위와 같이 하면 XML파일의 값은 변경되지 않지만

현재 appValue로 읽어오는 appSetting값은 웹사이트가 다시 시작하지 않는 이상 계속 test라는 값을 읽어온다.

3. 간단하게 appSetting.xml파일 변경하기

 

string key = "appValue";

string value = "test2"; 

DataSet ds = new DataSet();

ds.ReadXml("D:\\AppSettings.xml");

if (dsRs.Tables.Count > 0) {

DataTable dt = ds.Tables[0];

if (dt.Rows.Count > 0) {

for (int r = 0; r < dt.Rows.Count; w++) {

//그냥 찍어보는 for문 ㅋㅋ

for (int c = 0; c < dt.Columns.Count; i++) {

Response.Write(r + "/" + i + " : " + dt.Rows[r][c].ToString() + "<br />");

}

if (dt.Rows[r][0].ToString() == key) {

dt.Rows[r][c] = value;

System.Web.Configuration.WebConfigurationManager.AppSettings.Set(dt.Rows[r][0].ToString(), value);

}

}

}

ds.WriteXml("D:\\AppSettings.xml"); 

}

위의 예제는 간단하게 메모리상의 appSetting값을 변경하고 XML파일로 저장한다.

지금은 AppSettings.xml에 값이 있는 경우에만 수정이 가능한데

위의 예제로 쉽게 응용하여 새로운 값을 추가, 삭제도  쉽게 할 수 있을 것이다.

만약 appSettings가 자주 변경이 일어 나게 된거나 connectStrings 정보를 Web.config파일에 입력하지 않길 원한다면

아래와 같이 이 두 속성에 대해 따로 xml파일로 관리를 할 수 있다.

 

<appSettings configSource="App_Data\파일명.xml"/>
<connectionStrings configSource="App_Data\파일명.xml"/>

 

<appSettings file="경로\파일명.xml"/>

 

appSettings 와 같은 경우 configSource 또는 file 특성을 사용할 수 있다.

configSource 는 ASP.NET 프로젝트의 APP_Data 폴더에 파일을 두고 사용할 경우에 해당 특성을 사용하며

file과 같은 경우는 로컬 컴퓨터의 어디 위치에 상관없이 사용이 가능하다.

 

 

 위와 같이 파일로 설정을 뺀 이유는 다음과 같다.

  1. 어트리뷰트를 이용하여 특정 Configuration Section의 Subset을 다른 XML 파일로부터 가져오도록 처리 할 수 있다.
  2. 해당 XML 파일의 내용이 바뀌더라도 동적 컴파일이 발생하지 않는 유연성을 확보할 수 있다.

  

 

ASP.NET이라는 언어를 공부를 안한 상태로 처음 프로젝트를 진행했을 때의 일이다.

 

어느날인가 DB에서 불러온 값을 수정 한 후 다시 저장을 하는데 계속 같은 값으로 나오는 것이다.

수차례 클릭을 하면서 저장하는 이벤트 로직과 페이지를 봤지만 특별이 문제가 없었다

그때는 당연히 저장되어야 한다고 생각했다;;

 

대부분은 Copy&Paste로 작업을 해서 그런 문제가 생겼다고 생각을 해

수정이 잘되는 페이지를 열어 본 후 다른점을 발견했다

 

그것이 바로 IspostBack 이라는 것이 Page_Load부분에 들어가 있는 것이였다.

변경후 수정이 잘되는 페이지에는

if(!IsPostBack) {

//데이터 불러온 값을 처리하는 함수

}

와 같은 구조로 되어 있었다.

 

ASP.NET은 기존 다른 WEB PROGRAMMING과는 다른 구조로 되어 있다.

이벤트라는 것을 통하여 자신의 페이지를 POSTBACK 하는 방식으로 데이터를 처리 한다.

 

문제는 수정 버튼을 클릭했을 때 POSTBACK이 일어난다. 그 순간 다시 자신의 페이지를 읽으면서 Page_Load 이벤트를 타게된다.

원래 수정하고자 했던 텍스트 박스에는 다시 DB에서 불러온 값을 다시 넣을 것이고 결국 그 값으로 저장이 된 것이다.

그래서 내가 수정하고자 했던 정보는 계속 같은 값으로 나왔던 것이다.

 

ASP.NET에서는 기본적으로 페이지 수명 주기 이벤트를 이해해야 한다.

  

 페이지 이벤트  일반적인 용도 

 PreInit

이 이벤트의 용도는 다음과 같습니다.

  • IsPostBack 속성을 검사하여 페이지가 처음으로 처리되는 것인지 여부를 확인합니다.
  • 동적 컨트롤을 만들거나 다시 만듭니다.
  • 마스터 페이지를 동적으로 설정합니다.
  • Theme 속성을 동적으로 설정합니다.
  • 프로필 속성 값을 읽거나 설정합니다.

 참고
 요청이 포스트백인 경우에는 컨트롤의 값이 뷰 상태에서 아직 복원되지 않았습니다. 이 단계에서 컨트롤 속성을 설정하면 다음 이벤트에서 속성 값이 덮어쓰여질 수 있습니다.

 

 Init 

 모든 컨트롤을 초기화하고 모든 스킨 설정을 적용한 후에 발생합니다. 이 이벤트를 사용하여 컨트롤 속성을 읽거나 초기화할 수 있습니다.

 InitComplete  Page 개체를 통해 발생합니다. 이 이벤트를 사용하여 모든 초기화를 완료해야 할 작업을 처리할 수 있습니다.
 PreLoad

 이 이벤트는 Load 이벤트에 앞서 페이지나 컨트롤을 처리해야 하는 경우에 사용합니다.

 

Page에서 이 이벤트가 발생한 후에 해당 페이지와 모든 컨트롤에 대한 뷰 상태를 로드하고 Request 인스턴스에 포함된 모든 포스트백 데이터를 처리합니다.

 Load

 Page에서 Page에 대해 OnLoad 이벤트 메서드를 호출한 다음 자식 컨트롤 각각에 대해 동일한 과정을 되풀이합니다. 이 과정이 페이지와 모든 컨트롤을 로드할 때까지 해당 자식 컨트롤 각각에 대해 동일하게 진행됩니다.

 

OnLoad 이벤트 메서드를 사용하면 컨트롤의 속성을 설정하고 데이터베이스 연결을 설정할 수 있습니다.

 컨트롤 이벤트

 이러한 이벤트를 사용하면 Button 컨트롤의 Click 이벤트나 TextBox 컨트롤의 TextChanged 이벤트 같은 특정 컨트롤 이벤트를 처리할 수 있습니다.

 

 참고
 포스트백 요청에서 페이지에 유효성 검사기 컨트롤이 포함되어 있으면 처리를 수행하기 전에 Page 및 각 유효성 검사기 컨트롤의 IsValid 속성을 확인합니다.

 

 LoadComplete  이 이벤트는 페이지의 다른 모든 컨트롤을 로드해야 하는 작업에 대해 사용합니다.
 PreRender

 이 이벤트가 발생하기 전에 다음 과정이 진행됩니다.

  • Page 개체에서 각 컨트롤과 페이지에 대해 EnsureChildControls를 호출합니다.
  • 해당 DataSourceID 속성이 설정되어 있는 데이터 바인딩된 컨트롤 각각에서 해당 DataBind 메서드를 호출합니다. 자세한 내용은 이 항목의 뒷부분에 나오는 데이터 바인딩된 컨트롤에 대한 데이터 바인딩 이벤트를 참조하십시오.

페이지의 각 컨트롤에 대해 PreRender 이벤트가 발생합니다. 이 이벤트를 사용하여 페이지나 해당 컨트롤의 내용을 최종적으로 변경할 수 있습니다.

 SaveStateComplete

 이 이벤트가 발생하기 전에 페이지와 모든 컨트롤에 대해 ViewState가 저장됩니다. 이 시점에서 페이지나 컨트롤에 대한 변경 내용은 모두 무시됩니다.

 

이 이벤트를 사용하여 뷰 상태 저장이 필요한 작업을 수행할 수 있지만 컨트롤을 변경할 수는 없습니다.

 Render

 이는 이벤트가 아닙니다. 대신, 이 처리 단계에서 Page 개체가 각 컨트롤에 대해 이 메서드를 호출합니다. 모든 ASP.NET 웹 서버 컨트롤에는 브라우저에 보내는 컨트롤의 태그를 작성하는 Render 메서드가 있습니다.

 

사용자 지정 컨트롤을 만드는 경우 일반적으로 이 메서드를 재정의하여 컨트롤의 태그를 출력합니다. 그러나 사용자 지정 컨트롤에 표준 ASP.NET 웹 서버 컨트롤만 포함되어 있고 사용자 지정 태그는 포함되지 않은 경우 Render 메서드를 재정의할 필요가 없습니다. 자세한 내용은 사용자 지정 ASP.NET 서버 컨트롤 개발을 참조하십시오.

 

사용자 정의 컨트롤(.ascx 파일)에는 렌더링이 자동으로 포함되므로 코드에서 컨트롤을 명시적으로 렌더링할 필요가 없습니다.

 Unload

 이 이벤트는 각 컨트롤에 대해 발생한 다음 페이지에 대해 발생합니다. 컨트롤에서 이 이벤트를 사용하면 컨트롤별 데이터베이스 연결을 닫는 등 특정 컨트롤에 대한 최종 정리 작업을 수행할 수 있습니다.

페이지 자체에 대해 이 이벤트를 사용하면 열려 있는 파일 및 데이터베이스 연결을 닫거나 로깅 또는 기타 요청에 따른 작업을 마무리하는 등의 최종 정리 작업을 수행할 수 있습니다.

 

 참고
언로드 단계를 수행하는 동안 페이지와 페이지 컨트롤이 렌더링되었으므로 응답 스트림을 추가로 변경할 수 없습니다. Response.Write 등의 메서드를 호출하려고 하면 페이지에서 예외가 throw됩니다.

 

 출처: http://msdn.microsoft.com/ko-kr/library/ms178472.aspx ( MSDN )

 

 추가적인 정보 또한 위의 페이지에 친절하게 나와 있다.

 

최대 요청 길이를 초과했습니다.

 

System.Web.Services.Protocols.SoapException: Config 파일에 지정된 확장을 실행하는 동안 예외가 발생했습니다.

System.Web.HttpException: 최대 요청 길이를 초과했습니다.

 

Web.config 파일의

<httpRuntime executionTimeout="90" maxRequestLength="10240" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100" enableVersionHeader="true" />

 

maxRequestLength 를 늘려주세요.

단위는 kb 입니다.

 

액션 필더 이해하기

  

이 장에서 목표는 액션 필더를 설명하는 것이다. 액션 필터는 여러분이 컨트롤러 액션을 응용할 수 있는 속성이다.

ASP.NET MVC 프레임웍은 여러 액션 필터를 포함한다.

l   OutputCache – 이 액션 필터는 특정한 시간을 위한 컨트롤러 액션의 결과를 저장한다.

l   HandleError – 이 액션 필터는 컨트롤러 액션이 실행될 때 발생하는 에러를 잡아낸다.

l   Authorize – 이 액션 필터는 개개인의 사용자 또는 룰을 통해 접근을 제한할 수 있다.

 

여기서는 OutputCache 액션 필터에 대해서만 알아보겠다.

액션 필터는 attribute이다. 각각의 컨트롤러 또는 전체 컨트롤러에서 모두 액션 필터를 적용할 수 있다.

 

다음 예제는  Index() 액션의 결과를 10초동안 저장하는 예제이다.

 

//[OutputCache(Duration = 10)] 사이트소스ㅡㅡ)+ 에러발생아놔~

[OutputCache(Duration = 10, VaryByParam="none")]

public string Index()

{

    return DateTime.Now.ToString("T");

}

 

주소창에 URL /Data/Index입력하고 리플래쉬를 하면 10초동안 동일한 시간을 보게 될 것이다.

 OutputCache 액션 필터를 10초동안 Index() 페이지에 적용시켰다.

 

 

다른 타입의 필터

 

ASP.NET MVC 프레임웍은 4개의 다른 타입의 필터를 제공한다.

1.      Authorization Filters – IauthorizationFilter  속성을 구현

2.      Action Filter - IActionFilter 속성을 구현

3.      Result Filter – IresultFilter 속성을 구현

4.      Exception Filters – IexceptionFilter 속성 구현

 

필터는 위에 나열된 순서대로 실행이 된다.

 

 

Base ActionFilterAttribute Class

 

이 장에서는 여러분이 쉽게 커스텀 액션 필터, ASP.NET framework에 포함된 기본 ActionFilterAttribute 클래스로 구현을 쉽게 만들 것이다. 

이 클래스는 필터 클래스로부터 상속 받는 IActionFilter IResultFilter 인터페이스 둘다 구현을 한다.

 

base ActionFilterAttribute 클래스는 다음과 같은 메서드를 override 할 수 있다.

l   OnActionExecuting – 이 메소드는 컨트롤 액션 전에 실행이 된다.

l   OnActionExecuted – 이 메소드는 컨트롤 액션 후에 실행이 된다.

l   OnResultExecuting – 이 메소드는 컨트롤 액션 결과 전에 실행된다.

l   OnResultExecuted – 이 메소드는 컨트롤 액션 결과 후에 실행된다.

 

 

Creating a Log Action Filter

 

이 장에서는 커스텀 액션 필터를 어떻게 만들지에 대해 설명한다.

우리는 Visual Studio Output 윈도우에 컨트롤 액션의 상태 단계 로그의 커스텀 액션 필터를 만들 것이다.

LogActionFilter Listing2에 포함되어 있다.

 

using System;

using System.Diagnostics;

using System.Web.Mvc;

using System.Web.Routing;

 

namespace MvcApplication1.ActionFilters

{

    public class LogActionFilter : ActionFilterAttribute

    {

        public override void OnActionExecuting(ActionExecutingContext filterContext)

        {

            Log("OnActionExecuting", filterContext.RouteData);

        }

 

        public override void OnActionExecuted(ActionExecutedContext filterContext)

        {

            Log("OnActionExecuted", filterContext.RouteData);

        }

 

        public override void OnResultExecuting(ResultExecutingContext filterContext)

        {

            Log("OnResultExecuting", filterContext.RouteData);

        }

 

        public override void OnResultExecuted(ResultExecutedContext filterContext)

        {

            Log("OnResultExecuted", filterContext.RouteData);

        }

 

        private void Log(string methodName, RouteData routeData)

        {

            var controllerName = routeData.Values["controller"];

            var actionName = routeData.Values["action"];

            var message = String.Format("{0} controller:{1} action:{2}", methodName,

                                controllerName, actionName);

            Debug.WriteLine(message, "Action Filter Log");

        }

 

    }

}

 

Listing2에서 OnActionExcuting(), OnActionExcuted(), OnResultExecuting(), OnResultExecuted() 메소드를 Log()메소드에서 모두 호출한다.

메소드명과 정확한 라우트 데이터는 Log() 메소드를 통과한다.

Log() 메소드는 Visual Studio Output 윈도우에 메시지를 출력한다. ( 디버그 모드로 )

 

 

 

Home컨트롤러의 Index() 액션이든 아니든 Home컨트롤러에의 모든 액션에 대해서 동작을 한다.

그 동작된 내용을 Output창에 출력이 된다.

 

namespace ExamActionFilter.Controllers

{

    //[HandleError]

    [LogActionFilter]

    public class HomeController : Controller

    {

        public ActionResult Index()

        {

            return View();

        }

 

        public ActionResult About()

        {

            return View();

        }

    }

}

 

여기까지 간단한 액션 필터를 구현하는 것을 배웠다.

 

마스터 페이지

 

이 단원에서는 공통 페이지 레이아웃을 만드는 방법에 대해 배울 것이다.

마스터 페이지의 강점을 배우고 사이트에 로고나 메뉴 링크 그리고 배너 광고를 마스터 페이지 내에 배치하는 것을 배울 것이다.

 

마스터 페이지 만들기

 

 

하나의 어플리케이션 안에 하나 이상의 마스터 페이지를 만들 수 있으며 각각의 마스터 페이지는 각각 다른 레이아웃을 정의 할 수 있다.

 

컨텐츠 페이지 만들기

마스터 페이지를 만든 이후 마스터 페이지를 기본으로 하나 이상의 컨텐츠 페이지를 만들 수 있다.

 

 

  

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">

    브라우저 타이틀 변경

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

 

    <h2>Contents Page</h2>

 

 

</asp:Content>

 

 

추가한 index 페이지에서 타이틀을 변경한 내용이다. 마스터 페이지의 타이틀 부분에 컨텐츠를 만들어 놓으므로써

각 컨텐츠 페이지의 타이틀을 넣을 수 있다.

 

 

마스터 페이지로 데이터 전달

 

이 단원의 목표는 마스터 페이지에 데이터 전달할 수 있는가를 설명하고 있다.

영화 데이터베이스를 구축하고 영화 카테고리 테이블과 영화 목록 테이블 2개를 만들 것이다.

카테고리를 뿌려주고 그 뿌려준 카테고리에 속한 영화 리스트를 보여줄 것이다.

 

 

데이터베이스 Movies를 만들자. 만들어진 데이터베이스를 더블 클릭하면 서버 탐색기로 이동하여 해당 데이터베이스의 정보를 볼 수 있다.

 

 

 

모델 폴더에 해당 데이터베이스 관련된 LINQ to SQL을 생성한다

 

 컨트롤러 페이지

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using MvcApplication1.Models;

 

namespace MvcApplication1.Controllers

{

    [HandleError]

    public class HomeController : Controller

    {

        private MoviesDataContext _dataContext = new MoviesDataContext();

 

        public ActionResult Index()

        {

            ViewData["categories"] = from c in _dataContext.MovieCategory

                                     select c;

            ViewData["movies"] = from m in _dataContext.Movie

                                 select m;

            return View();

        }

 

        public ActionResult Details(int id)

        {

            ViewData["categories"] = from c in _dataContext.MovieCategory

                                     select c;

            ViewData["movies"] = from m in _dataContext.Movie

                                 where m.CategoryId == id

                                 select m;

            return View();

        }

    }

}

 

 디테일 페이지

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<%@ Import! Namespace="MvcApplication1.Models" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">

        Details

</asp:Content>

 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Details</h2>

    <% foreach (var m in (IEnumerable<Movie>)ViewData["movies"])

         { %>

         <li><%= m.title %></li>

 

    <% } %>

</asp:Content>

 

 마스터 페이지

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<%@ Import! Namespace="MvcApplication1.Models" %>

 

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

 

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

<head runat="server">

    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>

</head>

<body>

    <div>

        <h1>My Web Site</h1>

       

          <% foreach (var c in (IEnumerable<MovieCategory>)ViewData["categories"])

             {%>

               <%= Html.ActionLink(c.name, "Details", new {id=c.id} ) %>

 

          <% } %>

   

        <asp:ContentPlaceHolder ID="MainContent" runat="server">

       

        </asp:ContentPlaceHolder>

    </div>

</body>

</html>

 

위의 소스는 마스터 페이지에서 영화 카테고리를 클릭하면 해당 카테고리에 속한 영화 타이틀이 출력되는 예제이다.

 

 위의 소스는 마스터 페이지에서 영화 카테고리를 클릭하면 해당 카테고리에 속한 영화 타이틀이 출력되는 예제이다.

 

 

Good Solution

위의 예제는 심플하게 데이터를 뿌려주고 있다. 하지만 컨트롤러 소스를 보면 영화 카테고리 정보를 중복되게 사용하는 것을 보게 될 것이다.

왜 중복되게 보내는 것일까? 그 이유는 마스터에서 사용하는 카테고리 ViewData 때문이다.

이 단원에서 배울 것은 위의 예제를 좀 더 개선하여 좋을 프로그램으로 만드는 것이 목적이다.

 

우리는 컨트롤러에 추상화로 구현한 클래스를 하나 만들 것이다.

이 클래스의 역할은 Movie데이터를 사용할 수 있게 속성(프로퍼티)을 하나 제공하며 생성자에서 카테고리 정보를 ViewData로 만들어 주는 것을 한다.

그리고 잊으면 안되는 것이 이 클래스는 컨트롤러를 상속 받는 것이다.

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

using MvcApplication1.Models;

 

namespace MvcApplication1.Controllers

{

    public abstract class ApplicationController : Controller

    {

        private MoviesDataContext _dataContext = new MoviesDataContext();

 

        public MoviesDataContext DataContext

        {

            get { return _dataContext; }

        }

 

        public ApplicationController()

        {

            ViewData["categories"] = from c in DataContext.MovieCategory

                                     select c;

        }

    }

}

 

해당 추상 클래스를 사용할 Movies컨트롤을 만들겠다.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Mvc.Ajax;

using MvcApplication1.Models;

 

namespace MvcApplication1.Controllers

{

    public class MoviesController : ApplicationController

    {

        /// <summary>

        /// Show list of all movies

        /// </summary>

        public ActionResult Index()

        {

            ViewData["movies"] = from m in DataContext.Movie

                                 select m;

            return View();

        }

 

        /// <summary>

        /// Show list of movies in a category

        /// </summary>

        public ActionResult Details(int id)

        {

            ViewData["movies"] = from m in DataContext.Movie

                                 where m.CategoryId == id

                                 select m;

            return View();

        }

    }

}

 

소스를 보면 알듯이 ApplicationController를 상속 받아 Movie데이터를 사용하는 것을 볼 수 있다.

그리고 달라진 것이 마스터에 보내야 하는 정보를 이미 추상 클래스에서 해결을 했으므로 Movies컨트롤러에서는 할 필요가 없어진 것이다.

 

Controller를 상속 받은 클래스로 인해 추상 클래스를 상속 받은 모든 클래스는 어느 액션이든 호출될 때 마다 자동으로 영화 카테고리 정보를 ViewData에 포함하게 된다.

'Web Platform' 카테고리의 다른 글

에러) System.Web.HttpException: 최대 요청 길이를 초과했습니다.  (0) 2009.06.29
ASP.NET MVC 액션 필터  (0) 2009.06.29
ASP.NET MVC TagBuilder  (0) 2009.06.29
ASP.NET MVC View  (0) 2009.06.29
ASP.NET MVC Routing 기술  (0) 2009.06.29

HTML Helper 만들고 TagBuilder 사용하기

 

ASP.NET MVC 프레임웍은 HTML Helper를 만들때 TagBuilder라는 utility 클래스를 사용한다.

TagBulider 클래스는 손쉽게 HTML 태그를 만드는 것을 가능하게 하고 생각하네 하는 클래스이다.

 

TagBulider클래스는 System.Web.Mvc 네임스페이스에서 제공되고 5개의 Method를 가지고 있다.

 

AddCssClass()

새로운 Class=”” 속성을 추가

GenerateId()

Id 속성 추가

MergeAttribute()

속성을 추가. 다수의 overload 제공

SetInnerText()

Inner text 추가.

ToString()

기본적인 tag, “<”, “>”, “< />”

 

 

Image HTML Helper 만들기

tag명을 넣어 TagBuilder 생성자를 통해 TagBuilder Class의 인스턴스를 만든다.

다음으로 태그의 속성을 수정하기 위해 AddCssClass MergeAttribute() 메소드를 호출한다.

마지막으로 ToString() 메소를 호출하여 태그를 제공한다.

 

/Helpers/ImageHelper.cs

 

using System.Web.Mvc;

using System.Web.Routing;

 

namespace MvcMyApplication4.Helpers

{

    public static class ImageHelper

    {

        public static string Image(this HtmlHelper helper, string id, string url, string alternateText)

        {

            return Image(helper, id, url, alternateText, null);

        }

 

        public static string Image(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes)

        {

            // Create tag builder

            var builder = new TagBuilder("img");

 

            // Create valid id

            builder.GenerateId(id);

 

            // Add attributes

            builder.MergeAttribute("src", url);

            builder.MergeAttribute("alt", alternateText);

            builder.MergeAttributes(new RouteVal!ueDictionary(htmlAttributes));

 

            // Render tag

            return builder.ToString(TagRenderMode.SelfClosing);

        }

    }

}

 

/Home/Index.aspx

 

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<%@ Import! Namespace="MvcMyApplication4.Helpers" %>

 

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">

    Home Page

</asp:Content>

 

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

 

    <!-- Calling helper without HTML attributes -->

    <%= Html.Image("img1", ResolveUrl("~/Content/XBox.png"), "XBox Console") %>

 

    <!-- Calling helper with HTML attributes -->

    <%= Html.Image("img1", ResolveUrl("~/Content/XBox.png"), "XBox Console", new {border="4px"})%>

 

</asp:Content>

 

 

 

 

<%@ Import! Namespace="MvcMyApplication4.Helpers" %> index.aspx view의 상단에 반드시 import! 해야 한다.

'Web Platform' 카테고리의 다른 글

ASP.NET MVC 액션 필터  (0) 2009.06.29
ASP.NET MVC 마스터 페이지  (0) 2009.06.29
ASP.NET MVC View  (0) 2009.06.29
ASP.NET MVC Routing 기술  (0) 2009.06.29
ASP.NET MVC 개발 환경 만들기  (0) 2009.06.29

데이터베이스 데이터 테이블 출력하기

HTML Table에 데이터베이스 레코드를 구성하는 2개의 Method를 보자

 

Database 만들기

프로젝트에 App_Data폴더 오른쪽 버튼을 클릭하여 추가에 새 항목을 선택하면 다음과 같은 화면이 나온다.

 

 데이터 -> SQL Server 데이터베이스 선택 후 이름은 Movies.mdf 로 한 후 추가 버튼을 클릭한다.

 

 

Model Class 만들기

Movies 데이터베이스 테이블의 레코드 구성을 보여주는 것부터 출발한다. Movies 데이터베이스 테이블은 다음과 같은 컬럼으로 구성되어 있다.

 

Table : tblMovie

Column Name

Data Type

Allow Nulls

Id

Int

False

Title

Nvarchar(200)

False

Director

NVarchar(50)

False

DateReleased

DateTime

False

 

Movies 데이터베이스 테이블 나타내는 순서로는 LINQ to SQL 데이터 접근 기술을 사용할 것이다.

다른 단어로는 MVC model classes by using LINQ to SQL

 

프로젝트에 보면 Models폴더가 있는데 Models폴더 오른쪽 버튼을 클릭하여 추가에 새 항목을 선택하면 다음과 같은 화면이 나온다.

데이터 -> LINQ to SQL 클래스 선택 후 이름은 Movie.dbml로 한 후 추가버튼을 클릭한다.

 

 

서버탐색기에서 만든 테이블을 Movie.dbml에 끌어다 놓으면 다음과 같이 출력된다.

 (테이블의 컬럼은 알아서 만들어 보자 )

여기까지 데이터베이스 생성 및 Models LINQ to SQL 파일 생성이 모두 완료되었다.

 

 

Controller Action LINQ to SQL 사용하기

Controller에서 LINQ to SQL을 사용하려면

Using System.Linq; Using 프로젝트명.Models; 를 선언해야 한다.

 

using System.Linq; // 추가

using System.Web.Mvc;

using MvcMyApplication3.Models; //추가

 

namespace MvcMyApplication3.Controllers

{

    [HandleError]

    public class HomeController : Controller

    {

        public ActionResult Index()

        {

            // 사용할 ModelsLINQ to SQL Class

            var dataContext = new MovieDataContext();  

            var movies = from m in dataContext.tblMovie // 테이블명

                         select m;

            return View(movies);

        }

    }

}

 

View에 데이터 출력하기

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<%@ Import! Namespace="MvcMyApplication3.Models" %>

 

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">

    Home Page

</asp:Content>

 

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

 

<table>

<tr>

     <th>Id</th><th>Title</th><th>Release Date</th>

</tr>

<% foreach (tblMovie m in (IEnumerable)ViewData.Model)

{ %>

<tr>

     <td><%= m.id %></td>

     <td><%= Html.Encode(m.Title) %></td>

     <td><%= m.DateReleased %></td>

</tr>

<% } %>

</table>

 

</asp:Content>

 

 여기까지 View page에 데이터 출력하는 것이 완료 되었다.

MVC
에서는 Routing Controller Method를 통해 View page를 호출을 한다

using System.Web.Mvc;

 

namespace MvcMyApplication2.Controllers

{

    [HandleError]

    public class HomeController : Controller

    {

        public ActionResult Index()

        {

            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();

        }

 

        public ActionResult About()

        {

            return View();

        }

 

        public ActionResult Detail()

        {

            return RedirectToAction("Index");

        }

     }

}

HomeController 에는 3개의 Index(), About(), Detail() action Method가 있다.

 

action은 다음과 같이 주소표시줄에 표기된다.

Index()

/Home/Index

About()

/Home/About

Detail()

/Home/Detail

 

Index() action view를 리턴한다. 어떤 action은 다른 type action 결과를 리턴할 수 있다.

예를 들어 Detail() action처럼 Index() action을 요청하는 RedirectToActionResult를 리턴할 수 있다.

 

Index() action View();

반드시 웹서버에 \Views\Home\Index.aspx가 있어야 한다.

 

만약 View(“Fred”); 를 리턴하면

\Views\Home\Fred.aspx 실행된다.

 

View에 내용추가

View는 다양한 script내용을 포함할 수 있는 html문서이다.

예를 들어 날짜를 출력하는 view를 보겠다.

  

Add.aspx

<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

 

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

 

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

<head id="Head1" runat="server">

    <title>Add</title>

</head>

<body>

    <div>

       

    The current date and time is<br />

    <% Response.Write(DateTime.Now); %>

 

    </div>

</body>

</html>

이 구분기호 <% %> C#에서 쓰여진 script이다.

Response.Write() Method는 브라우저 내용에 현재 날짜를 보여준다.

이 구분기호 <% %>은 하나 또는 더 많은 세크먼트를 실행하는데 사용된다.

 

Result

The current date and time is
2009-04-18
오후 10:45:43

Add2.aspx

<%@ Page Title=”” Language=”C#” Inherits=”System.Web.Mvc.ViewPage” %>

 

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

 

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

<head id=”Head1” runat=”server”>

    <title>Add</title>

</head>

<body>

    <div>

 

    The current date and time is<br />

    <%=DateTime.Now %>

 

    </div>

</body>

</html>

<%=%> 구분기호는 Response.Write() 를 간략하게 쓰는 기호이다.

Result

The current date and time is
2009-04-18
오후 10:45:43

 

 

View에서 HTML Helper 사용하기

HTML HelperTextbox, Link, Dropdown List, List Box등의 표준 HTML 요소를 사용할 수 있게 한다.

 

Login.aspx

<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

 

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

 

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

<head id="Head1" runat="server">

    <title>Login Form</title>

</head>

<body>

    <div>

   

    <% using (Html.BeginForm())

       { %>

        

        <label for="UserName">User Name:</label>

        <br />

        <%= Html.TextBox("UserName") %>

       

        <br /><br />

           

        <label for="Password">Password:</label>

        <br />

        <%= Html.Password("Password") %>

       

        <br /><br />

 

        <input type="submit" value="Log in" />       

   

    <% } %>

   

    </div>

</body>

</html>

HTML Source

<form action="/Home/Login" method="post">

 

        <label for="UserName">User Name:</label>

        <br />

        <input id="UserName" name="UserName" type="text" value="" />

       

        <br /><br />

           

        <label for="Password">Password:</label>

        <br />

        <input id="Password" name="Password" type="password" />

       

        <br /><br />

 

        <input type="submit" value="Log in" />       

   

    </form>

 

위에서 보듯이 HTML Helper는 각 HTML 요소로 변경된다. 기존의 서버컨트롤과는 다른 string만 변경하여 리턴을 해준다. ( 랜더링 작업이 없다. )

 

 

View View Data 사용하기

Controller 에서 ViewData["Message"] = "Welcome to ASP.NET MVC!"; 설정하면

ViewData["Message"]View Page에서 사용할 수 있다.

<%= Html.Encode(ViewData["Message"]) %> 하면 View Page Welcome to ASP.NET MVC! 라고 출력이 된다.

 

 

Custom HTML Helper 만들기

ASP.NET MVC HTML Helper의 종류는 다음과 같다.

  • Html.ActionLink()
  • Html.BeginForm()
  • Html.CheckBox()
  • Html.DropDownList()
  • Html.EndForm()
  • Html.Hidden()
  • Html.ListBox()
  • Html.Password()
  • Html.RadioButton()
  • Html.TextArea()
  • Html.TextBox()

<label>관련된 static Method를 만들려고 한다.

우리가 가끔 string 관련 함수를 만들어 return 하는 방식과 같다.

Helpers/LabelHelper.cs

using System;

 

namespace MvcMyApplication2.Helpers

{

    public class LabelHelper

    {

        public static string Label(string target, string text)

        {

            return String.Format("<label for='{0}'>{1}</label>", target, text);

        }

    }

}

HTML 요소의 특성에 맞게 파라메터를 받고 스트링 문자열을 만들어 return 한다.

이렇게 만든 클래스를 사용해보자

 

<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<%@ Import! Namespace="MvcMyApplication2.Helpers " %>

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

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

<head id="Head1" runat="server">

     <title>Index2</title>

</head>

<body>

     <div>

          <% using (Html.BeginForm())

          { %>

               <%= LabelHelper.Label("firstName", "First Name:") %>

               <br />

               <%= Html.TextBox("firstName")%>

               <br /><br />

               <%= LabelHelper.Label("lastName", "Last Name:") %>

               <br />

               <%= Html.TextBox("lastName")%>

               <br /><br />

               <input type="submit" value="Register" />

          <% } %>

     </div>

</body>

</html>

 

Result

 

 

HTML Helpers Extension Method 만들기

HtmlHelper 클래스에 Label() 확장 메소드를 추가하기

1.     클래스는 Static class

2.     Static classExtension Method를 정의 해야한다.

 

Helpers/LabelExtensions.cs

using System;

using System.Web.Mvc;

 

namespace MvcMyApplication2.Helpers

{

    public static class LabelExtensions

    {

        public static string Label(this HtmlHelper helper, string target, string text)

        {

            return String.Format("<label for='{0}'>{1}</label>", target, text);

        }

    }

}

 

작성 후 View Page Import! 하면 아래 그림과 같이 출력이 된다.

 

 

 

'Web Platform' 카테고리의 다른 글

ASP.NET MVC 마스터 페이지  (0) 2009.06.29
ASP.NET MVC TagBuilder  (0) 2009.06.29
ASP.NET MVC Routing 기술  (0) 2009.06.29
ASP.NET MVC 개발 환경 만들기  (0) 2009.06.29
ASP.NET MVC(Model, View, Controller)란?  (0) 2009.06.29

ASP.NET MVC Routing

 

블로그나 카페등에서 사용되는 확장자 없는 URL을 자유롭게 설정해 주는 기능

Global.asax에서 routes.MapRoute() 메소드를 통해 매핑규칙을 추가하면

http://www.mnstime.com/microsoft/aspnet/mvc/routing 와 같은 URL이 가능하다는 것이다.

 

RoutingGlobal.asax에서 설정을 한다.

Global.asax의 소스를 보면 다음과 같다.

 

public class MvcApplication : System.Web.HttpApplication

    {

        public static void RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(

                "Default",                                              // Route name

                "{controller}/{action}/{id}",                           // URL with parameters

                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults

            );

        }

        protected void Application_Start()

        {

            RegisterRoutes(RouteTable.Routes);

        }

    }

 

프로젝트를 생성하면 Global.asax에 기본 routes.MapRoute() 이 설정되어 있다.

만약 URL /Home/Detail/10 로 요청이 들어오면 "{controller}/{action}/{id} 순으로

 

Controller

Home Controller

Action

Detail Method

Id

10 ( 5 Parameter )

이렇게 매핑이 된다.

 

이 매핑의 규칙은 Global.asax에서 routes.MapRoute() 통해 다양하게 설정할 수 있다.

URL 요청은 순서대로 다양하게 설정한 routes.MapRoute() 중에서 적용이 되는 제일 첫번째 설정으로 매핑이 된다.

 

Default Routing

MVC URL에 대한 Default Routing 다음과 같다.

 

Global.asax.cs

 

routes.MapRoute(

                "Default",                                              // Route name

                "{controller}/{action}/{id}",                           // URL with parameters

                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults

            );

 

다음은 URL에 대한 요청 설명이다.

http://localhost/ 라면 Paramter defaults로 인해 Home Controller Index Method를 호출한다.

http://localhost/Shop/List/ 라면 Shop Controller List Method가 호출된다.

http://localhost/Shop/List/1 라면 Shop Controller List Method 1값이 파라메터로 전달이 된다.

 

Customer Routing

Routing은 기본적으로 {controller}/{action}/{id} 형태로 구성되지만 다른 형태로 구성 할 수 있다.

 

Global.asax.cs

 

routes.MapRoute(

                "Plan",                                                     // Route name

                "Plan/{action}/{id}",                                       // URL with parameters

                new { controller = "Plan", action = "List", id = "" }    // Parameter defaults

            );

http://localhost/Plan/View/2

PlanMgt Controller View Method 2값이 파라메터로 전달이 되며 /Plan View.aspx를 호출한다.

그리고 List.aspx 뷰가 만들어져야 http://localhost/Plan/ 를 요청했을 경우 List.aspx가 호출이 된다.

 

Global.asax.cs

 

routes.MapRoute(

                "ShopProduct",                                                     // Route name

                "Shop/{controller}/{action}/{id}",                                       // URL with parameters

                new { controller = "Product", action = "Index", id = "" },    // Parameter defaults

                new { controller = "(Product)|(Product2)" }

            );

 

※ 중요

Route를 여러개 지정하여 사용할 경우 위에서부터 차례대로 해석하는데 Default Route이 최상단으로 올리는 경우 Default Route에서 URL을 해석하여 페이지 에러가 발생하게 된다.

Customer Route를 생성했을 경우에는 먼저 Customer Route를 넣어준 후 Default Route를 넣어주는게 좋은 방법이다.

 

 

URLController 찾기

http://localhost/Shop

기본으로 Product Controller Index Method를 호출하여 /Product Index.aspx를 호출한다.

 

http://localhost/Shop/Product2/

Product2 Controller Index Method를 호출하여 /Product Index.aspx를 호출한다.

 

http://localhost/Shop/Product3/

Product3 Controller가 존재하지 않아 오류가 발생한다.

 

 

URLParameter 전달하기

http://localhost/Shop/Product/Index/Hello

Controller Index Method Hello파라메터값을 전달하여 Index.aspx를 호출한다.

값의 전달을 위해 소스를 아래와 같이 수정하였다.

 

ProductController.cs

 

        public ActionResult Index(string id)

        {

            ViewData["ProductParam"] = id;

            return View();

        }

 

Index.aspx

 

<%=Html.Encode(ViewData["ProductParam"]) %>

  

간단하게 하나의 파라메터 값을 전달하였다.

 

 

응용해서 2개의 파라메터를 전달하려면 어떻게 해야 할까?

http://localhost:7002/Shop/Product/Index/Hello/Hi

 

Global.asax.cs

 

            routes.MapRoute(

                "ShopProduct",                                                     // Route name

                "Shop/{controller}/{action}/{id}/{id2}",                                       // URL with parameters

                new { controller = "Product", action = "Index", id = "", id2 = "" },    // Parameter defaults

                new { controller = "(Product)|(Product2)" }

            );

 

ProductController.cs

 

        public ActionResult Index(string id , string id2)

        {

            ViewData["ProductParam"] = id;

 ViewData["ProductParam2"] = id2;

            return View();

        }

 

Index.aspx

 

<%=Html.Encode(ViewData["ProductParam"]) %> / <%=Html.Encode(ViewData["ProductParam2"]) %>

 

 

 

Views Win Form 추가하기

지금까지는 그림에서 처럼 Views/ProductView 항목을 통해 Page를 추가했다.

 

지금은 새 항목을 통하여 Web Form을 추가하는 것을 해보겠다.

 

 

새 항목을 클릭 후 Web Form 선택하여 Detail.aspx라는 Web Form을 만들자.

다음으로 Product Controller Detail Action을 만들어 연결을 해보자

Product Controller.cs

 

        public ActionResult Detail()

        {

            return View();

        }

 

 http://localhost:7002/Shop/Product/Detail URL을 입력하면 다음과 같은 에러가 출력된다.

Detail.aspx ViewPage의 상속을 받지 않아서 생기는 문제이다.

  

Detail.aspx.cs의 코드를 수정하자.

Detail.aspx.cs

 

using System.Web.Mvc; // 추가

 

namespace MvcMyApplication.Views.Product

{

    public partial class Detail : ViewPage //System.Web.UI.Page 를 변경

    {

        protected void Page_Load(object sender, EventArgs e)

        {

 

        }

    }

}

 

'Web Platform' 카테고리의 다른 글

ASP.NET MVC TagBuilder  (0) 2009.06.29
ASP.NET MVC View  (0) 2009.06.29
ASP.NET MVC 개발 환경 만들기  (0) 2009.06.29
ASP.NET MVC(Model, View, Controller)란?  (0) 2009.06.29
날짜 관련 함수  (0) 2009.06.29

ASP.NET MVC Web Application 만들기

 

새로운 MVC 프로젝트를 만들기 위해서는 아래와 같은 환경이 준비되어야 한다.

1.      Microsoft Visual Studio2008

2.      .NET Framework 3.5 SP 1

3.      ASP.NET MVC 1.0

4.      IIS 7.0 (IIS 6.0 이상)

 

 

ASP.NET MVC 1.0http://www.asp.net/MVC/ 에서 다운 받을 수 있다.

버튼을 클릭하면 Web Platform Installer 2.0 Beta를 설치한다.

 

 

설치를 완료 하면 아래와 같은 화면이 나온다.

 

Web Platform -> Frameworks and Runtimes Customize를 선택하면

ASP.NET MVC 1.0 .NET Framework 3.5 SP1를 체크한 후 Install을 하면 설치가 된다.  

 

 

이제 환경이 준비 되었으니 새로운 MVC 프로젝트를 만들어보자.

 

 

Microsoft Visual Studio2008을 실행 한 후 새 프로젝트를 선택하면 아래와 같이 ASP.NET MVC Web Application이 생성된 것을 볼 수 있다.

 

 

 

MvcMyApplication 이름으로 새 프로젝트를 생성하자.

다음과 같은 화면이 나오는데 No, do not create a unit test project를 선택 -> OK

(Yest, create a unit test project를 하게 되면 단위테스트를 위한 프로젝트가 같이 생성이 된다.)

 

Ctrl + F5를 눌러 실행해보자.

 

이렇게 해서 하나의 MVC Application을 만들어보았다

 

 

'Web Platform' 카테고리의 다른 글

ASP.NET MVC View  (0) 2009.06.29
ASP.NET MVC Routing 기술  (0) 2009.06.29
ASP.NET MVC(Model, View, Controller)란?  (0) 2009.06.29
날짜 관련 함수  (0) 2009.06.29
JavaScript를 이용한 정규식 표현  (0) 2009.06.29

MVC란 객체지향언어인 Smalltalk에서 도입되었다.

 

MVC의 세부분의 구성은 다음과 같은 역활을 한다.

 

1. Model(Biz 로직

비즈니스를 처리한다. 데이터 부분의 클래스 및 논리적인 데이터 기반 구조를 표현

2. View(Biz의 프리젠테이션)

사용자가 보게 될 결과 화면을 담당한다.

3. Contoller(흐름제어)

Model View와의 통신을 담당한다.


MVC 어플리케이션을 만들기는 결정할 때

ASP.NET MVC framework 인지 혹은 ASP.NET Web Forms 모델 인지를 결정하는 것은 주의 깊게 고려해야 한다.

MVC framework ASP.NET Web Forms을 교체하지는 않는다.

결정하기 이전에 웹 어플리케이션에 주는 이점을 살펴야 한다

 

ASP.NET MVC 기반 웹 어플리케이션은 다음과 같은 이점을 제공한다.

* Model, View, Controller가 분리되어 있으므로 관리의 복잡성이 줄어든다.

* View State Server Based Control을 사용하지 않는다. 이것은 어플리케이션의 동작을 완전히 제어하려는 개발자들에게 이상적이다.

* 좀더 나은 Test-Driven Development의 지원

* 높은 수준의 제어가 필요한 개발자와 설계자들의 큰 팀을 지원하는 Web 어플리케이션에 적합

 

Web Forms 기반 웹 어플리케이션은 다음과 같은 이점을 제공한다.

* HTTP를 통해 상태를 저장하는 이벤트 모델을 제공한다. 서버컨트롤에서 지원하는 수만은 이벤트들을 지원한다.

* 상태정보를 쉽게 관리할 수 있는 View Status 또는 Server-based Forms를 제공한다.

* 많은 수의 컴포넌트를 빠르게 개발하려는 개발자 및 설계자들의 작은 팀에 적합.

* 일반적으로 컴포넌트가 긴밀하게 통합되어 있고 MVC 모델 보다 적은 코드가 필요하기 때문에 개발의 복잡도가 적다

 

MVC 어플리케이션에서는 더 이상 ViewState와 포스트백을 사용하지 않는다.

 

'Web Platform' 카테고리의 다른 글

ASP.NET MVC Routing 기술  (0) 2009.06.29
ASP.NET MVC 개발 환경 만들기  (0) 2009.06.29
날짜 관련 함수  (0) 2009.06.29
JavaScript를 이용한 정규식 표현  (0) 2009.06.29
location.href 와 location.replace의 차이  (0) 2009.06.29

/**
 * Copyright (c) 2000 by LG-EDS Systems Inc
 * All rights reserved.
 *
 * 날짜관련 자바스크립트 공통함수
 *
 * 분단위 이하(= 초)는 고려하지 않았습니다.
 * YYYYMMDDHHMI 형식의 String => 'Time'으로 칭함
 *
 * 주로 YYYYMMDD 까지만 쓰인다면 아래 함수들을
 * YYYYMMDD 형식의 String => 'Date'로 하여 적당히
 * 수정하시거나 아니면 함수를, 예를들어 isValidDate()처럼,
 * 추가하시기 바랍니다.
 *
 * @version 2.0, 2001/01/28
 * @author 박종진(JongJin Park), jongjpark@lgeds.lg.co.kr
 */


/**
 * 유효한(존재하는) 월(月)인지 체크
 */
function isValidMonth(mm) {
    var m = parseInt(mm,10);
    return (m >= 1 && m <= 12);
}

/**
 * 유효한(존재하는) 일(日)인지 체크
 */
function isValidDay(yyyy, mm, dd) {
    var m = parseInt(mm,10) - 1;
    var d = parseInt(dd,10);

    var end = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
    if ((yyyy % 4 == 0 && yyyy % 100 != 0) || yyyy % 400 == 0) {
        end[1] = 29;
    }

    return (d >= 1 && d <= end[m]);
}

/**
 * 유효한(존재하는) 시(時)인지 체크
 */
function isValidHour(hh) {
    var h = parseInt(hh,10);
    return (h >= 1 && h <= 24);
}

/**
 * 유효한(존재하는) 분(分)인지 체크
 */
function isValidMin(mi) {
    var m = parseInt(mi,10);
    return (m >= 1 && m <= 60);
}

/**
 * Time 형식인지 체크(느슨한 체크)
 */
function isValidTimeFormat(time) {
    return (!isNaN(time) && time.length == 12);
}

/**
 * 유효하는(존재하는) Time 인지 체크

 * ex) var time = form.time.value; //'200102310000'
 *     if (!isValidTime(time)) {
 *         alert("올바른 날짜가 아닙니다.");
 *     }
 */
function isValidTime(time) {
    var year  = time.substring(0,4);
    var month = time.substring(4,6);
    var day   = time.substring(6,8);
    var hour  = time.substring(8,10);
    var min   = time.substring(10,12);

    if (parseInt(year,10) >= 1900  && isValidMonth(month) &&
        isValidDay(year,month,day) && isValidHour(hour)   &&
        isValidMin(min)) {
        return true;
    }
    return false;
}

/**
 * Time 스트링을 자바스크립트 Date 객체로 변환
 * parameter time: Time 형식의 String
 */
function toTimeObject(time) { //parseTime(time)
    var year  = time.substr(0,4);
    var month = time.substr(4,2) - 1; // 1월=0,12월=11
    var day   = time.substr(6,2);
    var hour  = time.substr(8,2);
    var min   = time.substr(10,2);

    return new Date(year,month,day,hour,min);
}

/**
 * 자바스크립트 Date 객체를 Time 스트링으로 변환
 * parameter date: JavaScript Date Object
 */
function toTimeString(date) { //formatTime(date)
    var year  = date.getFullYear();
    var month = date.getMonth() + 1; // 1월=0,12월=11이므로 1 더함
    var day   = date.getDate();
    var hour  = date.getHours();
    var min   = date.getMinutes();

    if (("" + month).length == 1) { month = "0" + month; }
    if (("" + day).length   == 1) { day   = "0" + day;   }
    if (("" + hour).length  == 1) { hour  = "0" + hour;  }
    if (("" + min).length   == 1) { min   = "0" + min;   }

    return ("" + year + month + day + hour + min)
}

/**
 * Time이 현재시각 이후(미래)인지 체크
 */
function isFutureTime(time) {
    return (toTimeObject(time) > new Date());
}

/**
 * Time이 현재시각 이전(과거)인지 체크
 */
function isPastTime(time) {
    return (toTimeObject(time) < new Date());
}

/**
 * 주어진 Time 과 y년 m월 d일 h시 차이나는 Time을 리턴

 * ex) var time = form.time.value; //'20000101000'
 *     alert(shiftTime(time,0,0,-100,0));
 *     => 2000/01/01 00:00 으로부터 100일 전 Time
 */
function shiftTime(time,y,m,d,h) { //moveTime(time,y,m,d,h)
    var date = toTimeObject(time);

    date.setFullYear(date.getFullYear() + y); //y년을 더함
    date.setMonth(date.getMonth() + m);       //m월을 더함
    date.setDate(date.getDate() + d);         //d일을 더함
    date.setHours(date.getHours() + h);       //h시를 더함

    return toTimeString(date);
}

/**
 * 두 Time이 몇 개월 차이나는지 구함

 * time1이 time2보다 크면(미래면) minus(-)
 */
function getMonthInterval(time1,time2) { //measureMonthInterval(time1,time2)
    var date1 = toTimeObject(time1);
    var date2 = toTimeObject(time2);

    var years  = date2.getFullYear() - date1.getFullYear();
    var months = date2.getMonth() - date1.getMonth();
    var days   = date2.getDate() - date1.getDate();

    return (years * 12 + months + (days >= 0 ? 0 : -1) );
}

/**
 * 두 Time이 며칠 차이나는지 구함
 * time1이 time2보다 크면(미래면) minus(-)
 */
function getDayInterval(time1,time2) {
    var date1 = toTimeObject(time1);
    var date2 = toTimeObject(time2);
    var day   = 1000 * 3600 * 24; //24시간

    return parseInt((date2 - date1) / day, 10);
}

/**
 * 두 Time이 몇 시간 차이나는지 구함

 * time1이 time2보다 크면(미래면) minus(-)
 */
function getHourInterval(time1,time2) {
    var date1 = toTimeObject(time1);
    var date2 = toTimeObject(time2);
    var hour  = 1000 * 3600; //1시간

    return parseInt((date2 - date1) / hour, 10);
}

/**
 * 현재 시각을 Time 형식으로 리턴

 */
function getCurrentTime() {
    return toTimeString(new Date());
}

/**
 * 현재 시각과 y년 m월 d일 h시 차이나는 Time을 리턴
 */
function getRelativeTime(y,m,d,h) {
/*
    var date = new Date();

    date.setFullYear(date.getFullYear() + y); //y년을 더함
    date.setMonth(date.getMonth() + m);       //m월을 더함
    date.setDate(date.getDate() + d);         //d일을 더함
    date.setHours(date.getHours() + h);       //h시를 더함

    return toTimeString(date);
*/
    return shiftTime(getCurrentTime(),y,m,d,h);
}

/**
 * 현재 年을 YYYY형식으로 리턴
 */
function getYear() {
/*
    var now = new Date();
    return now.getFullYear();
*/
    return getCurrentTime().substr(0,4);
}

/**
 * 현재 月을 MM형식으로 리턴
 */
function getMonth() {
/*
    var now = new Date();

    var month = now.getMonth() + 1; // 1월=0,12월=11이므로 1 더함
    if (("" + month).length == 1) { month = "0" + month; }

    return month;
*/
    return getCurrentTime().substr(4,2);
}

/**
 * 현재 日을 DD형식으로 리턴

 */
function getDay() {
/*
    var now = new Date();

    var day = now.getDate();
    if (("" + day).length == 1) { day = "0" + day; }

    return day;
*/
    return getCurrentTime().substr(6,2);
}

/**
 * 현재 時를 HH형식으로 리턴
 */
function getHour() {
/*
    var now = new Date();

    var hour = now.getHours();
    if (("" + hour).length == 1) { hour = "0" + hour; }

    return hour;
*/
    return getCurrentTime().substr(8,2);
}

/**
 * 오늘이 무슨 요일이야?

 * ex) alert('오늘은 ' + getDayOfWeek() + '요일입니다.');
 * 특정 날짜의 요일을 구하려면? => 여러분이 직접 만들어 보세요.
 */
function getDayOfWeek() {
    var now = new Date();

    var day = now.getDay(); //일요일=0,월요일=1,...,토요일=6
    var week = new Array('일','월','화','수','목','금','토');

    return week[day];
}

* 영문/숫자조합 6~12자 비밀번호 체크(정규식)
 
function mycheck(p)
{
    chk1 = /^[a-z\d]{6,12}$/i;  //a-z와 0-9이외의 문자가 있는지 확인
    chk2 = /[a-z]/i;  //적어도 한개의 a-z 확인
    chk3 = /\d/;  //적어도 한개의 0-9 확인
    return chk1.test(p) && chk2.test(p) && chk3.test(p);
}

 * p : 검사 값
 * 조합이면 true 반환


*javascript로 숫자 또는 지정한 문자만 받게 필터링
 
<숫자만 가능>
function onlyNum(txtbox) 
{
    var v=txtbox.value;
    if(v.match(/[\-\+]?\d*(\.\d*)?/g)[0]!=v)
    {
        txtbox.value=v.match(/[\-\+]?\d*(\.\d*)?/g)[0]
    }
}
 
<문자만 가능>
function onlyNum(txtbox) 
{
    var v=txtbox.value;
    if(v.match(/[\-\+]?[a-z]*(\.[a-z]*)?/g)[0]!=v)
    {
        txtbox.value=v.match(/[\-\+]?\d*(\.\d*)?/g)[0]
    }
}


* HTML 태그 제거

function stripHTMLtag(string)

    varobjStrip = new RegExp(); 
    objStrip = /[<][^>]*[>]/gi; 
    return string.replace(objStrip, ""); 
}

.href 와 .repalce()는 모두 location의 하위객채로 브라우저에서 URL이동때 쓰인다.

그러나 쓰는 형태를 보면 알겠지만 .href 는 프로퍼티고, .replace()는 메소드다.

 

location.href = http://www.naver.com        <= [1] 값을 정의해야 하는프로퍼티

location.replace(http://www.naver.com)    <= [2] 파라미터로 동작을 명령하는 메소드

 

아. 그게 뭐가 중요하냐... 브라우저가 주소만 바뀌면 되는거 아냐... 라고 하겠지만..

그게 아니라 이거지... ㅡ ㅡa

 

골아프겠지만, 자바스크립트에서 정의한 정확한 의미를 집어보자.

 

location 은 현재 브라우저에 떠있는 URL 주소값에 관련된 내용을 다루는 객체다.

브라우저의 주소표시줄에 있는 URL은 다음과 같이 정의된다.

 

protocol :// hostname : port / pathname ? search # hash

 

location.href는 위에 써있는 전체를 가르키며,

location.pathname 이라고 하면 같은 사이트에 파일경로만을 가르킨다.

(예를 들면...http://www.naver.com/blog/myinfo/profile.asp  라는 페이지가 떠있따면...

location.href에는 이거 전체가, location.phthname 에는 [blog/myinfo/profile.asp] 가 들어있다.)

 

그래서 location.href 라고 하면 브라우저의 주소표시줄에 떠있는 URL를 가르킨다.

그러므로 [1]처럼하면 브라우저의 주소표시줄 값이 변경되므로 페이지가 바뀌게 된다.

(물론 프레임, 아이프레임을 썼을땐 그 프레임의 주소가 바뀐다.)

 

[1]을 했을떄 일어나는 일은 우리가 주소표시줄에 키보드로 직접 주소를 넣고 엔터를 치는것과 정확히 같은 일을 일으킨다.

여기서 같은 일이란,

새로은 페이지로 이동(a)되고,

[뒤로]버튼을 누르면 이전 URL로 이동(b)되는것을 말한다.

 

(a) , (b)에 대해 좀만더 자세히 보자.

 

(a)  새로운 페이지로 이동.

브라우저 옵션을 손대지 않았을때, 브라우저의 주소값이 바뀌면 브라우저는 '인터넷 임시파일'

(C:\Documents and Settings\Administrator\Local Settings\Temporary Internet Files\)

에 캐쉬가 있는지를 먼저 보고, 있으면 그걸 보여준다.

그래서 가끔 우린 사이트내용이 바뀌었는데도, 로컬에 있는 파일을 보는 경우가 있다.

location.href로 주소이동을 했을떄 이와 같은 일이 일어난다.

 

(b) [뒤로]버튼을 누르면 이전 URL로 이동.

[뒤로]버튼이 정상장동되는것은 History객체에 배열처럼 이전 URL들이 기록되어있기때문이다.

우리가 [뒤로]버튼을 누르는건 History객체를 역순으로 되집어 가는 과정이다. ( history.back()이 그 일을 한다. )

location.href를 쓰면 [뒤로]버튼도 history.back()도 직접URL바꿨을때와 똑같이 작동한다.

 

그럼 location.replace()는 뭐가 다를까?

location.repalce()는 다음과 같이 작동한다.

 

1. location.replace() (a)의 경우  '인터넷 임시파일'을 쓰지 않는다. 매소드가 실행될때마다 매번 서버에 접속해서 페이지를 가져온다. 게시판 리스트같은 곳을 이동할때 location.href를 쓰면 새 글이 올라온것을 모르고 '로컬에 있는 파일'만 보는 일이 생길 수 있는데, location.replace()를 쓰면 이를 방지할 수 있다.

 

2. location.replace()은 새 페이지로 이동하는게 아니라 현재페이지를 바꿔주는 거다.

말장난 같아도 이거 중요한거다.. 왜중요한고하니...

(b)의 경우, History객체에 새로운 URL를 기록하는게 아니라 현재 페이지값을 바꾼다.

그러므로 location.replace()로 이동하고 [뒤로]버튼을 누르면 이전페이지가 아니라 이전,이전페이지가 뜬다. 이해가 안된다고?

 

A --> B --> C    처럼 페이지가 이동을 했다하자. (현재 당신은 C사이트에...)

B --> C로 이동할때 location.href를 썼다면

C페이지트에서 [뒤로]버튼을 누르면 B가뜬다.

하지만..

B --> C로 이동할때 location.replace()를 썼다면

C페이지에서 [뒤로]버튼을 누르면 A가뜬다.

그럼 사용자입장에선 '어 내가 클릭을 두번했나?' 하게 된다...

 

이런 차이로 인하여 적절히 써야 한다.

[뒤로]버튼을 눌렀을때 두페이지 이전으로 넘어가면 안되는 경우가 있는 반면,(.href를 써야겠지..)

프레임을 쓴 사이트 의 경우는 [뒤로]버튼 한두번 클릭으로 사이트를 빠져나가게 할 수도 있다. (.repalce()를 쓴경우...)

+ Recent posts