.Net framework v4.0, Visual Studio 2010, asp.net MVC3 프로젝트 기준으로 진행된 내역입니다.

Asp.Net MVC 중에 _Layout.cshtml에서 각 페이지 렌더링 될 때 사용될 기본적인 룰을 정리하던 도중 RenderSection처리하는 부분이 너무 번거로운 것 같아 '좀 내 입맛대로 해보자!'하는 취지에서 찾아보고 진행했던 내용입니다.

WebViewPage클래스를 상속받는 클래스 생성

RenderSection은 MSDN을 찾아보면 System.Web.WebPages.WebPageBase클래스에 구현되어 있으니 WebPageBase클래스를 상속받은 클래스를 생성해도 되지만, WebViewPage클래스에 구현되어 View 페이지(*.cshtml)에서 사용되는 유용한 속성, 메서드들은 사용할 수 없거나, 다시 구현해야 하기 때문에 WebViewPage클래스를 상속받는 클래스를 생성합니다.

클래스를 생성하는 위치는 적절하게 선택하면 되며, 여기서는 WebViewPageHandler 클래스로 진행하도록 하겠습니다.
제가 원하는 RenderSection의 기능이 <script ...></script>를 필요에 따라서 삭제하고, 추가로 jquery에서 사용되는 $(document).ready...로 시작되는 부분을 필요에 따라서 삭제할 수 있도록 하는 부분이어서 아래와 같이 구현하였습니다.

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

using System.Web.Mvc;
using System.Web.WebPages;
using System.Text.RegularExpressions;

namespace 네임스페이스 명
{
    public abstract class WebViewPageHandler<T> : WebViewPage<T>
    {
        public override void InitHelpers()
        {
            base.InitHelpers();
        }

        /// <summary>
        /// 레이아웃 페이지에서 명명된 섹션의 콘텐츠를 렌더링하고 섹션이 필수인지를 지정합니다. 
        /// <para>또한 스크립트 블럭 테그와  Jquery의 '$(document).ready(function () {' 항목과 끝 '});' 항목을 삭제할지 지정합니다.</para>
        /// </summary>
        /// <param name="name">렌더링할 섹션입니다.</param>
        /// <param name="required">섹션을 필수로지정하려면 true이고, 그렇지 않으면 false입니다.</param>
        /// <param name="isRemoveScriptBlock">상단에 스크립트 블럭 시작Tag 와 끝Tag를 삭제하려면 true, 그렇지 않으면 false입니다.</param>
        /// <param name="isRemoveDocReady">Jquery의 '$(document).ready(function () {' 항목과 끝 '});' 항목을 삭제하려면 true, 그렇지 않으면 false입니다.</param>
        /// <returns>렌더링할 HTML 콘텐츠입니다.</returns>
        public HelperResult RenderSection(string name, bool required, bool isRemoveScriptBlock, bool isRemoveDocReady)
        {
            String renderString = NoNull.ToString(base.RenderSection(name, required), string.Empty);

            #region 객체에 대한 유효성 검사를 실시합니다. 
            if (string.IsNullOrEmpty(renderString) && !required)
            {
                // 필수지정이 되어 있지않고, 구현 된 Section 내용이 없다면 null을 리턴합니다.
                // cshtml에서는 아무런 내용도 작성되지 않습니다.
                return null;
            }
            else if (string.IsNullOrEmpty(renderString) && !required)
            {
                // 필수로 지정되어있으나 구현 된 Section 내용이 없다면 오류로 생각해야 합니다.
                // 때문에 MSDN 오류 처리에 맞춰 오류를 발생시킵니다.
                throw new HttpException("렌더링할 섹션을 찾을 수 없습니다.");
            }
            #endregion

            // 상단의 <script ...> 와</script> 항목을 삭제합니다.
            // 내용물은 삭제하지 않습니다.
            if (isRemoveScriptBlock)
            {
                renderString = Regex.Replace(renderString, @"<script[^>]*>", "");
                renderString = Regex.Replace(renderString, @"<\/script>", "");
            }

            // Jquery의 '$(document).ready(function () {' 항목과 끝 '});' 항목을 삭제합니다.
            if (isRemoveDocReady)
            {
                renderString = renderString.Replace(@"$(document).ready(function () {", "");
                int index = renderString.LastIndexOf(@"});");
                renderString = renderString.Substring(0, index);
            }

            HelperResult result = new HelperResult(__razor_helper_writer =>
            {
                // 아래 WriteLiteralTo 메서드를 써야 "나 '문자가 변환되지 않습니다.
                WriteLiteralTo(__razor_helper_writer, renderString);
            });

            return result;
        }
    }
}

Web.config 수정

Web.config 파일은 프로젝트 내에 2개가 존재하는데 여기서 수정하는 파일은 View폴더 밑에 있는 파일입니다. 내용 중에 <system.web.webPages.razor>노드 하위에 <pages>노드를 찾아 다음과 같이 수정해 줍니다.

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

<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
  </configSections>
  
  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.1, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <!--<pages pageBaseType="System.Web.Mvc.WebViewPage">-->
    <pages pageBaseType="네임스페이스 명.WebViewPageHandler">  <!-- 이 부분을 상황에 맞게 수정합니다. -->
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

_layout.cshtml 파일의 수정

_layout.cshtml에서 위에 overload된 RenderSection을 사용하는 부분입니다.

<!DOCTYPE html>
<html>
<head>
    <title>홈페이지에 오신걸 환영합니다.</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" lang="ko" />
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />

    <link href="@Url.Content("~/Content/layout.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/jquery-ui/themes/flick/jquery-ui-1.10.4.flick.css")" rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/menu_top.css")" rel="stylesheet" type="text/css" />
    @if (IsSectionDefined("PageDefineCssBlock")) { @RenderSection("PageDefineCssBlock") }
                                                                                        
    <script src="@Url.Content("~/Scripts/jquery-1.10.2.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery-ui-1.10.4.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/menu_top.js")" type="text/javascript"></script>
    @if (IsSectionDefined("PageDefineScriptBlock")) { @RenderSection("PageDefineScriptBlock") }
       
    <script type="text/javascript">
        $(document).ready(function () {
            $('#logOut').button().css('font-size', '0.8em');
            @RenderSection("PageDefineDocReadyBlock", false, true, true)   // overload된 RenderSection
        });

        @RenderSection("PageDefineFunctionBlock", false, true, false)    // overload된 RenderSection
    </script>
</head>

<body>

....

아래는 View 페이지 내역으로 PageDefineDocReadyBlock블럭에서는 위에서 구현한 부분과 같이 <script ...>부터 $(document).ready(function () {, </script> 부분이 제거된 상태로 _layout.cshtml파일에 삽입됩니다. 또한 PageDefineFunctionBlock블럭에서는 <script ...>, </script> 부분이 제거되어 삽입 됩니다.

....
@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
}

@*@section PageDefineScriptBlock { }*@

@section PageDefineCssBlock {
    <!-- 페이지 선언 CSS Block -->
    <link href="@Url.Content("~/Content/login.css")" rel="stylesheet" type="text/css" /> 
}

@section PageDefineDocReadyBlock {
    <script type="text/javascript">
        $(document).ready(function () {
            $("#Id_user").focus();
            $("#login_form").submit(function () {
                var inputId = $("#Id_user").val();
                var inputPw = $("#Pw_user").val();

                if (inputId.length === 0) {
                    alert("ID를 입력해주세요.");
                    $("#Id_user").focus();
                    return false;
                }

                if (inputPw.length === 0) {
                    alert("비밀번호를 입력해주세요.");
                    $("#Pw_user").focus();
                    return false;
                }
            });
        });
    </script>
}

@section PageDefineFunctionBlock {
    <script type="text/javascript">
        function test() {
            alert('test function입니다.');
        }
    </script>
}
....

마지막으로 실제 실행 된 HTML의 소스 부분입니다.

<!DOCTYPE html>
<html>
<head>
    <title>홈페이지에 오신걸 환영합니다.</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" lang="ko" />
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />

    <link href="/Content/jquery-ui/themes/flick/jquery-ui-1.10.4.flick.css" rel="stylesheet" type="text/css" />

    <!-- 페이지 선언 CSS Block -->
    <link href="/Content/login.css" rel="stylesheet" type="text/css" /> 
                                                                                        
    <script src="/Scripts/jquery-1.10.2.js" type="text/javascript"></script>
    <script src="/Scripts/jquery-ui-1.10.4.js" type="text/javascript"></script>
                                                                                              
    <script type="text/javascript">
        $(document).ready(function () {
            
    
        
            $("#Id_user").focus();
            $("#login_form").submit(function () {
                var inputId = $("#Id_user").val();
                var inputPw = $("#Pw_user").val();

                if (inputId.length === 0) {
                    alert("ID를 입력해주세요.");
                    $("#Id_user").focus();
                    return false;
                }

                if (inputPw.length === 0) {
                    alert("비밀번호를 입력해주세요.");
                    $("#Pw_user").focus();
                    return false;
                }
            });
        
        });

         
    
        function test() {
            alert('test function입니다.');
        }
    

    </script>
</head>

<body>
    <!-- Content Start -->

...

참고 페이지

- 우선 Win Form에 'notifyIcon'컨트롤을 추가.
- 속성에서 아이콘을 등록. (등록하지 않으면 트래이상태에서 아이콘이 보이지 않음)


- 이벤트 부분

//Tray 시키기
private void btnHide_Click(object sender, System.EventArgs e)
{
     this.Hide();                    // alt+tab 시 보이지 않는다.
     nIcon.Visible    = true;       // 트레이의 아이콘을 보이게 한다.
     this.Hide();
     this.nIcon.Text  = "설명.....";
}

//원래대로 돌아오기
private void nIcon_DoubleClick(object sender, System.EventArgs e)
{
     this.Visible             = true;
     this.ShowInTaskbar = true;                                  // 현재 프로그램을 테스크 바에 표시
     this.WindowState     = FormWindowState.Normal;   // 폼을 윈도 상태를 normal
     nIcon.Visible           = false;
}

출처 : http://cafe.naver.com/homepage815.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=19

연결 문자열 작성

웹 데이터 응용 프로그램을 작성하려면 제일 먼저 ADO에 대해 데이터 원본을 찾아서 식별할 수 있는 방법을 제공해야 합니다. 이는 연결 문자열을 통해 수행할 수 있는데, 이 연결 문자열은 데이터 원본 공급자와 데이터 원본 위치 등의 매개 변수를 정의하는 일련의 인수로서 세미콜론으로 구분되어 있습니다. ADO는 연결 문자열을 사용하여 OLE DB 공급자를 식별하고 이 공급자를 데이터 원본으로 안내합니다. 공급자는 데이터 원본을 나타내고 응용 프로그램에 대해 정보를 행 집합 형태로 표시하는 구성 요소입니다.

다음 표에는 일반적인 여러 데이터 원본에 대한 OLE DB 연결 문자열이 나와 있습니다.

데이터 원본 OLE DB 연결 문자열
Microsoft?? Access Provider=Microsoft.Jet.OLEDB.4.0;Data Source=.mdb 파일의 실제 경로
Microsoft SQL Server Provider=SQLOLEDB.1;Data Source=데이터베이스 서버 경로
Oracle Provider=MSDAORA.1;Data Source=데이터베이스 서버 경로
Microsoft Indexing Service Provider=MSIDXS.1;Data Source=파일 경로

이전 버전과의 호환성을 제공하기 위해 ODBC용 OLE DB 공급자는 ODBC 연결 문자열 구문을 지원합니다. 다음 표에서는 일반적으로 사용하는 ODBC 연결 문자열을 소개합니다.

데이터 원본 드라이버 ODBC 연결 문자열
Microsoft Access Driver={Microsoft Access Driver (*.mdb)};DBQ=.mdb 파일의 실제 경로
SQL Server DRIVER={SQL Server};SERVER=서버 경로
Oracle DRIVER={Microsoft ODBC for Oracle};SERVER=서버 경로
Microsoft Excel Driver={Microsoft Excel Driver (*.xls)};DBQ=.xls 파일의 실제 경로; DriverID=278
Microsoft Excel 97 Driver={Microsoft Excel Driver (*.xls)};DBQ=.xls 파일의 실제 경로;DriverID=790
Paradox Driver={Microsoft Paradox Driver (*.db)};DBQ=.db 파일의 실제 경로;DriverID=26
텍스트 Driver={Microsoft Text Driver (*.txt;*.csv)};DefaultDir=.txt 파일의 실제 경로
Microsoft Visual FoxPro?? (데이터베이스 컨테이너 포함) Driver= {Microsoft Visual FoxProDriver};SourceType=DBC;SourceDb=.dbc 파일의 실제 경로
Microsoft Visual FoxPro(데이터베이스 컨테이너 제외) Driver= {Microsoft Visual FoxProDriver};SourceType=DBF;SourceDb=.dbf 파일의 실제 경로
 [Html 부분]
<DIV id = "GridDiv" runat = "server">

[cs부분]

protected
System.Web.UI.HtmlControls.HtmlGenericControl GridDiv; //GridDiv 변수를 선언
DataSet ds = new DataSet();

//DataSet에 조회된 내용의 유무에 따라 스타일을 다르게 적용한다.
//있다면 WIDTH: 790px; HEIGHT: 480px
//없다면 WIDTH: 100%; HEIGHT: 100%
if( ds.Tables[0].Rows.Count > 0 )
{

       //적용할 스타일 속성
       string Attributes = "WIDTH: 790px; HEIGHT: 480px; ....";    
       GridDiv.Attributes.Add( "style", Attributes );
   
       DataGrid1.DataSource = ds;
       DataGrid1.DataBind();

}
else
{

       //적용할 스타일 속성
       string Attributes = "WIDTH: 100%; HEIGHT: 100%; ....";    
       GridDiv.Attributes.Add( "style", Attributes );

       DataGrid1.DataSource = ds;
       DataGrid1.DataBind();

}

 

머릿말에서 말한것 처럼 정말 웹페이지를 만들때 자바 스크립트가 많이 쓰인다.이것을 클래스로 만들어 매소드로 정의 한다음에 계속 가져다가 써보자


[자주쓰이는 자바스크립를 알아 보자!]


alert,window.open,alert.Location.href,window.opener.Location.reload()....등등 많이 쓰이고 있다. 한번 클래스를 만들어 놓고 자신이 자주 쓰는 스크립트는 계속 추가를 시켜주면된다.


[클래스 만들기!]


간단한 클래스 이기 때문에 우선 생성자는 없습니다.

그리고 서버단에서 자바스크립트를 쓸때 Response.write("") 로 값을 뿌리기 때문에 매서드를 만들때 String 형으로 반환하는 매서드를 만들겠습니다.

public static string JavascriptAlert(string str)

{

    StringBuilder strbuild = new StringBuilder("");

    strbuild.Append("<script language=\"javascript\">");

    strbuild.Append("   alert(\"" + str + "\");");

    strbuild.Append("</" + "script>");

    return strbuild.ToString();

}

 

alert 를 창을 띄우는 스크립트를 StringBuilder 클래스를 사용하여 문자열을 추가 시키고 있습니다. 여기에서 String 클래스를 안쓰고 굿이 StringBuilder 클래스를 사용하는 이유는 설명 안하겠습니다. 이부분은 다른 분이 올려놨으니 참고 하세요(최고 아티클의 [초급에서 중수로] .NET에서 문자열에 대한 이해)

그리고 static 로 만든 이유는 매번 자바스크립트를 써야 하는데 그때마다 인스턴스화를 안해주기 위해서 입니다. 그러니깐 언제 어디서든

클래스명.JavascriptAlert("창을 띄워라");

이런식으로 인스턴스화를 안해주고 사용할수가 있는 것이지요. 혹시 만약 이부분이 이해가 안가신다면 클래스 책 조금만 뒤지면 나올겁니다. 이렇게 다른 자바 스크립트도 만들어서 사용하 시면 편할겁니다. 그리고 응용을 해보면 게시판 같은 것을 만들때 html를 해석을 하지 말아야 할때가 있습니다. 이부분도 자주쓰일것같은데 이런것도

public static string Tagdate(string str)

{

   StringBuilder strbuild = new StringBuilder(str);

   strbuild.Replace("&apos;", "'");

   strbuild.Replace("&", "&amp;");

   strbuild.Replace("<", "&lt;");

   strbuild.Replace(">", "&gt;");

   strbuild.Replace("\n", "");

   strbuild.Replace("\r", "");

   strbuild.Replace("\"","");

   strbuild.Replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");

   strbuild.Replace(" ", "&nbsp;");

   return strbuild.ToString();

}


문자열만 넘겨 주면 Replace로 바꿔줘서 리턴 받아 버리면 편하실 겁니다. 설명 할게 별로 없군요. 그냥 하나의 팁같은 걸로 공유 하고 싶었습니다.



using System;

using System.Text;


namespace wangasp

{

    /// <summary>

    /// utils에 대한 요약 설명입니다.

    /// </summary>

    public class utils

    {

        public utils()

        {

           

        }


        public static string JavascriptAlert(string str)

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("   alert(\"" + str + "\");");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();


        }


        public static string Javascriptwindowopen(string str,string at)

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("   window.open(\"" + str + "\",\"\",\"" + at + "\");");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();

        }


        public static string Javascriptwindowopen(string str)

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("   window.open(\"" + str + "\",\"\",\"\");");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();

        }


        public static string JavascriptRedirect(string str)

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("   document.Location.href=\'" + str + "';");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();

        }


        public static string JavascriptReload()

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("window.Location.reload(true);");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();

        }


        public static string JavascriptBack()

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("   history.back();");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();

        }


        public static string JavascriptClose()

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("   self.close();");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();

        }


        public static string HTMLtoSQLServer(string str)

        {

            StringBuilder strbuild = new StringBuilder(str);


            strbuild.Replace("'", "''");


            return strbuild.ToString();

        }


        public static string JavascriptAlertAndLocation(string str,string Locationstr)

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("   alert(\"" + str + "\");Location.href=\""+ Locationstr +"\";");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();

        }


        public static string JavascriptAlertAndOpenerReload(string str)

        {

            StringBuilder strbuild = new StringBuilder("");


            strbuild.Append("<script language=\"javascript\">");

            strbuild.Append("   alert(\"" + str + "\");window.opener.Location.reload();window.close();");

            strbuild.Append("</" + "script>");


            return strbuild.ToString();

        }


        //html를 해석을 못하게 할때 이 함수를 가져다 쓴다.

        public static string TagDisable(string str)

        {

            StringBuilder strbuild = new StringBuilder(str);

           

            strbuild.Replace("&apos;", "'");

            strbuild.Replace("&", "&amp;");

            strbuild.Replace("<", "&lt;");

            strbuild.Replace(">", "&gt;");

            strbuild.Replace("\n", "<br>");

            strbuild.Replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");

            strbuild.Replace(" ", "&nbsp;");


            return strbuild.ToString();

        }


        public static string Tagdate(string str)

        {

            StringBuilder strbuild = new StringBuilder(str);

           

            strbuild.Replace("&apos;", "'");

            strbuild.Replace("&", "&amp;");

            strbuild.Replace("<", "&lt;");

            strbuild.Replace(">", "&gt;");

            strbuild.Replace("\n", "");

            strbuild.Replace("\r", "");

            strbuild.Replace("\"","");

            strbuild.Replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");

            strbuild.Replace(" ", "&nbsp;");


            return strbuild.ToString();

        }


        public static string Taglecture(string str)

        {



            StringBuilder strbuild = new StringBuilder(str);

           

            strbuild.Replace("\r\n", "<br>");


            return strbuild.ToString();

        }

       


    }

}

출처 : 고수닷컴

비주얼 웹 디벨로퍼 2005 익스프레스로 자바스크립트 디버그 하기




비주얼 웹 디벨로퍼 2005 익스프레스로 자바스크립트의 디버그 작업을 할 수 있습니다. 그러나 개발환경이 비주얼 웹 디벨로퍼 2005 익스프레스가 아닌 상황이라면, 디버그 작업이 허용되지 않습니다. 상용 비주얼 스튜디오 2005에서는 스크립트의 디버거가 필요한 상황에서 인터넷 익스플로러에서 바로 연결을 시켜주지만, 익스프레스 버전에서는 그러한 기능이 제외되었기 때문입니다. 여기서는 개발환경이 비주얼 웹 디벨로퍼 2005 익스프레스가 아닌 경우에 어떻게 비주얼 웹 디벨로퍼 2005 익스프레스에서 인터넷 익스플로러 브라우저의 스크립트 디버그를 할 수 있을지를 알아보도록 하겠습니다. 방법은 간단하며, 다음을 따라 해보시면 됩니다. 우선 다음과 같이 디버그 작업을 해볼 소스를 하나 준비하겠습니다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/java script">
window.0nload = function() {
var hello = document.getElementById( "Hello" );
debugger;
alert!( hello.innerHTML );
}
</script>
</head>
<body>
<div id="Hello">Hello</div>
</body>
</html>
이제 이 파일을 비주얼 웹 디벨로퍼 2005 익스프레스에서 디버그하는 방법은 다음과 같습니다.
  1. 비주얼 웹 디벨로퍼 2005 익스프레스를 실행합니다.
  2. 파일 > 새 웹 사이트를 클릭합니다.
  3. 빈 웹 사이트를 선택한 후, 위치 항목은 파일 시스템을 선택해서 적당한 경로를 선택해줍니다. 이 경로는 그냥 임시로 쓰이며, 아무 파일도 필요없이 그냥 빈 디렉터리면 됩니다.
  4. 확인을 클릭합니다.
  5. 이제 솔루션 탐색기를 보면 새 솔루션이 하나 생성되어있을 것입니다.
  6. 메뉴의 디버그 > 디버깅 시작을 클릭합니다.
  7. 디버깅 사용 안 함이라는 창이 나타났다면, 디버깅하도록 설정한 새 Web.config 파일 추가를 선택한 후 확인을 클릭합니다.
  8. 이제 잠시후면, 비주얼 웹 디벨로퍼 2005 익스프레스가 인터넷 익스플로러를 실행할 것입니다. 실행될 인터넷 익스플로러는 디버그 모드로 비주얼 웹 디벨로퍼 2005 익스프레스가 스크립트에 간섭할 수 있는 상태가 됩니다.
  9. 이제 이 인터넷 익스플로러 창에서 아까 작성한 파일을 열어줍니다.
  10. 이제 파일의 9번째 줄의 debugger; 라는 코드가 하이라이트 되면서 해당 라인에서 스크립트 실행이 멈추고, 비주얼 웹 디벨로퍼 2005 익스프레스가 해당페이지를 디버그 할 수 있는 상태가 될 것입니다.
  11. 이제 마음껏 디버깅을 즐기시면 됩니다.


펌 : http://delimount.com
출처 : http://cafe.daum.net/aspdotnet

사용자 삽입 이미지








 ▲listbos1(다중선택)                               ▲listbox2(다중선택)


listbox1에서 여러개의 item을 다중선택하여 listbox2로 추가하였을 때

문제점)
1. listbox1의 selected 속성이 0번 index를 제외하고 모두 false로 된다.
즉, 2번, 3번의 index를 선택하여도 0번index의 item만이 listbox2로 추가된다.


해결한 방법)

listbox에는 DataTextField 와 DataValueField 의 속성을 가지고 있는데 이 중에 DataValueField의 값을 모두 같게 둔다면 위와 같은 현상이 일어날 수 있다.
(test를 위해서 DataValueField의 값을 모두 같게 주었었다...ㅡ.ㅡ;;...)

<추가 사항>
---------------------------------------------------
첫번째, 아이템을 추가할때
<input type=hidden runat=server id=hdnItems> 필드에 내용을 저장하는 방법입니다...

function AddItem()
{
    //아이템 추가
    //추가된 아이템의 값저장(예, 1;2;3;4; )
    document.all['<%=hdnItems.ClientID%>'].value += '추가된 아이템의 value값' + ';';
}

서버컨트롤 실행후

void Button1_Click()
{
    string[] items = this.hdnItems.Value.Split(';');
    foreach(string item in items)
    {
        Response.Write(item + "<br>");
    }
}

두번째, 포스트백을 일으키는 버튼을 클릭했을때
<input type=hidden runat=server id=hdnItems> 필드에 내용을 저장하는 방법입니다...

function SaveItems()
{
    var lb = document.all['<%=ListBox1.ClientID%>'];
    var hval = document.all['<%=hdnItems.ClientID%>'];
    var temp = '';

    for(var i=0; i<lb.length; i++)
    {
        temp += lb.options[i].value + ';'
    }
    hval.value = temp;
}

위의 스크립트를 버튼을 클릭했을때 넣어주면 되겠죠^^

this.Button1.Attributes[""] = "SaveItems();";

void Button1_Click()
{
    string[] items = this.hdnItems.Value.Split(';');
    foreach(string item in items)
    {
        Response.Write(item + "<br>");
    }
}

Pass by Reference 형태가 다분히 로컬 애프리케이션에서만 적용되는 것이 아니고 분산된 환경에서도 적용될 수 있다. 또, 데이터를 많이 가지고 있는 Data Set의 경우 Pass by Value의 형태보다는 Pass by Reference형태의 전달 방식을 사용하면 리소스의 사용에 적은 부담을 가질 수 있다.

 하지만 데이터를 공유한다는 측면에서 조심스럽게 다루어야 한다는 것과 보안에 주의해야한다는 점을 알아야 한다.
웹 서비스를 이용하는 방법을 생각해 보자. 계산기능을 전문적으로 하는 서비스로의 서버를 만들수 있다. 클라이언트로부터 어떤 서비스 요청이 들어 왔을 때(ex- 두 숫자를 더하는 계산 등) 웹 사이트 서버는 웹 서비스 서버에 적재되어있는 계산함수를 호출하게 된다.(원격 프로시져의 호출 - RPC: Remoting Procedul Call) 

 호출 할 때 클라이언트로부터 받은 입력된 두 숫자는 웹 서비스 서버의 계산함수의 파라미터로 전달된다. 웹 서비스 서버에서는 계산기능을 수행하고 난 결과 값을 웹 사이트 서버로 넘겨주게 되고, 웹 서버에서는 결과치를 HTML로 변화하여 클라이언 측으로 보내주게 된다. 이때, 웹 사이트 서버에서의 서비스 함수를 호출 할 때 XML포멧으로 요청하게 되며 리턴되는 결과값도 XML형식의 값으로 전달받는다.

 즉, 웹 서비스란 어떠한 보여줌(View)의 기능보다는 계산(Calculation)적인 요소가 많이 들어가 있는 개념이며 서비스이다.

 웹 서비스는 HTTP를 통한 Remoting Method Call을 수행하는 새로운 아키텍처이다. 클라이언트는 웹 서버내에 정의된 메소드를 호출(Method Call)함으로서 서비스를 받을 수 있다. 인터넷이란 분산환경에서 그 중요성이 커지고 있는 부분은 원격지 응용프로그램과 상호 작용할 수 있어야 한다는 점이다. 이러한 종류의 이터랙션은 주로 클라이언트가 매개 변수를 전달하고 그 결과를 반환하는 프로시져 호출(RPC)로서 모텔링 된다.

 HTTP가 아주 융통성 있는 기술인 것은 사실이지만, 원격 프로시저를 호출하기 위한 프로토콜로서 설계된 것이 아니기 때문에 적절하지 못하다. 그 대신 원격지 응용 프로그램과 통신하는데 사용할 수 있는 다양한 분산객체 프로토콜이 존재한다.

 그 중에는 마이크로 소프트의 디스트리뷰트 컴퍼넌트 오브젝트 모델(Distributed Component Object : DCOM)에서 서용되는 프로토콜, 오브젝트 매니지먼트 그룹(Object Management Group)에서 정의된 Internet Inter-ORB Protocol(IIOP)등이 있다. 이러한 프로토콜은모두 클라이언트가 서버응용 프로그램에게 RPC를 전달한 다음 응답을 받게하는 서비스를 제공한다.

 보통 프로토콜에서는 서로간의 포트를 통하여 통신하게 된다. 예를 들어 HTTP는 80번 포트를, FTP는 21번 전용 포트 등을 사용하여 서로간의 메시지를 전달하게 된다. 반면에 위에서 소개한 분산객체 프로토콜들은 동적으로 할당받은 프로토콜을 사용하여 클라이언트와 서버사이에 통신을 하도록 한다.

 그러나 이부분에서 문제점이 발생한다. 만약 방화벽이 설치되어 있다면 전용프트를 사용하지 않는 포트들은 블로킹을 당해 통신할 수 없다. 따라서 위의 임으적으로 포트번호를 할당받는 분산객체 프로토콜등은 메시지를 전달할 수 없다는 결론이 나온다.

 우리는 "HTTP 프로토콜과 같이 보낼 수 있다면?"이라는 생각을 가질 수 있다. HTTP프로토콜은 전용 80번 포트를 사용하고 방화벽에 의해서 블로킹 당할 필요가 없기 때문에 분산환경에서 리모팅을 호출하는데 있어서 전혀 문제 될 것이 없다. 그래서 SOAP이 탄생하게 된다.

 SOAP(Simple Object Access Protocol)은 HTTP맨 위에 분산객체 프로토콜을 올려 전달하는 것이다. SOAP은 XML 문서를 포함할 수 있는 전용 프로토콜이라 했다. XML문서 내어에는 원격 메소드에 대한 정보(호출할 메소드 이름 등)가 실려있으며 그 정보에 의해서 원격 메소드에 대한 호출을 가능하게 만들어준다.

 클라이언트 측에서 요청한 SOAP패킥은 HTTP Post방식으로 웹 서비스에 넘어가고 웹 서비스의 ASP.NET에서 패킷을 파싱하고 객체와 매소드 이름을 분리해 내어 객체에 대해서는 인스턴스를 실행하고 생성된 객체로 하여금 네소드 호출을 실행한다.

 웹 서비스는 분산환경에서 마치 하난의 컴포넌트처럼 쓰일 수 있다. 웹 서비스는 끼워넣기식으로 하나의 또 다른 클리이언트에 부착될 수 있으며, 웹 환경뿐만아니라 웬도우 애플리케이션에도 임포트 될 수 있다. 웹 서비스는 분산환경에서 사용될 수 있는 컴포넌트라고 생각해도 좋다. 서로간의 웹 서비스들은 Xml과 SOAP을 이용해서 메소드의 정보를 전달하며 통신한다. 이렇게 웹 서비스는 커다란 거미줄 처럼 묶이변서 하나의 애플리케이션을 형성하는 것이다.

 결론을 내리면 닷넷 환경의 핵심은 XML과 SOAP을 이용한 분산 서비스의 구현이라고 볼 수 있다.

-C# & .NET Programming Bible 2nd Edition 에서

1. Web.Config에서 한글 설정
<globalization requestENCODING="ks_c_5601-1987" responseENCODING="ks_c_5601-1987" />
 이렇게 하면 당연히 될 것 같은데 잘 안돼는 경우도 발생.

2. Server.UrlEncode의 사용
소스에 ("Content-Disposition","attachment; filename=" + Server.UrlEncode(strFilename));

 

[개요]

 

Microsoft Visual Studio .NET 2003 Bootstrapper Plug-In을 사용하면 응용 프로그램과 함께 .NET Framework 1.1 및/또는 MDAC 2.7을 재배포하는 설치 관리자를 쉽게 만들 수 있습니다.

.NET Framework 응용 프로그램이 특정 컴퓨터에서 실행되도록 하려면 해당 컴퓨터에 .NET Framework가 설치되어 있어야 합니다. ADO.NET을 사용하여 데이터베이스에 연결하는 모든 .NET Framework 응용 프로그램은 MDAC 2.7을 요구합니다. 많은 컴퓨터에 이미 이러한 구성 요소가 설치되어 있지만 응용 프로그램이 확실하게 실행되도록 하려면 응용 프로그램과 함께 이 구성 요소를 재배포해야 합니다.

Visual Studio .NET 2003 Bootstrapper는 Visual Studio .NET 설치 프로그램 및 배포 프로젝트와 통합됩니다. 이 Bootstrapper를 사용하여 대상 컴퓨터에 요구되는 필수 구성 요소가 있는지 검사하여 필요한 경우 자동으로 해당 요소를 설치하는 단일 설치 관리자를 만들 수 있습니다. 컴퓨터를 다시 시작해야 하는 구성 요소가 있는 경우, 설치 관리자는 이후에 자동으로 작업을 다시 진행합니다. 응용 프로그램 사용자는 단지 하나의 설치 프로그램을 실행하여 필수 구성 요소와 응용 프로그램을 설치하면 됩니다.


[한번의 인스톨로 닷넷 환경을 완벽하게 갖추자.]

 

왜 부트스트래퍼가 필요한지가 궁금할것이다...

먼저 사용자 환경은 내 프로그램이 필요로 하는 기본 요구사항들을 만족하고 있는지 알수없다.

실행해보기 전까지는 말이다.

 

정작 자신이 개발한 프로그램을 배포해보면 정말 이유도 가지가지다.

안되는 이유말이다.

 

이 이유들중 가장 중요한 이유 두가지를 부트스트래퍼를 이용해서 처리해 보도록 하겠다.

 

먼저 아래의 url 로 이동해서 MS에서 제공하는 Microsoft Visual Studio .NET 2003 Bootstrapper Plug-In 을 이용해보도록 하겠다.

 

http://www.microsoft.com/downloads/details.aspx?FamilyID=627921a0-d9e7-43d6-a293-72f9c370bd19&DisplayLang=ko

 

간단하게 PluginInstaller.msi 파일을 설치하는것만으로도 셋팅은 끝난다.

정말이지 쉽고 간편하다.

몰라서 사용하지 못하는것 뿐이지 어려워서 사용하지 못하는건 적어도 아니다.


Capture2.gif     

 

설치하고나면 이렇게 부트스트래퍼가 생긴다.

이 프로그램이 설치되어있는 컴퓨터에서 배포프로젝트를 만들어서 배포하게되면 자기가 개발한 용량보다 약 25메가정도가 크다는것을 금방알수가 있을것이다.

 

왜냐하면 이렇게 배포된 인스톨 프로그램에는 기본적으로 프레임웍 1.1 과 언어팩, 그리고 mdac 등이 기본적으로 포함되어있으며 인스톨시에 사용자 컴퓨터에 설치되지 않았을경우 바로 인스톨 화면을 제공해주기 때문이다.

 

실제적용해보면 아주 부드럽게 화면과 화면이 이어지며 프래임워크와 mdac 와 언어팩들을 설치해주는 화면을 볼수있을것이다.

 

기존에는 배포하는 프로그램설치하랴.. 프래임웍 설치하랴.. mdac 설치하랴..언어팩설치하랴... 문제도 많고 말도 많았는데 이런 기능을 이용하면 한번 설치로 상쾌하게 인스톨 시킬수 있을것이다.

 

[정리]

이 이외에도 MSDN에서는 아주 유용한 기능들을 많이 제공한다.

 

출처 : 고수닷넷에 대니님께서 올리신 글.

Visual Studio .NET Framework BootStrapper Plug-in을 사용한 .NET Framework 재배포

Microsoft Visual Studio .NET 2003 Bootstrapper Plug-in 다운로드

Visual Studio .NET 2003의 설치 프로젝트는 응용 프로그램과 함께 .NET Framework를 설치하는 데 사용할 수 있지만, 개발 컴퓨터에 Visual Studio .NET Framework BootStrapper Plug-in 옵션을 설치한 경우에만 가능합니다.

Visual Studio .NET Framework BootStrapper Plug-in은 .NET Framework 부트스트래퍼뿐만 아니라 Windows Installer 부트스트래퍼를 포함하도록 설치 프로젝트의 부트스트래퍼 속성 기능을 수정합니다. 그런 다음 .NET Framework의 재배포 가능 요소는 사용자의 응용 프로그램과 함께 패키지화됩니다. 사용자가 부트스트래퍼 setup.exe를 실행할 경우 이 실행 프로그램은 설치 시에 .NET Framework의 버전이 올바른지 확인하고 필요할 경우 응용 프로그램을 설치하기 전에 이 .NET Framework 버전을 설치합니다.

    참고  영어 외의 언어일 경우 해당 언어용 언어 팩이 .NET Framework와 함께 설치됩니다.

    참고  Visual Studio .NET Framework BootStrapper Plug-in은 웹 부트스트래퍼를 수정하지 않습니다. 부트스트래퍼 속성을 웹 부트스트래퍼로 설정하면 웹을 통해서만 Windows Installer의 부트스트래핑을 실행할 수 있습니다.

또한 응용 프로그램에서 데이터 액세스가 필요한 경우, 설치할 때 Microsoft Data Access Components(MDAC)를 함께 설치할 수 있습니다.


플러그인이 설치되어 있는지 확인하려면

  1. 제어판에서 프로그램 추가/제거를 클릭합니다.
  2. 프로그램 추가/제거 대화 상자의 현재 설치된 프로그램 목록에서 Microsoft Visual Studio .NET 2003 BootStrapper Plug-in을 확인합니다.

    만약 Microsoft Visual Studio .NET 2003 BootStrapper Plug-in이 설치되어 있지 않으면 Visual Studio .NET Framework BootStrapper Plug-in을 다운로드하여 설치해야 합니다.

      참고  Visual Studio .NET Framework BootStrapper Plug-in을 제거하려면 목록에서 선택하여 제거를 클릭하면 됩니다.

설치 프로젝트를 이용해 .NET Framework를 설치하려면

  1. Visual Studio .NET Framework BootStrapper Plug-in이 설치되어 있는지 확인합니다.
  2. 솔루션 탐색기에서 설치 프로젝트를 선택합니다. 프로젝트 메뉴에서 속성을 선택합니다.
  3. 부트스트래퍼 속성을 Windows Installer 부트스트래퍼로 설정합니다.

    .NET Framework 재배포 가능 요소가 완성되면 설치 프로젝트용 Setup.exe와 함께 패키지로 제공됩니다 .

      참고  .NET Framework의 시작 조건은 .NET Framework를 참조하는 모든 프로젝트를 위해 기본적으로 사용 가능하도록 설정되어 있어야 합니다. 시작 조건을 확인하려면 보기 메뉴에서 편집기를 가리킨 다음 시작 조건을 선택하고 .Net Framework라고 되어 있는 시작 조건을 찾습니다.

설치 프로젝트를 이용해 MDAC를 설치하려면

  1. Visual Studio .NET Framework BootStrapper Plug-in이 설치되어 있는지 확인합니다.
  2. 솔루션 탐색기에서 설치 프로젝트를 선택합니다. 보기 메뉴에서 편집기를 가리키고 시작 조건을 선택합니다.
  3. 대상 컴퓨터의 요구 사항 노드를 선택합니다. 작업 메뉴에서 레지스트리 시작 조건 추가를 선택합니다.
  4. RegistryEntry1 검색 노드를 선택합니다. 속성 창에서 RegKey 속성을 선택하고 Software\Microsoft\DataAccess를 입력합니다.
  5. Root 속성을 선택한 다음 vsdrrHKLM를 선택합니다.
  6. Value 속성을 선택한 다음 FullInstallVer를 입력합니다.
  7. Property을 선택한다음 MDACSEARCH를 입력합니다.
  8. 시작 조건 편집기에서 Condition1 노드를 선택합니다. 속성 창에서 Condition 속성을 선택한 다음 MDACSEARCH>="2.6"을 선택합니다.
  9. 솔루션 탐색기에서 설치 프로젝트를 선택합니다. 프로젝트 메뉴에서 속성을 선택합니다.
  10. 부트스트래퍼 속성을 Windows Installer 부트스트래퍼로 설정합니다.

    .NET Framework 재배포 가능 요소와 MDAC는 설치 프로젝트를 위한 Setup.exe와 함께 패키지로 제공됩니다.

/// <summary>
/// 'showMessage'을 리턴하는 데이터 셋 만들기
/// </summary>
/// <param name="columnCount">그리드에 바인딩 될 컬럼 수</param>
/// <param name="columnName">해당 그리드에서 사용하는 컬럼 명</param>
/// <param name="showMessage">0번째 컬럼에 담아서 리턴할 메세지</param>
/// <returns>DataSet</returns>
public DataSet NoDataSet( int columnCount, string columnName, string showMessage )
{
   DataSet ds   = new DataSet( "NoData" );
   DataTable dt = new DataTable( "table" );

   

   string[] strColumnSplit = columnName.Split(',');
   
   for( int c = 0; c < columnCount; c++ )
   {
       dt.Columns.Add( strColumnSplit[c] );  

   }
                    
   ds.Tables.Add(dt);
   
   DataRow row = ds.Tables["table"].NewRow();
   row[0]          = showMessage;

   ds.Tables["table"].Rows.Add(row);

   

   return ds;
}


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

/// <summary>
/// 'showMessage'을 리턴하는 데이터 셋 만들기
/// </summary>
/// <param name="columnName">(Array)해당 그리드에서 사용하는 컬럼명</param>
/// <param name="showMessage">0번째 컬럼에 담아서 리턴할 메세지</param>
/// <returns>DataSet</returns>

public DataSet NoDataSet( string[] columnName, string showMessage )
{
   DataSet ds   = new DataSet( "NoData" );
   DataTable dt = new DataTable( "table" );


   for( int c = 0; c < columnName.Length; c++ )
   {
       dt.Columns.Add( columnName[c] );//, typeof(string) );
   }
                    
   ds.Tables.Add(dt);
   
   DataRow row = ds.Tables["table"].NewRow();
   row[0]          = showMessage;

   ds.Tables["table"].Rows.Add(row);

   return ds;

}

 

Appendix

Exceptions to the supported platforms

Namespace

Item

XP Pro

XP Home

2000

NT 4

98 ME

System.Web

 

Y

N

Y

N

N

System.Web.Caching

 

Y

N

Y

N

N

System.Web.Configuration

 

Y

N

Y

N

N

System.Web.Security

 

Y

N

Y

N

N

System.Web.UI

 

Y

N

Y

N

N

System.Web.UI.Design

 

Y

N

Y

N

N

System.Web.UI.Design.WebControls

 

Y

N

Y

N

N

System.Web.UI.Design.Util

 

Y

N

Y

N

N

System.Web.UI.HTMLControls

 

Y

N

Y

N

N

System.Web.UI.WebControls

 

Y

N

Y

N

N

System.Web.Util

 

Y

N

Y

N

N

System.Web.Handlers

 

Y

N

Y

N

N

System.Web.Hosting

 

Y

N

Y

N

N

System.Web.SessionState

 

Y

N

Y

N

N

System.Web.Mail

 

Y

N

Y

N

N

System.EnterpriseServices

 

Y

Y

Y

N

N

System.Messaging

Message.Transaction.Id

Y

Y

Y

N

N

System.Messaging

Message.Transaction.IsLastInTransaction

Y

Y

Y

N

N

System.Messaging

Message.Transaction.IsFirstInTransaction

Y

Y

Y

N

N

System.Diagnostics

Process.PriorityBoostEnabled

Y

Y

Y

Y

N

System.Diagnostics

Process.MinWorkingSet

Y

Y

Y

Y

N

System.Diagnostics

Process.MaxWorkingSet

Y

Y

Y

Y

N

System.Diagnostics

Process.VirtualMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.UserProcessorTime

Y

Y

Y

Y

N

System.Diagnostics

Process.NonpagedSystemMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PrivilegedProcessorTime

Y

Y

Y

Y

N

System.Diagnostics

Process.PrivateMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PeakVirtualMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PeakWorkingSet

Y

Y

Y

Y

N

System.Diagnostics

Process.PeakPagedMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PagedSystemMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PagedMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.WorkingSet

Y

Y

Y

Y

N

System.Diagnostics

Process.BasePriority

Y

Y

Y

Y

N

System.Diagnostics

Process.PowerBroadcastStatus

Y

Y

Y

Y

N

System.ServiceProcess

ServiceControllerStatus

Y

Y

Y

Y

N

System.ServiceProcess

ServiceStartMode

Y

Y

Y

Y

N

System.ServiceProcess

ServiceType

Y

Y

Y

Y

N

System.ServiceProcess

ServiceProcessInstaller

Y

Y

Y

Y

N

System.ServiceProcess

ServiceInstaller

Y

Y

Y

Y

N

System.ServiceProcess

ServiceController

Y

Y

Y

Y

N

System.ServiceProcess

ServiceBase

Y

Y

Y

Y

N

System.IO

WatcherChangeTypes

Y

Y

Y

Y

N

System.IO

ChangedFilters

Y

Y

Y

Y

N

System.IO

ErrorEventArgs

Y

Y

Y

Y

N

System.IO

ErrorEventHandler

Y

Y

Y

Y

N

System.IO

FileSystemEventArgs

Y

Y

Y

Y

N

System.IO

FileSystemEventHandler

Y

Y

Y

Y

N

System.IO

FileSystemWatcher

Y

Y

Y

Y

N

System.IO

InternalBufferOverflowException

Y

Y

Y

Y

N

System.IO

IODescriptionAttribute

Y

Y

Y

Y

N

System.IO

RenamedEventArgs

Y

Y

Y

Y

N

System.IO

RenamedEventHandler

Y

Y

Y

Y

N

System.IO

WaitForChangedResult

Y

Y

Y

Y

N

System.IO

NotifyFilters

Y

Y

Y

Y

N

System.Diagnostics

CounterCreationDataCollection

Y

Y

Y

Y

N

System.Diagnostics

CounterCreationData

Y

Y

Y

Y

N

System.Diagnostics

CounterSample

Y

Y

Y

Y

N

System.Diagnostics

CounterSampleCalculator

Y

Y

Y

Y

N

System.Diagnostics

EntryWrittenEventArgs

Y

Y

Y

Y

N

System.Diagnostics

EntryWrittenEventHandler

Y

Y

Y

Y

N

System.Diagnostics

EventLog

Y

Y

Y

Y

N

System.Diagnostics

EventLogEntry

Y

Y

Y

Y

N

System.Diagnostics

EventLogEntryCollection

Y

Y

Y

Y

N

System.Diagnostics

EventLogEntryType

Y

Y

Y

Y

N

System.Diagnostics

EventLogInstaller

Y

Y

Y

Y

N

System.Diagnostics

InstanceData

Y

Y

Y

Y

N

System.Diagnostics

InstanceDataCollection

Y

Y

Y

Y

N

System.Diagnostics

InstanceDataCollectionCollection

Y

Y

Y

Y

N

System.Diagnostics

PerformanceCounter

Y

Y

Y

Y

N

System.Diagnostics

PerformanceCounterCategory

Y

Y

Y

Y

N

System.Diagnostics

PerformanceCounterInstaller

Y

Y

Y

Y

N

System.Diagnostics

PerformanceCounerManager

Y

Y

Y

Y

N

System.Diagnostics

PerformanceCounterType

Y

Y

Y

Y

N

System.Diagnostics

EventLogTraceListener

Y

Y

Y

Y

N

System.Environment

WorkingSet

Y

Y

Y

Y

N

System.Threading

ThreadPool.BindHandle

Y

Y

Y

Y

N

System.Threading

Overlapped.Pack

Y

Y

Y

Y

N

System.Threading

Overlapped.Unpack

Y

Y

Y

Y

N

System.Threading

Overlapped.UnsafePack

Y

Y

Y

Y

N

System.Diagnostics

Process.PeakVirtualMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.NonpagedSystemMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PriorityBoostEnabled

Y

Y

Y

Y

N

System.Diagnostics

Process.WorkingSet

Y

Y

Y

Y

N

System.Diagnostics

Process.MaxWorkingSet

Y

Y

Y

Y

N

System.Diagnostics

Process.PrivilegedProcessorTime

Y

Y

Y

Y

N

System.Diagnostics

Process.MinWorkingSet

Y

Y

Y

Y

N

System.Diagnostics

Process.StartTime

Y

Y

Y

Y

N

System.Diagnostics

Process.PrivateMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PagedSystemMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PeakWorkingSet

Y

Y

Y

Y

N

System.Diagnostics

Process.UserProcessorTime

Y

Y

Y

Y

N

System.Diagnostics

Process.PagedMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.PeakPagedMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.VirtualMemorySize

Y

Y

Y

Y

N

System.Diagnostics

Process.TotalProcessorTime

Y

Y

Y

Y

N

System.Diagnostics

Process.ExitTime

Y

Y

Y

Y

N

System.EnterpriseServices

ApplicationActivationAttribute.SoapVRoot

Y

Y

N

N

N

System.EnterpriseServices

ApplicationQueuingAttribute.MaxListenerThreads

Y

Y

N

N

N

System.EnterpriseServices

ContextUtil.ApplicationId

Y

Y

N

N

N

System.EnterpriseServices

ContextUtil.ApplicationInstanceId

Y

Y

N

N

N

System.EnterpriseServices

PrivateComponentAttribute

Y

Y

N

N

N

System.EnterpriseServices

TransactionAttribute.Timeout

Y

Y

N

N

N

System.EnterpriseServices

TransactionIsolationLevel

Y

Y

N

N

N

System.EnterpriseServices

Namespace overview

Y

Y

Y

N

N

System.EnterpriseServices

AccessChecksLevelOption

Y

Y

Y

N

N

System.EnterpriseServices

ActivationOption

Y

Y

Y

N

N

System.EnterpriseServices

ApplicationAccessControlAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ApplicationActivationAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ApplicationIDAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ApplicationNameAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ApplicationQueuingAttribute

Y

Y

Y

N

N

System.EnterpriseServices

AuthenticationOption

Y

Y

Y

N

N

System.EnterpriseServices

AutoCompleteAttribute

Y

Y

Y

N

N

System.EnterpriseServices

BOID

Y

Y

Y

N

N

System.EnterpriseServices

BYOT

Y

Y

Y

N

N

System.EnterpriseServices

ComponentAccessControlAttribute

Y

Y

Y

N

N

System.EnterpriseServices

COMTIIntrinsicsAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ConstructionEnabledAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ContextUtil

Y

Y

Y

N

N

System.EnterpriseServices

DescriptionAttribute

Y

Y

Y

N

N

System.EnterpriseServices

EventClassAttribute

Y

Y

Y

N

N

System.EnterpriseServices

EventTrackingEnabledAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ExceptionClassAttribute

Y

Y

Y

N

N

System.EnterpriseServices

IISIntrinsicsAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ImpersonationLevelOption

Y

Y

Y

N

N

System.EnterpriseServices

InstallationFlags

Y

Y

Y

N

N

System.EnterpriseServices

InterfaceQueuingAttribute

Y

Y

Y

N

N

System.EnterpriseServices

IRegistrati[안내]태그제한으로등록되지않습니다-onHelper

Y

Y

Y

N

N

System.EnterpriseServices

IRemoteDispatch

Y

Y

Y

N

N

System.EnterpriseServices

ITransaction

Y

Y

Y

N

N

System.EnterpriseServices

JustInTimeActivationAttribute

Y

Y

Y

N

N

System.EnterpriseServices

LoadBalancingSupportedAttribute

Y

Y

Y

N

N

System.EnterpriseServices

MustRunInClientContextAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ObjectPoolingAttribute

Y

Y

Y

N

N

System.EnterpriseServices

PrivateComponentAttribute

Y

Y

N

N

N

System.EnterpriseServices

PropertyLockMode

Y

Y

Y

N

N

System.EnterpriseServices

PropertyReleaseMode

Y

Y

Y

N

N

System.EnterpriseServices

Registrati[안내]태그제한으로등록되지않습니다-xxonErrorInfo

Y

Y

Y

N

N

System.EnterpriseServices

RegistrationException

Y

Y

Y

N

N

System.EnterpriseServices

Registrati[안내]태그제한으로등록되지않습니다-onHelper

Y

Y

Y

N

N

System.EnterpriseServices

Registrati[안내]태그제한으로등록되지않습니다-onHelperTx

Y

Y

Y

N

N

System.EnterpriseServices

ResourcePool

Y

Y

Y

N

N

System.EnterpriseServices

SecureMethodAttribute

Y

Y

Y

N

N

System.EnterpriseServices

SecurityCallContext

Y

Y

Y

N

N

System.EnterpriseServices

SecurityCallers

Y

Y

Y

N

N

System.EnterpriseServices

SecurityIdentity

Y

Y

Y

N

N

System.EnterpriseServices

SecurityRoleAttribute

Y

Y

Y

N

N

System.EnterpriseServices

ServicedComponent

Y

Y

Y

N

N

System.EnterpriseServices

ServicedComponentException

Y

Y

Y

N

N

System.EnterpriseServices

SharedProperty

Y

Y

Y

N

N

System.EnterpriseServices

SharedPropertyGroup

Y

Y

Y

N

N

System.EnterpriseServices

SharedPropertyGroupManager

Y

Y

Y

N

N

System.EnterpriseServices

SynchronizationAttribute

Y

Y

Y

N

N

System.EnterpriseServices

SynchronizationOption

Y

Y

Y

N

N

System.EnterpriseServices

TransactionAttribute

Y

Y

Y

N

N

System.EnterpriseServices

TransactionIsolationLevel

Y

Y

N

N

N

System.EnterpriseServices

TransactionOption

Y

Y

Y

N

N

System.EnterpriseServices

TransactionVote

Y

Y

Y

N

N

System.EnterpriseServices

XACTTRANSINFO

Y

Y

Y

N

N

System.EnterpriseServices

ContextUtil.PartitionId

Y

Y

N

N

N

System.EnterpriseServices

TransactionAttribute.
Isolation

Y

Y

N

N

N

System.EnterpriseServices.
CompensatingResourceManager

ApplicationCrmEnabledAttribute

Y

Y

Y

N

N

System.EnterpriseServices.
CompensatingResourceManager

Clerk

Y

Y

Y

N

N

System.EnterpriseServices.
CompensatingResourceManager

ClerkInfo

Y

Y

Y

N

N

System.EnterpriseServices.
CompensatingResourceManager

ClerkMonitor

Y

Y

Y

N

N

System.EnterpriseServices.
CompensatingResourceManager

Compensator

Y

Y

Y

N

N

System.EnterpriseServices.
CompensatingResourceManager

CompensatorOptions

Y

Y

Y

N

N

System.EnterpriseServices.
CompensatingResourceManager

LogRecord

Y

Y

Y

N

N

System.EnterpriseServices.
CompensatingResourceManager

LogRecordFlags

Y

Y

Y

N

N

System.EnterpriseServices.
CompensatingResourceManager

TransactionState

Y

Y

Y

N

N

 

 

 

 

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/framewkwinsupp.asp 발췌

 

출처 : http://cafe.daum.net/aspdotnet

DataGrid를 엑셀로 변환하는 방법은 싸이트에 많이 올라와 있고요.

그런데 변환된 엑셀의 헤더나, 컬럼길이, 색깔 등을 마음대로 제어하기가 좀 어렵더라고요.

저는 다른 방법으로 엑셀을 다운받게 했습니다.  ==> 첨부참조


즉 원하는 모양대로 html을 만들어서 데이타 부분만 Loop돌면서 만드는거죠.

첨부를 보시면 DataSet으로 데이타를 받아내는 foreach문과 print_list 변수의 셋팅이 핵심입니다.

생각보다는 간단했습니다.


    ....

    ....

    print_list = "<html> \r\n";

    허걱~~

    html 이 이상하게 먹히네요.

    첨부를 참조하세요....

    93 ~ 94Line....

    ....

    ....



그런데, 제 PC에서는 잘 되던게  다른 Client PC에서는 한글이 깨지더군요.

제 PC의 엑셀은 2002, 다른 Client PC의 엑셀은 2000.

정확히는 엑셀이 인코딩을 인식 못하는 경우가 있습니다.

엑셀의 메뉴 [도구] -> [옵션] -> (일반 탭) -> (웹옵션 버튼) -> (인코딩 탭) 에서 확인할 수 있습니다.

아마도 엑셀2000의 버그인 듯함.


프로그램 아무리 잘만들어도, web.config 잘설정해도,

다운받는 PC가 Excel 2000이면 위에서 주석처리한 코딩은 한글이 깨집니다.

주석라인 밑에서 보는 것처럼 태그정보를 정확하게 쌍따옴표로 묶어야 합니다.


이 하나 때문에 반나절 보냈습니다.

^^;;


저처럼 시간 허비하는 분이 없으시길 빌며 2000.


출처 : http://club.cyworld.nate.com/51289444167/9627141

 경우에 따라 유효성 검사를 무시할 수 있습니다.

예를 들어, 페이지에 "취소" 단추나 탐색 단추가 있으면 사용자가 모든 유효성 검사 필드를 제대로 채우지 않아도 페이지를 게시할 수 있어야 합니다. ASP.NET 서버 컨트롤을 설정하여 서버와 클라이언트 모두에서 또는 클라이언트에서만 유효성 검사를 무시할 수 있습니다.


서버측 및 클라이언트측 휴효성 검사 해제

특정 컨트롤이 유효성 검사를 무시하게 하려면 컨트롤의 CausesValidation 속성을 false로 설정합니다.

<asp:Button id="Button1" runat="server"
   Text="Cancel" CausesValidation="False">
</asp:Button>

또한 유효성 검사 컨트롤을 해제하여 해당 컨트롤을 사용하여 유효성 검사가 모두 수행되거나 전혀 수행되지 않을 경우 렌더링되지 않도록 할 수 있습니다. 유효성 검사 컨트롤을 해제하려면 유효성 검사 컨트롤의 Enabled 속성을 false로 설정합니다.


클라이언트측 유효성 검사만 해제

서버에서는 유효성 검사가 수행되고 클라이언트에서는 수행되지 않게 하려면 각 유효성 검사 컨트롤이 클라이언트측 스크립트를 생성하지 않게 설정할 수 있습니다. 이는 클라이언트의 동적 업데이트 시 페이지 레이아웃에 문제가 있을 경우 또는 유효성 검사를 수행하기 전에 일부 서버 코드를 실행하고자 할 때 유용합니다.

클라이언트측 유효성 검사를 해제하려면 유효성 검사 컨트롤의 EnableClientScript 속성을 false로 설정합니다

출처 : MSDN

 Ajax - A New Approach to Web Applications

위의 제목은 Ajax라는 단어를 처음 사용한 것으로 알려진 Jesse James Garrett의 Ajax에 대한 소개글의 제목입니다. 제목에서 알 수 있듯이 Ajax는 웹 응용 프로그램 개발을 위한 새로운 접근법입니다. Garrett의 원문을 읽고 싶으신 분은 여기를 클릭해 주세요.

위 글을 보면 아시겠지만 Garrett은 이미 2005년 2월에 Ajax라는 새로운 접근 방법을 제시했습니다. 그리고 그것을 가장 먼저 채택하고 발전시켜 온 곳이 바로 구글(www.google.com)  이지요.

일반적으로 Ajax를 소개할 때 단골손님처럼 빠지지 않고 등장하는 것이 바로 구글 Earch와 구글 Suggest입니다. 구글 Suggest는 네이버나 다음등 국내 대형 포털에서도 이제는 익숙하게 사용하고 있는 기능들이지요.

재미있는 것은 웹 응용 프로그램에 대한 새로운 접근법으로 제시된 Ajax가 결코 새롭지 않은 기술들을 이용하고 있다는 것입니다. 자바스크립트는 이미 1990년대 중반 월드 와이드 웹의 폭발적으로 보편화되기 시작하던 때부터 존재하고 있었습니다.

XML 또한 제법 오래전에 표준으로 제정된 개념이었고 Ajax의 핵심을 담당하는 XmlHttpRequest 역시 IE 4.0부터 제공이 되던 기술이었습니다. 다만 그 당시에는 지금과 같은 초고속 인터넷 망의 보급이 여의치 않았던 시절이었고 그런 상태에서 XmlHttpRequest를 이용한 비동기 통신을 시도했다면 아마도 느린 속도 때문에 사용자들은 웹 브라우저가 멈춰버린 것으로 오해했을지도 모릅니다.

어찌됐든 지금은 눈깜짝할 새에 웹 페이지를 보여줄 수 있는 고속 인터넷 시대가 되었고 Ajax는 오랜 무명의 터널을 지나 웹 개발자들의 수퍼스타가 되어 버렸습니다.


Ajax를 정의하는 요소들

Ajax의 가장 큰 특징은 자바 스크립트와 XML 등의 표준 기술들을 이용하여 클라이언트와 서버 사이의 비동기 통신을 가능하게 한다는 것입니다. 웹 응용 프로그램의 관점에서 보면 사용자가 라운드트립을 느끼지 못하게 하면서도 서버와 데이터 교환이 가능해 진다는 것입니다.

경력이 조금있는 웹 개발자라면 누구나 한 번쯤 깜박임 없는 웹 응용 프로그램의 개발을 시도해 보았을 것입니다. 적어도 Ajax를 모르기 전에는 숨겨진 프레임이나 IFRAME 등을 이용한 꽁수(?)를 써서 비슷한 기능을 구현하기도 했었지요. 그러나 실제로 Ajax 기법이 적용된 웹 사이트들은 여전히 숨겨진 프레임이나 IFRAME을 함께 사용하고 있으니 단지 꽁수라고 치부해 버리기는 어렵습니다.

앞서 소개했던 Garrett은 자신의 글에서 Ajax를 정의하는 요소를 다음과 같이 소개하고 있습니다.

1. 표준을 따르는 UI 표현 방법

XHTML과 CSS와 같은 표준화된 기술을 이용하여 웹 브라우저 독립적인 UI의 표현이 가능합니다.

2. DOM을 이용한 동적인 페이지 표현

DOM (Document Object Model)을 이용하여 동적으로 웹 페이지의 컨텐츠를 변경하거나 페이지 요소와 상호작용할 수 있습니다.

3. XML/XSLT를 이용한 데이터 교환 및 표현

표준 기술인 XML과 XSLT를 이용하여 데이터를 교환하고 표현할 수 있습니다.

4. XMLHttpRequest를 이용한 비동기 데이터 전송

XMLHttpRequest를 이용하여 비동기 데이터 통신이 구현될 수 있습니다.

5. 이 모든 것들을 어우르기 위한 자바 스크립트

그리고 이러한 모든 것들은 자바스크립트를 통해 제어할 수 있습니다.

Garrett은 이와 같은 5가지 조건이 바로 Ajax 스타일의 웹 응용 프로그램을 개발하는데 필요한 요소라고 말하고 있습니다. 그러나 이 5가지가 반드시 사용되어야 하는 것은 아닙니다. 자바 스크립트와 XMLHttpRequest를 이용하여 비동기 통신을 구현할 수 있다면 이것도 Ajax 스타일의 웹 응용 프로그램이라 할 수 있지요.


Ajax, 대체 어떤 장점이?

그렇다면 우리가 Ajax를 사용할 경우 어떤 장점이 있을까요? 우리는 왜 Ajax에 열광하고 이것을 배우기 위해 안달복달 하는 것일까요? 왜 많은 개발자들이 자신이 사용하는 웹 개발 언어를 지원하는 Ajax 라이브러리를 앞다투어 개발하고 공개하고 있는 것일까요?

먼저 기존의 웹 응용 프로그램과 Ajax를 채택한 웹 응용 프로그램의 동작 방식이 어떻게 다른지 Garrett이 제시한 그림을 보면서 이야기 해보도록 하겠습니다.

그림 1: 기존 웹 응용 프로그램과 Ajax 스타일 웹 응용 프로그램의 동작 방식


그림에서 보듯이 기존의 웹 응용 프로그램은 웹 브라우저와 웹 서버 사이에서 사용자의 특정 동작이 발생할 때마다 매번 라운드 트립이 발생했었습니다. 이 과정에서 사용자는 라운드 트립 이후 서버로부터 웹 브라우저가 페이지를 다운로드 하는 동안에 늘 썰렁한 하얀 화면을 보고 있어야 했었지요.

그에 반해 Ajax 스타일의 웹 응용 프로그램은 XMLHttpRequest를 이용하여 백그라운드에서 서버와의 통신을 수행합니다. 또한 HTML이나 CSS, 자바 스크립트 등이 모두 새로 전송되는 것이 아니라 필요한 데이터만 XML 형태로 전송되므로 네트워크 트래픽을 줄일 수 있다는 장점도 있지요.

제가 생각하기에 가장 큰 장점은 서버가 해야 할 일을 클라이언트에게 나누어 줄 수 있다는 것입니다. 즉, 서버는 데이터만 전송해 주고 이 데이터를 가공하고 UI에 표시하는 것은 자바스크립트를 통해 클라이언트 측에서 처리할 수 있다는 것이지요. 계속해서 발전하는 클라이언트 컴퓨터의 성능을 제대로 활용할 수 있는 방법이라 할 수 있습니다.

Ajax 모델을 채택할 경우 우리가 얻을 수 있는 장점을 간단히 소개해 보면 다음과 같습니다.

1. 비동기 통신을 통한 UI 성능의 향상

웹 브라우저가 서버와 통신하는 동안 사용자는 자신이 원하는 다른 작업을 수행할 수도 있습니다. 왜냐하면 브라우저와 서버의 통신이 비동기적으로 진행되기 때문이지요. 버튼 한 번 클릭하고 서버로부터 응답이 오기까지 아무것도 할 수 없었던 것과 비교해 볼 때 이는 활용 정도에 따라 대단히 생산적인 일을 할 수 있는 좋은 방법이 됩니다.

2. 네트워크 트래픽의 감소와 서버/클라이언트의 분업

웹 브라우저가 현재 페이지 데이터를 서버로 전송한 후 서버에서 처리된 결과는 다시 클라이언트로 전달됩니다. 이 때 페이지를 재구성하기 위해 모든 HTML 코드와 CSS 코드, 자바 스크립트 코드 등이 함께 다운로드되고 실행됩니다. ASP.NET의 이벤트 드리븐 웹 폼 페이지의 경우 버튼을 클릭하면 해당 페이지가 다시 로드됩니다. 같은 페이지를 보여주기 위해 매번 많은 양의 데이터가 서버로부터 클라이언트로 전송되는 것이지요.

그러나 Ajax를 이용하면 서버는 최소한의 데이터만을 클라이언트로 보내게 됩니다. 클라이언트는 이 데이터를 받아 DOM을 이용하여 페이지의 컨텐츠를 업데이트 해주게 되지요. 클라이언트 또한 서버가 작업하는데 필요한 최소한의 정보만 골라서 보낼 수 있습니다.

3. C/S 환경과의 차이점을 최소화

최근에는 많은 기업용 소프트웨어들이 웹을 기반으로 만들어지고 있습니다. 인터넷과 웹 브라우저만 있으면 언제 어디서든 활용할 수 있다는 장점 때문이지요. 그러나 한편으로는 특정 작업을 수행할 때마다 라운드 트립 때문에 멀뚱멀뚱 기다려야 한다는 것, 그리고 웹이 가진 한계로 인해 기존의 기업용 소프트웨어들이 제공하던 것과 유사한 UI를 구현한다는 것이 매우 어려웠다는 점입니다.

그러나 Ajax를 통해 이러한 웹 기반 응용 프로그램의 단점을 어느 정도 커버할 수 있게 되었습니다. 가장 대표적인 예가 바로 얼마전 발표된 구글 스프레드 시트입니다.

그림 2: 구글 스프레드 시트의 모습

그림에서 보듯이 구글은 웹 브라우저에서 마이크로소프트의 엑셀과 유사한 UI를 구현해 두었습니다. 우리가 알고 있는 것과 같은 방법으로 이 스프레드 시트를 사용할 수 있으며 작성된 시트는 엑셀 파일이나 CSV 파일로 내 컴퓨터로 다운로드 할 수도 있습니다.

물론 엑셀과 비교해 볼 때 매우 단순한 기능만이 제공될 뿐이지만 업무에 꼭 필요한 기능들을 구현하는데는 필요한 시간이 그다지 길지 않을 것으로 예상됩니다.

이처럼 기존의 데스크톱 응용 프로그램과의 차이점을 줄이고 거기에 웹이 가진 장점을 더욱 극대화함으로써 Ajax는 새로운 형태의 응용 프로그램 개발 방향을 제시하고 있습니다.


Ajax, 그럼 누구나 좋아라해야 하는걸까?

세상 모든 이치가 그렇듯 좋은 점이 있으면 나쁜 점도 있게 마련이겠지요. Ajax라고 무슨 용빼는 재주가 있어서 모든 것이 다 좋기만 하지는 않을 것입니다. Ajax가 가지는 단점, 어떤 것들이 있을까요?

1. 아직은 쉽지 않은 브라우저 독립적인 웹 페이지

아시다시피 웹 브라우저들은 그동안 인터넷 시장을 차지하기 위한 기업들의 이해관계 덕분에 각기 제멋대로 발전해 왔습니다. 물론 최근에는 이러한 차이점을 줄이고 표준을 받아들이려는 노력이 가시화 되고 있으며 Ajax가 그런 노력들에 많은 보탬이 되고 있습니다.

그러나 아직까지도 브라우저 독립적인 페이지를 개발하는 것은 쉬운 일이 아니며 특히 초보 웹 개발자들에게는 매우 곤욕스러운 일이 아닐 수 없습니다. 그렇다면 반드시 Ajax 스타일의 웹 응용 프로그램은 브라우저 독립적이어야 하는 것일까요?

물론 그렇게 할 필요는 없습니다. 그러나 Ajax를 구성하는 요소들이 모두 인터넷 표준을 따르고 있으므로 (사실 XMLHttpRequest는 표준은 아닙니다만) 가급적 브라우저에 독립적인 웹 페이지를 구현하는 것이 보다 Ajax 스러운 웹 응용 프로그램이라는 것이지요.

어쨌든 쉬운 일만은 아니니 우리 웹 개발자들은 Ajax 덕분에 또 한 가지 시련을 겪게 되었습니다. 모쪼록 마이크로소프트와 모질라 재단이 W3C의 표준을 적극적으로 준수해 주기를 바랄 뿐이지요.

2. 늘어나는 코딩량

서버와 클라이언트 사이에 전달되는 데이터와 트래픽은 감소할 지언정 우리가 작성해야 하는 코드는 획기적으로 늘어날 수 있다는 안타까운 현실이 우리를 기다리고 있습니다. 언뜻 이해가 안가시지요?

만일 여러분이 <TABLE>태그를 페이지에 표시해야 한다고 가정해 보겠습니다. 기존의 방법이라면 그저 서버 측 페이지에서 <TABLE>태그를 작성하기만 해주면 끝이었습니다. 그러나 Ajax를 채택하게 되면 이야기는 달라집니다. 서버에서 전달되는 것은 <TABLE>태그를 작성하는데 필요한 데이터 뿐입니다. 나머지는 자바 스크립트를 통해 제어해야 한다는 것이지요.

<table border="0" cellpadding="0">

    <tr>

        <td>Hello, World!</td>

    </tr>

</table>

이 코드를 만들기 위해 우리가 작성해야 하는 자바 스크립트 코드는 다음과 같습니다.

function buildTable() {
    var objTable = document.createElement("table");

    objTable.border = 0;

    objTable.cellpadding = 0;

    var objTr = objTable.insertRow(0);

    var objTd = objTr.insertCell(0);

    objTd.innerText = "Hello, World";

    document.body.appendChild(objTable);

}

이게 끝일까요? 아니지요. 위의 코드가 잘 동작하는지 테스트와 디버깅을 해야합니다. 작업이 몇 배로 늘어날 수도 있다는 것, 미리 알아두셔야 하지 않을까요?

3. 디버깅, 완전 대박이다

그렇습니다. Ajax 스타일을 채택하면 디버깅, 완전 대박입니다. 기존에는 라운드 트립 과정에서 서버 코드에 오류가 발생한 경우 브라우저 상에 오류 내용이 표시되었습니다. ASP.NET의 경우 강력한 디버깅 기능과 추적 기능으로 정말 한 눈에 알아볼 수 있을 정도로 상세한 정보가 출력됩니다.

그런데 Ajax를 채택하면 이러한 디버깅 정보는 더 이상 볼 수가 없습니다. 왜냐하면 그 오류 데이터는 XMLHttpRequest 덕분에 백그라운드로 숨겨지기 때문이지요. 물론 다른 여러 가지 방법을 통해 디버깅을 할 수는 있습니다. 그.러.나 여러분은 지금까지 알고 있던 디버깅 방법을 버리고 새로운 디버깅 방법을 배우고 경험해야 합니다. 산너머 산이네요.

(다행히 이러한 작업들은 Ajax.NET이나 Atlas 등의 Ajax 프레임워크를 이용할 경우 어느 정도 도움을 받을 수 있습니다. 그러나 분명 우리가 지금까지 해오던 방법과는 많은 면에서 다를 수 있다는 것도 사실입니다.)

4. 새롭게 대두되는 보안 문제

Ajax를 사용하게 되면 보안에 구멍이 뚫릴 우려가 상당히 높습니다. 왜냐하면 Ajax는 일단 자바스크립트에 의해 제어가 되며, 자바 스크립트는 js파일만 다운로드하면 간단히 열어볼 수 있기 때문입니다. (그래서인지 자바스크립트를 읽기 어렵도록 난독처리해 주는 웹 사이트도 있더군요. ㅡㅡ;;)

자바스크립트 파일이 노출되면 우리가 개발한 웹 응용 프로그램이 어떤 패턴으로 서버와 데이터를 주고받는지 적나라하게 공개되는 것입니다. 완전 해커들 앞에서 벌거벗고 춤추는 것과 다름이 없지요.

다행히 Ajax는 SSL로 보호를 할 수도 있습니다만 그렇다고 모든 페이지에 SSL 보안을 걸기도 우습거니와 다양한 암호화 기술을 적절히 활용하고 중요한 데이터나 정보는 가급적 서버 쪽에서 처리할 수 있도록 하는 것이 최선의 대책이 아닐까 생각됩니다.

이 외에도 몇 가지 단점들이 존재하지만 대부분 소소한 것들이므로 일단은 패스 하도록 하겠습니다. 사실 제가 여기서 장점과 단점을 늘어놓아봤자 여러분이 Ajax를 이용하여 웹 페이지를 개발하면서 느끼는 것에 비하면 아무것도 아닐테니까요.


Ajax - 선택과 활용은 여러분의 판단에 좌우됩니다.

지금까지 Ajax란 무엇이고 어떤 장점을 가지는지, 또 어떤 단점을 가지는지 살펴보았습니다. 저로서는 솔직히 Ajax의 단점들을 경험한 후로 Ajax를 정말 사용해야 하는 것인지 한때 의심하기도 했습니다.

그러나 모든 도구들이 그러하듯이 언제, 어떻게, 누가, 왜 사용하느냐에 따라 그 결과는 천차만별로 달라질 수 있다는 것을 굳이 제가 말씀드리지 않아도 충분히 아실 것입니다. 다만 무분별한 사용보다는 반드시 필요한 부분에 꼭 필요한 만큼만 사용한다면 아마도 웹 응용 프로그램은 지금보다 훨씬 나은 모습을 갖출 수 있을 것입니다.

Ajax가 새로운 웹 응용 프로그램의 초석이 되느냐 아니면 말도많고 탈도많은 천덕꾸러기 신세가 되느냐는 바로 우리들, 웹 개발자의 손에 달려있다는 점을 명심해야 하겠습니다.

written by webgenie
www.bullog.net
Microsoft ASP/ASP.NET MVP

 VS.NET 을 시행하다보면 종종 HTML Tag나 Script 때문에 디자인 부분으로 넘어 갈 수 없는 경우가 있다.(경고가 먼저 나오기때문에 알 수 있다.) 그런 경우에는 해당 Tag&Script 의 ' 였던 부분을  " 로 " 였던 부분은 ' 로 바꾸면 디자인 부분을 보 수 있으며 실행에도 크게 문제가 되지않는다. (본인의 경험이므로 100%신뢰 불가능...)

ex)

<!--<a href="#" ="send('<%#DataBinder.Eval(Container.DataItem,"VERIFY_TYPE")%>','<%#DataBinder.Eval(Container.DataItem,"CHECK_RANGE")%>','<%#DataBinder.Eval(Container.DataItem,"ITEM_CD")%>:<%#DataBinder.Eval(Container.DataItem,"WORK_SEQ")%>');"><%#DataBinder.Eval(Container.DataItem,"CHECK_METHOD")%></a>-->

<!--<a href="#" ='send("<%#DataBinder.Eval(Container.DataItem,"VERIFY_TYPE")%>","<%#DataBinder.Eval(Container.DataItem,"CHECK_RANGE")%>","<%#DataBinder.Eval(Container.DataItem,"ITEM_CD")%>:<%#DataBinder.Eval(Container.DataItem,"WORK_SEQ")%>");'><%#DataBinder.Eval(Container.DataItem,"CHECK_METHOD")%></a>-->

<%#DataBinder.Eval(Container.DataItem,"CHECK_RANGE")%><%#DataBinder.Eval(Container.DataItem,"ITEM_CD")%><%#DataBinder.Eval(Container.DataItem,"WORK_SEQ")%>

작성자: Joydip Kanjilal (누굴까? ㅡㅡ;;)
번역 작성일: 2006년 12월 27일
역자: 웹지니™
원문 보기: http://www.aspaliance.com

독자 여러분의 편의를 위해 원문은 삭제하고 번역문만 기재합니다. 원문이 궁금하신 분은 상단의 [원문 보기] 링크를 클릭해 주세요.
커넥션 풀링은 데이터베이스 액세스 성능을 크게 향상시킵니다. 이 기사에서는 커넥션 풀링이 무엇인지, 어떻게 데이터베이스 액세스 성능을 향상시키는지 그리고 .NET 환경에서 어떻게 커넥션 풀을 생성하고 커넥션 객체를 추가하거나 제거하는지 설명합니다.


Introduction
데이터베이스 연결은 상당히 리소스 집약적이며 상대적으로 느린 작업입니다. 하지만 매우 중요한 일이지요. 커넥션 풀이란 이미 열려져 있으며 재활용 가능한 커넥션 객체들의 컨테이너 입니다. 커넥션 풀은 마지막 커넥션 객체가 닫힐 때 메모리에서 해제됩니다. 커넥션 풀링을 이용할 때의 가장 기본적인 이점은 성능의 향상과 확장성이며 가장 중요한 단점은 실제로 사용되지 않는 커넥션이 열린 상태로 보관된다는 점입니다.
.NET의 데이터 프로바이더들은 기본적으로 커넥션 풀링이 활성화되어 있습니다. 만일 커넥션 풀링을 비활성화 하려면 연결 문자열에 Pooling=false라고 명시적으로 지정해야 합니다. 커넥션 풀링은 매번 데이터베이스 연결이 필요할 때마다 커넥션 객체를 생성하는 대신 이미 만들어져 있고 연결된 상태로 재활용할 수 있는 커넥션 객체를 제공합니다.
커넥션 객체가 닫히거나 메모리에서 해제될 때 이 커넥션 객체는 커넥션 풀로 되돌아가 다시 데이터베이스 연결이 필요해 질 때까지 대기하게 됩니다. 우리가 커넥션 풀링을 효과적으로 사용한다면 데이터베이스 액세스 작업에 필요한 리소스는 비교적 줄어들게 됩니다. 이 기사에서는 커넥션 풀링이 대체 무엇인지, 그리고 응용 프로그램의 성능과 확장성을 향상시키기 위해 커넥션 풀링을 어떻게 효율적으로 활용할 것인지를 설명합니다.


How does Connection Pooling work?
사실 커넥션 풀은 이미 열려져 있고 재사용 가능한 연결들을 보관하는 일종의 컨테이너입니다. 동시에 동일한 응용 프로그램 도메인 내에 여러 개의 풀이 존재할 수 있지만 커넥션 풀은 서로 다른 응용 프로그램 도메인 사이에서 공유될 수는 없습니다. 중요한 것은 하나의 연결 문자열을 위한 하나의 커넥션 풀이 생성된다는 점입니다. (역자 주: 즉, 서로 다른 연결 문자열 2개를 사용하는 응용 프로그램에서는 두 개의 커넥션 풀이 생성되게 됩니다. 연결 문자열이 단 한글자만 틀려도 커넥션 풀은 서로 다른 연결 문자열로 인식한다는 것에 주의해야 합니다.)
커넥션 풀은 어떤 연결 문자열을 이용해서 데이터베이스 액세스가 처음 시도될 때 생성됩니다. 또한 다른 연결 문자열을 이용해서 데이터베이스에 액세스하려는 요청이 들어오면 이 때는 또 다른 커넥션 풀이 생성됩니다. 그래서 우리는 데이터베이스 당 하나의 커넥션 풀이 아니라 연결 문자열 하나 당 하나의 커넥션 풀을 갖게 되는 것입니다. 다음 예제는 이러한 상황을 재현해 줍니다.

Listing 1

//연결 풀이 생성됩니다.
SqlConnection sqlConnection = new SqlConnection();
sqlConnection.ConnectionString = "Server=localhost;Database=test;User ID=joydip;Password=joydip;Trusted_Connection=False";
sqlConnection.Open();     

Listing 2
//연결 문자열이 다르기 때문에 또 다른 커넥션 풀이 생성됩니다.
SqlConnection conn = new SqlConnection();
sqlConnection.ConnectionString =
"Server=localhost;Database=test;User ID=test;Password=test;Trusted_Connection=False";
sqlConnection.Open();  

Listing 3
// 연결 문자열이 Listing 1에서 사용된 것과 같기 때문에 새로운 커넥션 풀이생성되지 않습니다..
SqlConnection conn = new SqlConnection();
sqlConnection.ConnectionString =
"Server=localhost;Database=test;User ID=joydip;Password=joydip;Trusted_Connection=False";
sqlConnection.Open();   
 

새로운 커넥션에 대한 요청이 들어오면 새로운 커넥션을 생성하지 않고 커넥션 풀에 보관되어 있던 재사용 가능한 커넥션 객체가 사용됩니다. 이 방법은 여러분의 응용 프로그램 성능과 확장성을 향상 시킵니다. 응용 프로그램이 커넥션을 닫으면 커넥션 객체는 커넥션 풀로 되돌아가 재연결 제한 시간이 지날 때까지 대기합니다. 연결 제한 시간이란 커넥션 객체가 동일한 연결 문자열로 동일한 데이터베이스에 다시 액세스할 필요가 있을 때까지 대기하는 시간입니다. 이 제한 시간 내에 새로운 요청이 들어오지 않으면 데이터베이스에 대한 연결은 닫히고 커넥션 객체는 커넥션 풀에서 제거됩니다.
새로운 커넥션 풀이 생성되면 커넥션 객체는 커넥션 풀에 보관되고 커넥션 풀과 커넥션 객체는 언제든지 사용할 수 있는 상태가 됩니다. 커넥션 풀은 연결 문자열에 지정된 최대 개수만큼의 커넥션 객체를 보관하고 있습니다. 커넥션 객체들은 비활성화된 상태로 장시간 커넥션 풀에 보관되거나 지정된 시간이 지나거나 또는 실제로 데이터베이스 연결이 가능하지 못한 상태가 될 때까지 커넥션 풀에 보관됩니다.
커넥션 풀은 내부적으로 커넥션 풀 관리자에 의해 관리됩니다. 지속적인 연결 요청이 들어오면 커넥션 풀 관리자는 커넥션 풀에서 사용 가능한 커넥션 객체를 찾아 응용 프로그램에 리턴합니다. 다음의 사항들은 커넥션 풀 관리자가 어떻게 동작하는지를 보여주며 새로운 커넥션 객체에 대한 요청이 들어왔을 때 동작을 시작합니다.
사용되지 않는 커넥션 객체가 커넥션 풀에 존재하면 이 커넥션 객체를 리턴합니다. 모든 커넥션 객체가 사용 중이면 새로운 커넥션 객체를 생성하고 커넥션 풀에 추가합니다. 커넥션 객체의 수가 커넥션 풀의 최대 객체 수에 도달하면 사용 가능한 커넥션 객체가 커넥션 풀로 되돌아올 때까지 요청이 대기하게 됩니다.

커넥션 풀을 제어하는데 필요한 연결 문자열의 매개 변수들은 아래와 같습니다.

Connection Timeout
MinPoolSize
MaxPoolSize
Pooling

커넥션 풀링을 보다 효과적으로 사용하기 위해서는 사용이 끝난 커넥션 객체의 Close 메서드를 반드시 호출해서 커넥션 객체가 커넥션 풀로 돌아갈 수 있도록 해야 합니다.


Improving Connection Pooling Performance
우리는 늘 최대한 늦게 커넥션을 열고 최대한 빨리 커넥션을 닫아야 합니다. 즉, 사용이 끝난 즉시 커넥션을 닫아야 하는 것이지요. 커넥션 객체는 실제로 사용되는 동안에만 열려있어야 합니다. 커넥션 객체가 오래도록 열려 있어서 커넥션 풀 내의 사용 가능한 커넥션 객체의 수를 줄이고 그에 따라 커넥션 풀의 성능에 영향을 미쳐서는 안됩니다. 커넥션 객체는 사용이 끝난 즉시 해제되어야 합니다. 이는 커넥션 객체가 재빨리 커넥션 풀로 되돌아가 재사용 가능한 상태로 만들어 줍니다. 아래 예제는 응용 프로그램 내에서 커넥션 객체를 효율적으로 열고 닫는 방법을 보여줍니다.


Listing 4
SqlConnection sqlConnection = new SqlConnection(connectionString);
try
{
  sqlConnection.Open();
  //실행될 코드
}
finally
{
  sqlConnection.Close();
}
Listing 4의 코드는 아래와 같이 "using" 키워드로 바꿔 쓸 수 있습니다.


Listing 5
using(SqlConnection sqlConnection = new SqlConnection(connectionString))
{
  sqlConnection.Open();
  //실행될 코드
}
Listing 5에서 사용된 using 키워드는 컴파일 시 try ~ finally 구문으로 변환된다는 것을 기억할 필요가 있습니다. 아래는 커넥션 풀링을 보다 효율적으로 활용하기 위한 방법입니다.

데이터베이스 연결은 항상 필요할 때 열고 사용이 끝나면 곧바로 닫아줍니다. 커넥션 객체를 닫기 전에 사용자 정의 트랜잭션을 항상 먼저 닫아줍니다. 최소한 하나 이상의 열려진 커넥션 객체가 커넥션 풀에 있도록 합니다.
연결 문자열에서 Integrated Security 특성을 이용하는 경우 커넥션 풀리의 사용을 피합니다. 커넥션 풀의 상태는 아래와 같은 방법으로 모니터링 할 수 있습니다.

sp_who 또는 sp_who2 저장 프로시저를 실행합니다. SQL Server Profiler를 사용합니다. 성능 모니터와 성능 카운터를 사용합니다.


References
- Tuning Up ADO.NET Connection Pooling in ASP.NET Applications
- Connection Pooling for the .NET Framework Data Provider for SQL Server
- The .NET Connection Pool Lifeguard
- ADO.NET Connection Pooling Explained
 

Conclusion
커넥션 객체의 컨테이너인 커넥션 풀은 활성화 되어 있거나 열려진 커넥션 객체가 존재하는 한 지속적으로 존재합니다. 새로운 연결 요청이 연결 문자열과 함께 들어오면 그에 따른 새로운 커넥션 풀이 생성됩니다. 우리는 응용 프로그램이 동일한 연결 문자열을 사용하도록 하여 응용 프로그램의 성능과 확장성을 향상시킬 수 있습니다. 그러나 우리는 커넥션 풀링을 적절히 사용하여야 하며 그렇지 못하면 응용 프로그램의 전반적인 성능에 악영향을 미칠 수 있습니다.
MSDN에는 "커넥션 풀링은 응용 프로그램의 성능을 향상시킬 수 있는 매우 강력한 기능이지만 효율적으로 관리하지 못하면 응용 프로그램에 악영향을 미칠 수 있다"라고 표기되어 있습니다.
이 기사를 통해 커넥션 풀링과 응용 프로그램 성능 향상을 위해 이를 어떻게 효율적으로 활용할 것인지를 알게 되었습니다.

브라우저는 사용자 시스템상에 쿠키들을 관리할 책임이 있습니다. 쿠키들은 HttpResponse 객체를
통해서 브라우저에 보냅니다. Page 클래스의 Response 프로퍼티 처럼 HttpResponse 객체를 접근할 수 있습니다. 브라웢에 보내기를 원하는 어떤 쿠키들도 collection 에 추가될 겁니다. 쿠키를 생성할 때, 쿠키의 명과 값을 명시해야합니다. 브라우저가 서버에서 request 할 때 , 서버는 request 와 함께 쿠키들을 보냅니다. asp.net 어플리케이션에서 HttpRequest 객체를 이용하여 쿠키들을 읽을 수 있습니다. 마치 page 클래스의 request 프로퍼티 처럼 가능합니다. 하나의 text box 를 추가하고 2개의 버튼들과 하나의 label 을 웹페이지에 추가했습니다. textbox 은 쿠키정보를 inputting 하기 위한 용도입니다. 추가 버튼을 누름으로 인해 샘플 어플리케이션은 새로운 쿠키를 생성할 겁니다. View 버튼을 클릭하면 우리는 생성된 쿠키를 확인 하실 수 있습니다. 쿠키 만기일은날짜는 2006-10-1로 셋팅 했습니다.

protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{

Response.Cookies["MyCookie"]["Data"] = TextBox1.Text;
Response.Cookies["MyCookie"]["Time"] = DateTime.Now.ToString("G");
Response.Cookies["MyCookie"].Expires=DateTime.Now.AddMonths(1);

Label1.Text = "Cookie created!<p>" + "Your cookie contains:<font color=red>" + Request.Cookies["MyCookie"]["Data"] + "<br>" + Request.Cookies["MyCookie"]["Time"] + "</font>";

Response.Cookie("MyCookie").Expires=DateTime.FromString("2006-10-1");

}
protected void Button2_Click(object sender, EventArgs e)
{
if (Request.Cookies["MyCookie"] == null)
Label1.Text = "There is no cookie:";
else
Label1.Text = "Your cookie contains:" + "<font color=red>" + Request.Cookies["MyCookie"]["Data"] + "<br>" + Request.Cookies["MyCookie"]["Time"] + "</font>";

}

aspx 페이지 입니다.

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>

<body>
<form id="form1" runat="server">
<div>
<fieldset>
<legend>rdfdf</legend>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Add" Width="70px" />
<asp:Button ID="Button2" runat="server" Text="View" Width="84px" />
<br />
<br />
<asp:Label ID="Label1" runat="server" Text="" Width="138px"></asp:Label>
</fieldset>
</div>
</form>
</body>
</html>

전체적인 code behind 는 아래와 같습니다.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{

protected void Page_Load(object sender, EventArgs e)
{

}

protected void Button1_Click(object sender, EventArgs e)
{
Response.Cookies["MyCookie"]["Data"] = TextBox1.Text;
Response.Cookies["MyCookie"]["Time"] = DateTime.Now.ToString("G");
Response.Cookies["MyCookie"].Expires=DateTime.Now.AddMonths(1);
Label1.Text = "Cookie created!<p>" + "Your cookie contains:<font color=red>" + Request.Cookies["MyCookie"]["Data"] + "<br>" + Request.Cookies["MyCookie"]["Time"] + "</font>";
Response.Cookie("MyCookie").Expires=DateTime.FromString("2006-10-1");
}
protected void Button2_Click(object sender, EventArgs e)
{
if (Request.Cookies["MyCookie"] == null)
Label1.Text = "There is no cookie:";
else
Label1.Text = "Your cookie contains:" + "<font color=red>" + Request.Cookies["MyCookie"]["Data"] + "<br>" + Request.Cookies["MyCookie"]["Time"] + "</font>";

}
}

감사합니다.
==================================
카페 : http://cafe.daum.net/aspdotnet
작성자 : 심재운
메일 : shimpark@gmail.com
==================================

 * 문자열 검사를 할 때 ==과 Equals메서드 중 누가 더 빠를까요?..

* 저번에 본 봐와 같이 ==(IL : op_Equality)에는 12개의 메서드가 사용되지만

* Equals 매서드는 2 가지만 사용되더군요.

* 따라서 문자열 비교할 때는 Equals메서드를 사용해 비교하세요.


using System;


namespace EqualsVs__

{

  /// <summary>

   /// Class1에 대한 요약 설명입니다.

   /// </summary>

   class Class1

   {

       /// <summary>

       /// 해당 응용 프로그램의 주 진입점입니다.

       /// </summary>

       [STAThread]

       static void Main(string[] args)

       {

           string strCompared = "문자열";


           //IL_000c:  call       bool [mscorlib]System.String::op_Equality(string, string)

           //사용 메서드 수 : 12개

           //시간 : 7453.4

           if (strCompared == "문자열")

               Console.WriteLine("True");


           // IL_0023:  callvirt   instance bool [mscorlib]System.String::Equals(string)

           //사용 메서드 수 : 2개

           //시간 : 37.9

          if (strCompared.Equals("문자열"))

               Console.WriteLine("True");

       }

   }

}

덧붙여서.. int,double... 의 실수와 연관있는형은 ==가 훨빠릅니다. 단 스트링비교는 반드시 equal 로 하시는 습관을 들이십시요. 얼마안된다 안된다 생각하실수도 있겠지만.. 저거 하나가 여러게 모이면 확연히 표가 납니다...

- 출처 :  KNUG (한국 닷넷 사용자 모임; Korea .NET User Group)
- 출처 2 : http://cafe.daum.net/aspdotnet

* 문자열이 있는지 검사할 때 흔히 if (문자열개체 != "")나
* if (문자열개체 != Stirng.Empty)를  쓰는데 이럴 경우 불필요한 오버헤드가 생기지만,
* Length 속성은 개체가 생성될때 설정되므로
* if (문자열개체.Length != 0 )로 해서 값만 비교해서 보다 빠르게 검사할 수 있습니다.

using System;

namespace StringEmptyVSStringLength
{
  /// <summary>
   /// Class1에 대한 요약 설명입니다.
   /// </summary>
   class Class1
   {
       /// <summary>
       /// 해당 응용 프로그램의 주 진입점입니다.
       /// </summary>
       [STAThread]
       static void Main(string[] args)
       {
          string notEmptyString = "값이 있는 문자열";

           // IL_000c:  call       bool [mscorlib]System.String::op_Inequality(string, string)
          if (notEmptyString != String.Empty)
           {
           }

          //IL_0014:  callvirt   instance int32 [mscorlib]System.String::get_Length()
           if (notEmptyString.Length != 0)
           {
           }
       }
   }
}

IL 코드로는 1가지 명령어지만

"if (notEmptyString != String.Empty)"에서는 12가지 내부 개체의 메서드를 사용해 비교하려는 양쪽의 문자열을 정렬하고 서로 일일히 비교하지만, i"f (notEmptyString.Length != 0)"에서는 단순이 변수에 값이 0이냐만 비교하기 때문에 속도가 빠를수 밖에 없죠.

실행해 시간을 검사하면 아래와 같은 차이를 보입니다. 단위는 (Microseconds)
             
742.4          if (notEmptyString != String.Empty)
0.7             if (notEmptyString.Length != 0)


- 출처 :   KNUG (한국 닷넷 사용자 모임; Korea .NET User Group)
- 출처 2 : http://cafe.daum.net/aspdotnet

스레드 사용

Greg Ewing
Clarity Consulting Inc.

요약: 기사에서는 스레딩의 다른 모델(단일, 아파트 자유) 모델의 사용에 대해 설명합니다. 스레드를 이용하는 응용 프로그램을 작성하는 도움을 있도록 스레드를 사용하는 C# 코드 샘플도 소개합니다. 또한 다중 스레딩 코드에 포함된 중요한 문제에 대해서도 설명합니다(9페이지/인쇄 페이지 기준).

목차

소개
스레딩에 대한 배경 지식
예제 응용 프로그램
다중 스레드 코드의 문제
결론

소개

다중 스레드 MSMQ(Microsoft Message Queuing) 트리거 응용 프로그램을 작성하는 일은 일반적으로 까다로운 작업이었습니다. 그러나 .NET Framework 스레딩 메시징 클래스의 도입으로 어느 때보다 쉬워졌습니다. 클래스를 사용하면 .NET Framework 대상으로 하는 모든 언어로 다중 스레드 응용 프로그램을 작성할 있습니다. 이전에 Microsoft Visual Basic 같은 도구는 스레딩에 대한 지원이 매우 제한되어 있었습니다. 따라서 C++ 사용하여 다중 스레드 코드를 작성하거나 Visual Basic에서 여러 프로세스나 ActiveX DLL 구성되는 이상적이지 않은 솔루션을 작성하거나 또는 다중 스레딩을 완전히 무시하는 밖에 없었습니다. .NET Framework에서는 어떤 언어를 사용하는지에 관계없이 풍부한 다중 스레드 응용 프로그램을 작성할 있습니다.

기사에서는 Microsoft 메시지 대기열의 메시지를 수신하고 처리하는 다중 스레드 응용 프로그램을 작성하는 프로세스를 단계적으로 소개하며, 특히 System.Threading System.Messaging이라는 가지 네임스페이스에 초점을 둡니다. 샘플 코드는 C#으로 작성되어 있지만 원하는 다른 언어로 쉽게 변환할 있습니다.

스레딩에 대한 배경 지식

Win32 환경에서 스레딩의 기본 모델은 단일, 아파트 자유 가지입니다.

단일 스레딩

처음에 작성한 응용 프로그램은 아마 응용 프로그램의 프로세스에 해당하는 스레드만 포함된 단일 스레드였을 것입니다. 프로세스는 해당 응용 프로그램의 메모리 공간을 차지하는 응용 프로그램의 인스턴스로 정의할 있습니다. 대부분의 Windows 응용 프로그램은 단일 스레드에서 모든 작업을 수행하는 단일 스레드 응용 프로그램입니다.

아파트 스레딩

아파트 스레딩은 단일 스레드보다 복잡한 스레딩 모델입니다. 아파트 스레딩으로 표시된 코드는 자체의 아파트로 제한된 고유 스레드에서 실행될 있습니다. 스레드는 처리 시간 동안 일어날 프로세스에서 소유하는 엔터티로 정의할 있습니다. 아파트 스레딩 모델에서 모든 스레드는 기본 응용 프로그램의 메모리에서 각각의 하위 섹션 내에서만 작동합니다. 모델에서는 코드의 여러 인스턴스를 동시에 그리고 독립적으로 실행할 있습니다. 예를 들어 .NET 이전의 Visual Basic에서는 아파트 스레드 구성 요소와 응용 프로그램을 만드는 것으로 제한되어 있었습니다.

자유 스레딩

자유 스레딩은 가장 복잡한 스레딩 모델입니다. 자유 스레딩 모델에서는 동시에 여러 스레드가 같은 메서드와 구성 요소로 호출됩니다. 아파트 스레딩과 달리 자유 스레딩은 분리된 메모리 공간에 제한되지 않습니다. 예를 들어 응용 프로그램에서 매우 비슷하지만 독립적인 수학 계산을 대량으로 실행해야 하는 경우에 자유 스레드 개체를 사용할 있습니다. 경우 같은 코드 인스턴스를 사용하여 계산을 실행하는 여러 스레드를 만듭니다. Visual Basic 6.0 같은 언어에서는 이와 같은 작업이 거의 불가능하므로 자유 스레드 응용 프로그램을 작성한 경험이 있는 응용 프로그램 개발자는 아마 C++ 개발자뿐일 것입니다.

스레딩 모델 작업

스레딩 모델에 대한 개념의 이해를 돕는 예로 집에서 다른 집으로 이사하는 일을 있습니다. 단일 스레드 방법은 포장에서 상자 운반과 풀기까지의 모든 일을 직접하는 것이라고 있습니다. 아파트 스레딩 모델로 작업하는 경우는 절친한 친구 몇에게 도움을 청하는 것과 같습니다. 친구는 각기 다른 방에서 일하고 다른 방에서 일하는 사람을 도울 없습니다. 그들은 각자의 공간과 이삿짐을 맡습니다. 자유 스레드 방법을 선택하는 경우, 친구들에게 도움을 요청하는 것은 아파트 스레딩 모델과 동일하지만 친구들이 모두 어느 시간이나 어느 방에서든 함께 이삿짐을 꾸릴 있다는 점이 다릅니다. 비유에서 집은 모든 스레드가 작동하는 프로세스이고 친구는 코드의 인스턴스이며 이삿짐은 응용 프로그램의 리소스와 변수입니다.

위의 예에서는 모델의 장점과 단점을 보여 줍니다. 아파트 스레딩은 구성 요소의 여러 인스턴스가 작동하므로 단일 스레딩보다 빠릅니다. 자유 스레딩에서는 모든 일이 동시에 일어나고 모든 리소스가 공유되므로 어떤 경우에는 아파트 스레딩보다 빠르고 훨씬 효율적입니다. 그러나 여러 스레드에서 공유 리소스를 변경하는 경우 문제가 일어날 있습니다. 사람이 상자를 사용해 부엌 물건을 다음 다른 친구가 와서 같은 상자에 침실 물건을 포장하는 경우를 생각해 보십시오. 번째 친구는 상자에 '부엌'이라는 레이블을 붙였는데 친구가 위에 '침실'이라는 레이블을 붙입니다. 결국 짐을 때는 부엌 물건을 침실에서 풀게 것입니다.

예제 응용 프로그램

단계로 예제 응용 프로그램의 디자인을 검토합니다. 응용 프로그램에서는 여러 스레드를 만들고 스레드는 MSMQ 대기열의 메시지를 수신합니다. 예제에서는 기본 Form 클래스와 사용자 지정 MQListen 클래스의 가지 클래스를 사용합니다. Form 클래스는 사용자 인터페이스를 처리하는 것과 아울러 작업자 스레드를 만들고 관리하고 소멸시킵니다. MQListen 클래스에는 메시지 대기열 항목을 비롯해 작업자 스레드를 실행하는 필요한 모든 코드가 포함됩니다.

다중 스레드 코드의 문제

샘플 코드 작업을 완료했으므로, 이제 다중 스레드 응용 프로그램을 작성하는 필요한 도구를 가지게 되었습니다. 스레딩은 응용 프로그램의 성능과 확장성을 극적으로 개선할 있습니다. 이런 강력함과 더불어 스레딩의 위험에 대해서도 알고 있어야 합니다. 어떤 경우에는 스레드 사용으로 응용 프로그램에 해를 끼칠 있습니다. 스레드로 인해 작업이 다운되거나 예상치 못한 결과가 일어날 있으며 심지어 응용 프로그램이 응답을 중지할 수도 있습니다.

스레드가 여러 개인 경우 스레드 서로가 특정 지점에 도달하거나 종료할 때까지 대기하고 있지 않은지 확인합니다. 제대로 수행하지 않으면 스레드가 서로 대기하고 있으므로 아무 스레드도 종료되지 않는 교착 상태를 초래할 있습니다.

여러 스레드에서 쉽게 공유될 없는 리소스(: 플로피 디스크 드라이브, 직렬 포트 또는 적외선 포트) 액세스해야 하는 경우 스레드 사용을 방지하거나 synclock 또는 mutex 같은 고급 스레딩 도구를 사용하여 동시성을 관리할 있습니다. 스레드가 리소스 하나를 동시에 액세스하려 하면 스레드에서는 리소스를 얻을 없고 데이터 손상이 일어납니다.

스레딩의 다른 일반적인 문제는 경쟁 조건입니다. 스레드가 파일에 데이터를 쓰는 동안 다른 스레드에서 해당 파일을 읽고 있는 경우 어떤 스레드가 먼저 종료할지 없습니다. 문제는 스레드가 파일경쟁 조건이라고 합니다. 읽는 스레드가 쓰는 스레드보다 앞서는 경우 없는 결과가 반환됩니다.

스레드를 사용할 모든 스레드가 다른 스레드와 별도로 완전히 작업을 마칠 있을지 여부도 생각해 보아야 합니다. 데이터를 앞뒤로 전달해야 하는 경우 데이터가 비교적 간단해야 합니다. 복잡한 개체를 전달하는 경우 개체를 앞뒤로 이동하기 위해 막대한 마샬링 비용이 들어가기 시작합니다. 이에 따라 운영 체제에서 관리하는 오버헤드가 생기고 전체 성능이 떨어집니다.

다른 문제로는 코드를 다른 개발자에게 넘겨주는 따른 전환 비용이 있습니다. .NET으로 스레딩이 훨씬 쉬워졌지만 코드를 유지 관리하는 다음 개발자가 스레딩 작업을 하기 위해서는 스레딩에 대해 알고 있어야 합니다. 그러나 점은 스레드 사용을 피해야 이유라기 보다는 적절한 코드 주석을 제공해야 이유입니다.

이런 문제들로 인해 스레딩 자체를 사용하지 않는 보다는 응용 프로그램을 디자인하고 스레드를 사용할지 여부를 결정할 모든 문제들을 기억하고 있는 것이 좋습니다. 불행히도 백서에서는 이런 문제를 방지하기 위한 방법을 설명하지 않습니다. 스레드를 사용하기로 했으나 위에서 언급한 문제가 발생한 경우 synclock이나 mutex 검토하여 문제를 해결하거나 다른 솔루션을 찾아 보십시오.

결론

여기에 있는 내용으로 스레딩을 이용하는 응용그러나 이렇게 하는 동안 관련된 문제를 기억하십시오. 스레딩은 제대로 사용하면 응용 프로그램의 성능과 확장성을 단일 스레드 응용 프로그램에 비해 훨씬 개선할 있지만, 올바로 사용하지 못하는 경우 정반대의 결과를 가져올 있으며 응용 프로그램이 불안정하게 있습니다.

출처: http://blog.naver.com/ansysda?Redirect=Log&logNo=19257436

이럴 때 :  신규 파일의 등록시 같은 이름의 파일에 대해, 파일 이력을 남기기 위해 이름만 수정해서 같은 폴더 內 존재해야 한다.

FileNameEditer 메소드가 있는 걸로 알고 있지만.......잘 모르니까.....

File.Move( OrgFilePath, NewFilePath )를 사용
OrgFilePath   = 이동해야 할 파일의 경로와 파일명
NewFilePath  = OrgFilePath를 옮길 경로

( NewFilePath 같은 경로를 쓰고 파일 이름이 변경 된 값을 준다면!  )

public static string[] GetLogicalDrives()

1. namespace : System
2. 반환 값 : 각 요소에 논리 드라이브의 이름이 들어 있는 문자열의 배열. 예를 들어 컴퓨터의 하드 드라이브가 첫 번째 논리 드라이브일 경우, 반환되는 첫 번째 요소는 "C:\"
3. 예외
- IOExceptionI/O :     오류가 발생하는 경우
- SecurityException : 호출자에게 필요한 권한이 없는 경우

using System;

class Sample
{
  public static void Main()
  {
       Console.WriteLine();
       String[] drives = Environment.GetLogicalDrives();
       Console.WriteLine("GetLogicalDrives: {0}", String.Join(", ", drives));
  }
}

결과 : "GetLogicalDrives: A:\, C:\, D:\"
출처 : MSDN


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

public string ReturnDir()
{

string OutputPath = string.Empty;
string innerPath = string.Empty;
string[] sar  = Environment.GetLogicalDrives();


for( int i = 0; i < sar.Length; i++ )
{

string path = sar[i].ToString() + "examplePath";

dir = new DirectoryInfo( path );
       
if( !dir.Exists ) // == false
{

path = string.Empty;
dir = null;

}
else
{

innerPath = sar[i].ToString() + "examplePath";

dir = null;

}

}


OutputPath = innerPath

return OutputPath;

}

추가 NameSpace  
using System.Diagnostics;       [Process, ProcessStartInfo]
using System.Windows.Forms; [Application]

//Environment.SystemDirectory //system32폴더)

//Application.StartupPath  //프로그램이 실행되는 폴더

/// <summary>
/// 인터넷 정보서비스를 중지
/// </summary>
public void IIS_stop()
{

Process processCmd = new Process();
ProcessStartInfo processInfo = new ProcessStartInfo();
try
{

processInfo.FileName = "Iisreset";         //실행하려는 프로세스 이름
processInfo.Arguments = @" /stop";      //실행되는 프로세스의 인자값
processInfo.UseShellExecute = false;     //운영체제 셸의 사용여부
processInfo.CreateNoWindow = true;      //새창에서 실행 할 것인지 여부
processInfo.RedirectStandardInput = true;
processInfo.RedirectStandardError = false;
processInfo.RedirectStandardOutput = false;


processCmd.StartInfo = processInfo;

processCmd.Start();                              //프로세스의 시작
processCmd.WaitForExit();                     //프로세스가 종료 될 때 까지

                                                            무기한 대기한다.
processCmd.StandardInput.Flush();

}
catch( Win32Exception ex )
{

//Exception처리 :

Win32Exception에 해당되며, 상위 Exception으로 처리해도 된다.

}
finally
{

processCmd.Close(); //프로세스연결 종료

}

}


// 실행인자를 수집한다.

public void Example()

{

string commandLineArgs = "";
foreach(string arg in Environment.GetCommandLineArgs())
{

commandLineArgs += '"' + arg + '"' + " ";

}
commandLineArgs = commandLineArgs.Trim();

Process mainProcess = null;

try
{

ProcessStartInfo p = new ProcessStartInfo(this.executablePath);
p.WorkingDirectory = Path.GetDirectoryName(this.executablePath);
p.Arguments = commandLineArgs;
mainProcess = Process.Start(p);

}
catch(Exception e)
{
}


if(mainProcess != null)
{


try
{

mainProcess.WaitForExit(); // 실행시킨 프로세스가 종료될때까지 기다린다.

}
catch (Exception e)
{

return;

}

if (mainProcess.ExitCode == 2) // 아마도 종료코드가 0 인게 정상종료일거다....
{
}
else
{
}

}

Process p = new Process();
ProcessStartInfo pinfo = new ProcessStartInfo();


pinfo.FileName = "copy";
pinfo.Arguments = "test.txt test1.txt";


p.StartInfo = pinfo;
p.Start();


이렇게 실행을 하면 파일을 찾을 수 없다고 나옵니다.
첨에는 인자로 준 파일이 없나 했는데 실제로는 Process에서 실행하는 명령의 파일 이름은 실제 존재하는 exe 실행 파일을 의미 합니다.
제가 실행 하려고 했던 copy 명령은 실제로는 cmd.exe 파일의 내부 명령입니다.
그래서 파일을 찾을 수 없다고 하는 것입니다.
하여간 하다보니 이렇게 cmd 내장 명령을 실행 하려면 어떻게 해야 하는지도 궁금해 져서 이렇게 질문을 올립니다.


Process p = new Process();
ProcessStartInfo pinfo = new ProcessStartInfo();

p.StartInfo = pinfo;


pinfo.FileName = "cmd";

pinfo.UseShellExecute=false;

pinfo.CreateNoWindow=true;

pinfo.RedirectStandardInput=true;

pinfo.RedirectStandardError=false;

pinfo.RedirectStandardOutput=false;    


p.Start();

p.StandardInput.WriteLine(@"copy G:\Test\test.xls G:\Test\test2.xls");

p.StandardInput.Flush();


//화일이 있으면 덮어쓴다.

//  p.StandardInput.WriteLine(@"Y");

//  p.StandardInput.Flush();


p.Close(); 


저는 copy 명령을 직접 날리는 것으로 했는데,,,
아래와 같이 하니까 되네요
두가지 모두 잘 됩니다.
CMD 명령어의 옵션 값으로 해결을 했습니다.


pinfo.FileName = "cmd";

pinfo.Arguments = "/C copy c:\\code39.txt com1:";


출처 :데브피아

추가 정보
한 번에 하나씩 셀을 채우지 않고 여러 셀 범위를 채우려면 Range 개체의 Value 속성을 2차원 배열로 설정하면 됩니다. 마찬가지로 Value 속성을 사용하여 한 번에 여러 셀에 대한 2차원 배열 값을 가져올 수 있습니다. 다음 단계에서는 2차원 배열을 사용하여 데이터를 설정하고 검색하는 과정을 보여 줍니다.
Microsoft Excel용 자동화 클라이언트 빌드

1. Microsoft Visual Studio 2005 또는 Microsoft Visual Studio .NET를 시작합니다.

2. 파일 메뉴에서 새로 만들기를 누르고 프로젝트를 누릅니다. Visual C# 프로젝트 형식에서 Windows 응용 프로그램을 선택합니다. 기본적으로 Form1이 만들어집니다.

3. Visual Studio 2005의 경우 Microsoft Excel 11.0 Object Library에 대한 참조나, Visual Studio .NET의 경우 Microsoft Excel Object Library에 대한 참조를 추가합니다. 해당 참조를 추가하려면 다음과 같이 하십시오.

a.  프로젝트 메뉴에서 참조 추가를 누릅니다.
b.  COM 탭에서 Microsoft Excel Object Library를 찾아 선택을 누릅니다.

Visual Studio 2005의 경우 COM 탭에서 Microsoft Excel 11.0 Object Library를 찾습니다.

참고 Microsoft Office 2003에는 PIA(기본 Interop 어셈블리)가 포함되어 있습니다. Microsoft Office XP에는 PIA가 포함되어 있지 않지만 PIA를 다운로드할 수 있습니다. Office XP PIA에 대한 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
328912 (http://support.microsoft.com/kb/328912/) Microsoft Office XP PIA를 다운로드할 수 있다 
c.  참조 추가 대화 상자에서 확인을 눌러 선택한 내용을 적용합니다. 선택한 라이브러리에 대해 래퍼를 생성할 것인지 묻는 메시지가 나타나면 예를 누릅니다.

4. 보기 메뉴에서 도구 상자를 선택하여 도구 상자를 표시합니다. 단추 두 개와 확인란 하나를 Form1에 추가합니다.

5. 확인란의 이름 및 텍스트 속성을 FillWithStrings로 설정합니다.

6. Button1을 두 번 누릅니다. 해당 폼에 대한 코드 창이 나타납니다.

7. 코드 창에서


private void button1_Click(object sender, System.EventArgs e)
{
}
   
위의 코드를 아래와 같이 바꿉니다.      

//Declare these two variables globally so you can access them from both
//Button1 and Button2.
Excel.Application objApp;
Excel._Workbook objBook;

private void button1_Click(object sender, System.EventArgs e)
{

Excel.Workbooks objBooks;
Excel.Sheets objSheets;
Excel._Worksheet objSheet;
Excel.Range range;

try
{

// Instantiate Excel and start a new workbook.
objApp = new Excel.Application();
objBooks = objApp.Workbooks;
objBook = objBooks.Add( Missing.Value );
objSheets = objBook.Worksheets;
objSheet = (Excel._Worksheet)objSheets.get_Item(1);

//Get the range where the starting cell has the address
//m_sStartingCell and its dimensions are m_iNumRows x m_iNumCols.
range = objSheet.get_Range("A1", Missing.Value);
range = range.get_Resize(5, 5);

if (this.FillWithStrings.Checked == false)
{

//Create an array.
double[,] saRet = new double[5, 5];

//Fill the array.
for (long iRow = 0; iRow < 5; iRow++)
{

for (long iCol = 0; iCol < 5; iCol++)
{
//Put a counter in the cell.
saRet[iRow, iCol] = iRow * iCol;
}

}

//Set the range value to the array.
range.set_Value(Missing.Value, saRet );

}

else
{

//Create an array.
string[,] saRet = new string[5, 5];

//Fill the array.
for (long iRow = 0; iRow < 5; iRow++)
{

for (long iCol = 0; iCol < 5; iCol++)
{
//Put the row and column address in the cell.
saRet[iRow, iCol] = iRow.ToString() + "|" + iCol.ToString();
}

}

//Set the range value to the array.
range.set_Value(Missing.Value, saRet );

}

//Return control of Excel to the user.
objApp.Visible = true;
objApp.UserControl = true;

}

catch( Exception theException )
{

String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat( errorMessage, theException.Message );
errorMessage = String.Concat( errorMessage, " Line: " );
errorMessage = String.Concat( errorMessage, theException.Source );

MessageBox.Show( errorMessage, "Error" );

}

}
   
참고 Visual Studio 2005에서는 코드를 변경해야 합니다. 기본적으로 Visual C#에서는 Windows Forms 프로젝트를 만들면 해당 프로젝트에 폼 하나가 추가됩니다. 이 폼의 이름은 Form1입니다. 폼을 나타내는 두 개의 파일 이름은 각각 Form1.cs와 Form1.designer.cs입니다. 코드는 Form1.cs에 작성합니다. Windows Forms 디자이너에서는 사용자가 도구 상자에서 컨트롤을 끌어 놓는 방법으로 수행한 모든 작업을 구현하는 코드를 Form1.designer.cs 파일에 작성합니다. Visual C# 2005의 Windows Forms 디자이너에 대한 자세한 내용은 다음 MSDN(Microsoft Developer Network) 웹 사이트를 참조하십시오.
http://msdn2.microsoft.com/ko-kr/library/ms173077.aspx (http://msdn2.microsoft.com/ko-kr/library/ms173077.aspx)

8. Form1의 디자인 보기로 돌아가서 Button2를 두 번 누릅니다.

9. 코드 창에서

private void button2_Click(object sender, System.EventArgs e)
{
}
   
위의 코드를 아래와 같이 바꿉니다.

private void button2_Click(object sender, System.EventArgs e)
{

Excel.Sheets objSheets;
Excel._Worksheet objSheet;
Excel.Range range;

try
{

try
{


//Get a reference to the first sheet of the workbook.
objSheets = objBook.Worksheets;
objSheet = (Excel._Worksheet)objSheets.get_Item(1);

}

catch( Exception theException )
{

String errorMessage;
errorMessage = "Can't find the Excel workbook.  Try clicking Button1 " + "to create an Excel workbook with data before running Button2.";

MessageBox.Show( errorMessage, "Missing Workbook?");

//You can't automate Excel if you can't find the data you created, so
//leave the subroutine.
return;

}

//Get a range of data.
range = objSheet.get_Range("A1", "E5");

//Retrieve the data from the range.
Object[,] saRet;
saRet = (System.Object[,])range.get_Value( Missing.Value );

//Determine the dimensions of the array.
long iRows;
long iCols;
iRows = saRet.GetUpperBound(0);
iCols = saRet.GetUpperBound(1);

//Build a string that contains the data of the array.
String valueString;
valueString = "Array Data\n";

for (long rowCounter = 1; rowCounter <= iRows; rowCounter++)
{

for (long colCounter = 1; colCounter <= iCols; colCounter++)
{

//Write the next value into the string.
valueString = String.Concat(valueString,
saRet[rowCounter, colCounter].ToString() + ", ");

}

//Write in a new line.
valueString = String.Concat(valueString, "\n");

}

//Report the value of the array.
MessageBox.Show(valueString, "Array Values");

}

catch( Exception theException )
{

String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat( errorMessage, theException.Message );
errorMessage = String.Concat( errorMessage, " Line: " );
errorMessage = String.Concat( errorMessage, theException.Source );

MessageBox.Show( errorMessage, "Error" );

}

}


10. 코드 창의 맨 위로 스크롤합니다. using 지시문 목록의 끝에 다음 행을 추가합니다.

using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
   

자동화 클라이언트 테스트
1. F5 키를 눌러 예제 프로그램을 빌드하고 실행합니다.

2. Button1을 누릅니다. Microsoft Excel이 시작되어 새로운 통합 문서가 나타나고 첫 번째 워크시트의 A1:E5 셀이 배열의 숫자 데이터로 채워집니다.

3. Button2를 누릅니다. A1:E5 셀의 데이터가 새로운 배열에 삽입되고 결과가 메시지 상자에 표시됩니다.

4. FillWithStrings를 선택하고 Button1을 눌러 A1:E5 셀을 문자열 데이터로 채웁니다.

1. 일단 txt를 날짜 형식으로 변환하는 방법

DateTime convDate = DateTime.Now;   //기본값으로 현재 날짜를 넣어 둡니다.
string strDate = "2004-03-18";              //임의의 날짜값을 받습니다.
convDate = DateTime.Parse(strDate);   // 스트링 형식의 날짜를 Date 형식으로 바꾸어 놓은 것입니다.

이 형변환을 통해 나중에 날짜 비교를 할때  사용하는 거죠...

2. 두 날짜간의 순서 비교
이 비교는 단순비교로 두개의 날짜를 비교해서 값을 리턴해 주는 것으로,
기준값(t1) 보다 비교값(t2)가 더 크면  (즉 t1의 날짜가 t2의 날자가 더 나중이면, t1<t2) -1을 리턴,   기준값(t1) 보다 비교값(t2)가 더 작으면(즉 t1의 날짜가 t2의 날자가 더 이전이면, t1>t2) 1을 리턴,  기준값(t1) 보다 비교값(t2)가 같으면(즉 t1의 날짜가 t2의 날자가 같으면, t1=t2) 0을 리턴합니다.

MSDN의 내용을 발췌하면...

DateTime t1 = new DateTime(100);
DateTime t2 = new DateTime(20);
if (DateTime.Compare(t1, t2) >  0) Console.WriteLine("t1 > t2");
if (DateTime.Compare(t1, t2) == 0) Console.WriteLine("t1 == t2");
if (DateTime.Compare(t1, t2) <  0) Console.WriteLine("t1 < t2");

이렇게 되는 것이구요.
실제 날짜를 비교해서 넣으면,(<--저 같은 초보를 위해...)

DateTime t1 = new DateTime("2004-03-17");
DateTime t2 = new DateTime("2004-03-18");
if (DateTime.Compare(t1, t2) >  0) Console.WriteLine("t1 > t2");
if (DateTime.Compare(t1, t2) == 0) Console.WriteLine("t1 == t2");
if (DateTime.Compare(t1, t2) <  0) Console.WriteLine("t1 < t2");

이러면 답은...뭐가 될까요?...답은...  -1이 리턴되며  표시는 t1< t2 가 화면에 표시 되겠죠?...ㅎㅎㅎ

3. 특정일에서 특정일 더하거나 빼거나 해서 날짜 구하는 법
오늘을 기준으로 날짜를 30일 더하거나 빼는 방법은...

30일 더하는 방법 : DateTime.Today.AddDays(30).ToString("yyyyMMdd")
30일 빼는 방법 : DateTime.Today.AddDays(-30).ToString("yyyyMMdd")

4. 두 날짜 사이의 간격을 구하는 방법
DateDiff 인가 하는 것이 VB에도 있구, SQL에도 있는 것인데...C#에서는 이렇게 한답니다.(사실은 이것 땜시 공부를 한거죠...ㅎㅎㅎ...)   TimeSpan을 사용하는 것인데 두가지 방법이 있습니다. 뭐...같다고도 할 수 있죠...

DateTime t1 = DateTime.Now;    //날짜형 변수 t1을 선언하는데 기본값으로 현재 날짜를 설정합니다.
DateTime t2 = DateTime.Now;    //아래부분은 사실 두개의 택스트 박스의 값을 입력 받은 것입니다.
t1 = DateTime.Parse(txt_StartDay.Text); // 이 내용은 한줄로도 가능하며...이런 형식입니다. 괜히 길게썼죠?...
t2 = DateTime.Parse(txt_EndDay.Text);  // DateTime t1 =DatTime.Parse("2004-03-18");

//TimeSpan을 쓰는 두가지 방법. 방법(1)
TimeSpan t3 = t2.Subtract(t1);

//TimeSpan을 쓰는 두가지 방법. 방법(2)
TimeSpan t4 = t2 - t1;

//위의 날짜차이를 계산하여 int 형식으로 리턴해 주며 쓰기는 이렇게 씁니다. t5, t6의 값은 같습니다.
int t5 = t3.Days;
int t6 = t4.Days;

만약 t1의 날짜가 "2004-03-18" 이고 t2의 날짜가 "2004-03-01" 이라면 -17을 리턴해 주겠죠?

출처 : http://blog.naver.com/corea4004/120007284388

폼의 버튼에 gif 애니메이션 그림을 넣으려고 합니다.  
버튼의 이미지 속성에다 파일경로를 적어주니까 그냥 멈춘 그림으로 보여서요.

--> 그럴 때 쓰는 것이 ImageAnimator타입이죠.

출처 : http://www.c-sharpcorner.com/Code/2002/Nov/ThreadPoolGifs.asp

+ Recent posts