다음 article 은 MSDN 의 내용을 한글로 바꾼 내용입니다.

참고만 하시기 바랍니다.

 

Tutorial : SignalR 2 시작하기

 

 

이 Tutorial 은 SignalR 을 사용하여 real-time chat application 을 만드는 방법을 보여줍니다.

빈 ASP.NET web application 에 SignalR 을 추가하고 생성한 HTML page 에 message 를 보내고 표시합니다.

 

이 tutorial 은 다음과 같은 Software 의 버전을 사용합니다.

• Visual Studio 2013
• .NET 4.5
• SignalR version 2

 

 

Visual Studio 2012 에서 이 Tutorial 사용하기

Visual Studio 2012 에서 이 Tutorial 을 수행하려면 다음 절차를 따르십시오.

• Package Manager 를 최종버전으로 Update 하십시오. the latest version.

• Web Platform Installer 를 설치하십시오..

• Web Platform Installer,에서  Visual Studio 2012 용 ASP.NET and Web Tools 2013.1 를 검색해서 설치하십시오.  그러면 Hub 같은 SignalR class 용 Visual Studio template 들이 설치될 것입니다.

• 일부 template (OWIN Startup Class 같은) 들은 사용할 수 없으므로 대신 Class 파일을 사용하면 됩니다.

 

 

Tutorial Version

SignalR 의 이전버전에 대한 사항은 SignalR Older Versions. 을 참조하십시오.

 

질문과 의견

이 Tutorial 이 얼마나 맘에 들었는지, 어떻게 하면 개선할 수 있는지 페이지 아래쪽에 의견을 남겨주십시오.

만약 Tutorial 에 직접 연관된 질문이 아니라면 ASP.NET SignalR forum 이나 StackOverflow.com 에 글을 게시할 수 있습니다.

 

 

개요.

이 Tutorial 은 간단한 Browser based chat application 을 개발하는 방법을 보여줌으로써 SignalR 개발을 소개합니다.

빈 ASP.NET web application 에 SignalR library 를 추가하여, client 에 message 를 보낼 hub class 를 생성하고, 사용자들이 chat message 를 보내고 받을 HTML page 를 생성합니다.

MVC 5 의 MVC view 를 사용하는 MVC 5 에서 chat application 을 생성하는 방법을 보여주는 유사한 Tutorial 은 Getting Started with SignalR 2 and MVC 5. 를 참조하십시오.

  

 

노트
이 튜토리얼은 버전 2 의 SignalR 애플리케이션을 생성하는 방법을 보여줍니다.
SignalR 1.x와 2 사이의 변경 사항에 대한 자세한 내용은 SignalR 1.x 프로젝트 업그레이드하기와 Visual Studio 2013 Release Notes 를 참조하십시오.

 

SignalR 은 실시간 사용자 상호작용이나 실시간 데이터 update 가 요구되는 Web Application 을 구축할 수 있도록 하는 Open-source .NET Library 입니다.

Social application, Multiuser Game, Business collaboration, 그리고 뉴스, 날씨 혹은 재무 업데이트 application 등이 예가 될 수 있습니다.


이들은 종종 real-time application 이라 불리웁니다.

SignalR 은 real-time application 구축 process를 간소화 합니다. ASP.NET Server library 와 JavaScript client library 를 포함하고 있어 client-server 연결을 쉽게 관리할 수 있으며 Client 로 content update 를 쉽게 Push 할 수 있습니다.

기존의 ASP.NET application 에 SignalR library 를 추가하면 real-time 기능을 얻을 수 있습니다.


 

Tutorial 은 SignalR 개발 작업 진행을 보여줍니다.
• ASP.NET web application 에 SignalR library 추가하기.
• clinet 에 Content 를 Push 하기 위해서 Hub class 를 생성하기.
• application 을 설정하기 위해 OWIN startup class 생성하기.
• web page 에 SignalR jQuery library 를 추가하여 message 를 보내고 Hub 로 부터 온 Update 사항을 표시합니다.


다음 Screen shot 은 browser 에서 동작하는 chat application 을 보여줍니다. 각 새로운 사용자는 사용자가 chat 에 참여한 후 의견을 게시할 수 있고,  추가한 의견을 볼 수 있습니다.
 

Chat instances


Sections:
• Project 설정
• Sample 실행
• Code 검사
• 다음단계
 

 프로젝트 설정

이 Section 은 Visual Studio 2013 과 SignalR versin 2 를 사용하여 빈 ASP.NET web application 을 생성하는 방법을 보여줍니다.  SignalR 을 추가하고 chat application 을 생성합니다.

 

필수사항:

• Visual Studio 2013.

만약 Visual Studio 를 가지고 있지 않다면 무료 Visual Studio 2013 Express Development Tool 를 얻을 수 있는 ASP.NET Downloads 를 참조하십시오.

 

다음 단계는 ASP.NET 빈 Web Application 을 생성하기 위해서 Visual Studio 2013 을 사용합니다. 그리고 SignalR library를 추가합니다:

 

1. Visual Studio 에서 ASP.NET Web Application 을 생성하십시오.
 

Create web


2. New ASP.NET Project 창에서 Empty 를 선택한 채로 두고 Create Project 를 클릭합니다.
 

Create empty web

 

 

 

3. Solution 탐색기에서, project 를 오른쪽 클릭하여, Add | SignalR Hub Class (v2) 를 선택하십시오. class 의 이름을 ChatHub.cs 로 지정하고 project 에 추가하십시오.

이 단계는 ChatHub class 를 생성하고 project 에 SignalR 을 지원하는 script file 과 assembly references 를 추가합니다.

 

 

Note

Tools | Library Package Manager | Package Manager Console 을 열어 명령을 실행하여 project 에 SignalR 또한 추가할 수 있다.

 

 

install-package Microsoft.AspNet.SignalR

만약 SignalR 을 추가하기 위해 console 을 사용한다면 SignalR 을 추가한 이후에 별도의 단계에서 SignalR hub class 를 생성하십시오.

 

Note

만약 Visual Studio 2012 를 사용한다면 SignalR Hub Class(2) template 을 사용할 수 없습니다.

ChatHub 를 호출하는 대신 평범한 Class 를 추가할 수 있습니다.

 

4.  Solution 탐색기에서 Script node 를 확장합니다. project 내에 jQuery 와 SignalR 용 Script library 가 보일 것입니다.

5. 새 ChatHub class 에 있는 code 를 다음 code로 바꾸십시오.

 

using System;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalRChat
{
    public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }
    }
}

 

 

6. Solution 탐색기에서 프로젝트를 오른쪽 클릭하여 나온 메뉴에서 Add | OWIN Startup Class 를 클릭합니다.

새 클래스 이름을 Startup 이라 입력하고 OK 를 클릭합니다.

 

Note

만약 visual Studio 2012를 사용한다면 OWIN Startup class template 을 사용할 수 없습니다.

Startup 을 호출하는 대신 보통 class 를 추가할 수 있습니다.

 

7. 새 Startup class 의 내용을 다음 내용으로 바꾸십시오.

 


using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}   

 

8. Solution 탐색기에서 project 를 오른쪽 클릭해서 나온 메뉴에서 Add | HTML Page 를 클릭합니다.

새로운 page 의 이름을 index.html 로 지정합니다.

>[!NOTE] >JQuery 와 SignalR library 사용하기 위해 reference 의 version number 를 변경해야할 수도 있습니다.

 

9. Solution 탐색기에서 방금전에 생성한 Html page 를 오른쪽 클릭하여 나타난 메뉴에서 Set as Start Page 를 클릭합니다.

10. HTML page 의 기본 code 를 다음 code 로 변경합니다.

 

Note

package manager 가 SignalR script 의 마지막 버전을 설치했을 수도 있습니다.

아래 script reference 가 project 의  script 파일의 version 과 일치하는지 확인하십시오.

(hub 를 추가하는 대신 NuGet 을 사용하여 SignalR 을 추가했다면 차이가 날것입니다.)

 

 


<!DOCTYPE html>
<html>
<head>
    <title>SignalR Simple Chat</title>
    <style type="text/css">
        .container {
            background-color: #99CCFF;
            border: thick solid #808080;
            padding: 20px;
            margin: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />
        <input type="hidden" id="displayname" />
        <ul id="discussion">
        </ul>
    </div>
    <!--Script references. -->
    <!--Reference the jQuery library. -->
    <script src="Scripts/jquery-3.1.1.min.js" ></script>
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="signalr/hubs"></script>
    <!--Add script to update the page and send messages.-->
    <script type="text/javascript">
        $(function () {
            // Declare a proxy to reference the hub.
            var chat = $.connection.chatHub;
            // Create a function that the hub can call to broadcast messages.
            chat.client.broadcastMessage = function (name, message) {
                // Html encode display name and message.
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                // Add the message to the page.
                $('#discussion').append('<li><strong>' + encodedName
                    + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
            };
            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            // Set initial focus to message input box. 
            $('#message').focus();
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    // Call the Send method on the hub.
                    chat.server.send($('#displayname').val(), $('#message').val());
                    // Clear text box and reset focus for next comment.
                    $('#message').val('').focus();
                });
            });
        });
    </script>
</body>
</html>

 

11. project 전부를 저장하십시오.

 

 

Sample 실행

 

1. project 를 debug mode 로 실행시키기 위해 F5 를 누릅니다. HTML page 가 browser 에 뜹니다 그리고 user name 을 입력하도록 깜빡입니다.
 

Enter user name


 

2. user name 입력

3. browser 의 address line 의 URL 을 복사합니다. 그리고 두개 이상의 browser 에서 엽니다.

각각의 browser 에서 유일한 user name 을 입력합니다.

4. 각 browser 에서 의견을 입력하고 Send 를 click 합니다. 의견이 모든 browser 에 나타날 것입니다.

 

Note

이 간단한 chat application 은 서버에 discussion context 를 유지하지 않습니다. hub 는 모든 현재 user 에게 의견을 broadcast 합니다.

User 는 chat 에 가입한 후에 가입한 시간 후에 추가된 message 를 볼 수 있습니다.

 

 

다음 screen shot 은 세 browser 에서 돌아가는 chat application 을 보여줍니다. 한 instance 가 message 를 보내면 나머지 모든 browser 가 update 됩니다:

 

Chat browsers


 

5. Solution 탐색기에서 실행중인 application 의 Script Document node 를 검사하십시오. hubs 라는 script file  이 SignalR library 에 의해 realtime 에 동적으로 생성됩니다. 이 file 은 jQuery script 와 server-side code 간의 communication 을 관리합니다.


 

 

Code 검사

SignalR chat application 은 두개의 기본 SignalR 개발 작업을 보여줍니다: server 에서 main coordination object 로써 hub 를 생성하는 작업과 message 를 보내고 받는데 SignalR jQuery library 를 사용하는 작업입니다.

 

SignalR Hubs

Code sample 에서 ChatHub class 는 Microsoft.AspNet.SignalR.Hub class 로 부터 파생되었습니다. Hub class 로부터 파생하는 것은 SignalR application 을 구축하는데 사용하는 유용한 방법입니다.

hub class 에 public method 를 생성할수 있어서 web page 의 script 로 부터 호출하여 method 에 접근할수 있습니다.

 

chat code 에서 client 는 새로운 message 를 보내기위해서 ChatHub.Send method 를 호출합니다.

그러면 hub 는 Client.All.broadcastMessage 를 호출함으로써 모든 client 들에게 message 를 보냅니다.

 

Send method 는 몇가지 hub 개념을 보여줍니다.

• client 들이 호출할 수 있는 public method 를 hub 에 선언합니다.  

• 이 hub 에 연결된 모든 client 에 접근하기 위해 Microsoft.AspNet.SignalR.Hub.Clients dynamic property 를 사용합니다.
• client 들을 업데이트 하기위해 client 의 function(broadcastMessage function 같은) 을 호출합니다.

 

public class ChatHub : Hub
{
    public void Send(string name, string message)
    {
        // Call the broadcastMessage method to update clients.
        Clients.All.broadcastMessage(name, message);
    }
}


 
SignalR 과 jQuery

Code sample 의 HTML page 는 SignalR hub 와 commiunication 하기 위해 SignalR jQuery library 를 사용하는 방법을 보여줍니다.

code 에서의 필수작업은 hub 를 참조하기 위해 proxy 를 선언하고, client 에 content 를 push 하기 위해 호출할 수 있는 function 을 선언하는 것입니다. 그리고 hub 에 message 를 보내기위해 connection 을 시작하는 것입니다.

다음 code 는 hub proxy 를 위한 reference 를 선언합니다.

 

var chat = $.connection.chatHub;


 

Note

JavaScript 에서 server class 와 class 의 member 에 대한 reference 는 camel case 를 사용합니다.

code sample 에서 C# 의 ChatHub 를 JavaScript 에서 chatHub 로 참조합니다.

 

다음 code 는 script 에서 callback function 을 생성하는 방법입니다.

server 의 hub class 는 이 function 을 이용하여 각 client 에 content update 를 push 합니다.

표시하기전에 content 를 HTML 로 encode 하는 두줄은 선택사항이며 script injection 을 방지하는 간단한 방법을 보여줍니다.

 

chat.client.broadcastMessage = function (name, message) {
        // Html encode display name and message.
        var encodedName = $('<div />').text(name).html();
        var encodedMsg = $('<div />').text(message).html();
        // Add the message to the page.
        $('#discussion').append('<li><strong>' + encodedName
            + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
    };

 

다음 code 는 hub 와의 connection 을 여는 방법을 보여줍니다 code 는 connection 을 시작하고 난뒤 HTML page 의 Send button 의 click event  를 처리하기 위한 function 을 전달합니다.

 

Note

이렇게 하면 event handler 가 실행되기전에 connection 이 설정됩니다.

 


$.connection.hub.start().done(function () {
        $('#sendmessage').click(function () {
            // Call the Send method on the hub.
            chat.server.send($('#displayname').val(), $('#message').val());
            // Clear text box and reset focus for next comment.
            $('#message').val('').focus();
        });
    });

 

다음 단계

여러분은 SignalR 이 real-time web application 을 구축하는 framework 이라는 걸 배웠습니다.

ASP.NET application 에 SignalR 을 추가하는 방법, hub class 를 생성하는 방법, hub 로 부터 message 를 보내고 받는 방법 과 같은 몇가지 SignalR 개발 작업에 대해서도 배웠습니다.

sample SignalR application 을 Azure 에 배포하는 방법에 대한 walkthrough 는 Using SignalR with Web Apps in Azure App Service.를 참조하십시오.

Windows Azure Web Site 에 Visual Studio web project 를 배포하는 방법에 대한 자세한 내용은 Create an ASP.NET web app in Azure App Service. 를 참조하십시오.

고급 SignalR 개발 개념을 배우려면 SignalR source code 와 참조가 있는 다음 사이트에 방문하십시오.


• SignalR Project
• SignalR Github 와 Samples
• SignalR Wiki

 

 

 

행복한 고수 되셔요. ^^

 

woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

 













저작자 표시 비영리 변경 금지
신고

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

[SignalR] Tutorial: Getting Started with SignalR 2  (0) 2017.11.23
Posted by woojja


Excel 의 Column 문자를 숫자로, 숫자를 알파벳 문자로 변환하는 방법입니다.


  1.  
  2.         /// <summary>
  3.         /// Coulumn 문자를 Int 값으로 변환
  4.         /// </summary>
  5.         /// <param name="value">Column 문자</param>
  6.         /// <returns></returns>
  7.         static public int Column2Int(string value)
  8.         {
  9.             int result = 0;
  10.  
  11.             if (value != null && value.Length > 0)
  12.             {
  13.                 foreach (char item in value)
  14.                 {
  15.                     result = 26 * result + (item - 'A');
  16.                 }
  17.  
  18.                 result++; //1 based
  19.  
  20.                 if (value.Length > 1)
  21.                 {
  22.                     result += 26;
  23.                 }
  24.             }
  25.  
  26.             return result;
  27.         }
  28.  
  29.         /// <summary>
  30.         /// Column 숫자를 알파벳 문자로 변환.
  31.         /// </summary>
  32.         /// <param name="value">Column 숫자</param>
  33.         /// <returns></returns>
  34.         static public string Int2Column(int value)
  35.         {
  36.             List<char> result = new List<char>();
  37.  
  38.             if (value > 0)
  39.             {
  40.                 value--; //1 based
  41.  
  42.                 if (value < 26)
  43.                 {
  44.                     result.Add((char)('A' + value));
  45.                 }
  46.                 else
  47.                 {
  48.                     value -= 26;
  49.                     do
  50.                     {
  51.                         result.Add((char)('A' + value % 26));
  52.                         value = value / 26;
  53.                     } while (value > 0);
  54.  
  55.                     if (result.Count == 1)
  56.                     {
  57.                         result.Add('A');
  58.                     }
  59.                 }
  60.             }
  61.  
  62.             return new string(result.Reverse<char>().ToArray());
  63.         }

행복한 고수되십시오.



woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\














저작자 표시 비영리 변경 금지
신고
Posted by woojja

Excel 을 사용하시다가


Excel Office Object 를 사용하시다가 다음구문에서 "해당 셀이 없습니다." 라는 류의 오류가 발생한다면

xlWorkSheet.Range[firstCell, lastLastCell].SpecialCells(MSExcel.XlCellType.xlCellTypeConstants)

해당 영역 내에 아무런 값이 없어서 발생하는 것입니다.


값이 들어가 있는 녀석들만 골라서 추려주거든요. ^^

행복한 고수되셔요. ^^


woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\















저작자 표시 비영리 변경 금지
신고
Posted by woojja
2017.11.15 21:00


이런 초보적인... ^^;


Directory 생성후 생성한 폴더에 작업시 오류가 발생한다면...


            if (!Directory.Exists(directoryName))

            {

                Directory.CreateDirectory(target.FullName);

                Thread.Sleep(100);

            }


또는


            if (!Directory.Exists(directoryName)) Directory.CreateDirectory(directoryName);

            int i = 0;

            while (true)

            {

                if (Directory.Exists(directoryName))

                    break;

                

                Thread.Sleep(100);

                i++;


                if (i > 10) break;

            }



행복한 고수되셔요. ^^


woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\













저작자 표시 비영리 변경 금지
신고

'.NET > C#' 카테고리의 다른 글

[C#] CreateDirectory  (0) 2017.11.15
[C#] Logging on File  (0) 2017.10.24
[C#] How do you check if a file is in use?  (0) 2017.07.27
[C#] 단일 Process 실행  (2) 2010.11.08
[C#] C# 은 VB.NET 따라쟁이...  (3) 2009.05.07
[C#] C# 컴파일러 오류  (0) 2009.03.06
Posted by woojja

 

 

 

Visual Studio 의 Extention 을 소개하려고 합니다.

 

Go To Definition 이라는 Extention 인데요.

Class 나 변수를 Ctrl 과 함께 클릭을 하면 정의한 곳으로 이동 시켜줍니다.

 

추가 팁으로는 Ctrl + Shift + 7 또는 8 을 이용하여 다시 되돌아가거나 돌아 올수 있습니다.

마우스에 따라 앞으로, 뒤로 가기 버튼이 있는 경우도 있지만

있어도 기능이 먹는 녀석이 있고, 안되는 경우도 있고.

 

^^;

 

VisualStudio 2017 의 경우는

 

https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.CtrlClickGoToDefinition

 

에서 Download 받아 설치하시고요.

 

이전 버전의 경우는

https://marketplace.visualstudio.com/items?itemName=NoahRichards.GoToDefinition

 

에서 Downlad 받으시면 되겠습니다.

 

매우 유용합니다.

 

 

행복한 고수되셔요.

 

 

woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\













저작자 표시 비영리 변경 금지
신고

'Tools > Settings' 카테고리의 다른 글

[Settings] VisualStudio - Go To Definition  (2) 2017.11.07
[Settings] Visual Studio 2010 Pro Power Tools  (0) 2010.06.25
Posted by woojja

 

GUID Maker 를 수정했습니다.

(http://jumptovb.net/search/guidmaker 를 참고하셔요.)

 

 

필요한 사항이 있어서요. ^^

 

 

수정사항은 Hyphen 표시 유무 입니다. ^^

Source 는 링크를 Click 하시면 GitHub 로 이동합니다.

 

 

GUID Maker Source

 

 

 

 

 

GUID Maker 2 Source

 

 

다음 Update 시에는 두개를 합쳐야겠습니다. ^^

 

 

행복한 고수되셔요.













저작자 표시 비영리 변경 금지
신고

'Tools' 카테고리의 다른 글

[Tools] GUID Maker Updated.  (0) 2017.10.31
[Tools] Log4Net  (0) 2017.10.12
[Tools] DotNetZip  (0) 2017.10.10
[Tools] 3 Ways to Change Bitrate on MP3 Files  (0) 2017.09.08
[Tools] NShape  (0) 2017.06.28
[Tools] GUID Maker  (0) 2017.06.21
Posted by woojja
2017.10.27 21:00

tutorialspoint 에서 배포한 MVVM PDF 문서를 우리말로 바꾸어 보려고 합니다.

엉망이니 참고만 하시기 바랍니다.

 

###############################################################################

 

1. MVVM – 소개

 

코드를 잘 정리하고 가장 잘 재사용할 수 있도록 조직화 하는 방법은 'MVVM' pattern 을 사용하는 것입니다.

Model, View, ViewModel (MVVM pattern) 은 여러분이 유지보수 가능하고, 테스트가 가능하며 확장가능한 application 을 작성할 수 있도록 코드를 조직화하고 구조하는 방법으로  안내합니다.

 

Model : data 의 정보를 가지고 있으며 business logic 과는 아무런 작업도 하지 않습니다.

ViewModel : Model 과 ViewModel 사이에서 Link/connection 으로서의 역할을 하며 꽤 멋지게 보이게 합니다.

View : 형식화된 data 를 가지고 있으며 특히나 모든것을 Model 에 위임 (delegate) 합니다.

 

 

분리된(Seperated) Presentation

code-behind 나 XAML 의 application logic 에서 야기된 문제들을 피하기 위해서 분리된 presentation 이라고 알려진 기술을 사용하는 것이 최선입니다.

이런 문제점을 피하기 위해서 User interface object 와 직접 작업하는데 필요한 XAML 과 Code-behind 를 최소한으로 할 것입니다.

 

다음 그림의 왼쪽을 보는 것 처럼 User interface class 들은 복잡한 interaction behaviors, application logic 과 모든 것을 위한 코드를 포함하고 있습니다. 

 

 

 

 

  • 분리된 presentation 기술로 User interface class 는 더욱 단순해집니다.  XAML 을 가지고 있습니다. 하지만 Code-behind 는 실용적으로 적습니다.
  • application logic 이 별도의 class 내에 들어가 있으며 이는 종종 model 로 언급됩니다.

 

  • 하지만 이는 전체 이야기가 아닙니다. 여기서 그만두면 여러분은 data binding 방식을 잃어버리는  매우 흔한 실수를 반복하게 될 것입니다. (However, this is not the whole story. If you stop here, you're likely to repeat a very common mistake that will lead you down the path of data binding insanity)
  • 많은 개발자들이 XAML 에서 data binding 을 사용하여 element 를 직접 model 의 properties 와 연결하기를 시도합니다.

 

  • 때때로 이 방법은 괜찮을수 있습니다. 하지만 그렇지 않을 수 있습니다. Model 은 application 의 동작과 관련이 있지 사용자가 application 과 상호작용하는 방법과는 관련이 없다는 것이 문제입니다.

 

  • Data 를 표현하는 방식은  내부적으로 구조화된 방식과 다소 다릅니다. 게다가 대부분의 user interface 는 application model 이 가지고 있지 않은 몇몇 state 를 가지고 있습니다.

 

  • 예를 들어 만약 user interface 가 drag and drop 을 사용한다면 Drag 되는 항목의 현재 위치는 어디인지,  drop 할 수 있는 target 의 위로 이동했을 때 모양은 어떻게 바뀌는지, target 또한 어떻게 바뀌어야하는지 같은 것들을  추적해야합니다.

 

  • 이런 state 는 놀라울정도록 복잡할 수 있고 철저한 테스트가 필요합니다.

 

  • 실제로 여러분은 User interface 와 Model 사이에 어떤 다른 class 가 있길 원합니다. 여기에는 두가지 중요한 role 이 있습니다.
    • 첫째, 특정 User interface view 를 위한 application model 을 채택합니다.
    • 둘째, 자잘한 interaction logic 이 존재하는 곳이며 그 코드는 여러분이 원하는 방식으로 user interface 가 작동하도록 합니다.

 

######################################################

 

이상입니다. 우리말이 너무 어렵네요. 

머리로는 이해가 가는데 말로 표현하려니...

 

제가 잘 몰라서겠죠...

 

영어도 못하고 우리말도 못하고... ㅡㅡ;

 

 

행복한 고수되셔요.

 

woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\













저작자 표시 비영리 변경 금지
신고

'MVVM' 카테고리의 다른 글

[MVVM] 1. 소개  (0) 2017.10.27
Posted by woojja

 

Adding a view to an ASP.NET Core MVC app (3/10)

 

 

1. 시작 (원글 : Getting started)
2. Controller 추가하기 (원글 : Adding a controller)
3. View 추가하기 (원글 : Adding a view)
4. Model 추가하기 (원글 : Adding a model)
5. Working with SQL Server LocalDB
6. Controller methods and views
7. Adding Search
8. Adding a New Field
9. Adding Validation
10. Examining the Details and Delete methods

 

이 섹션에서 여러분은 client 에 응답할 HTML 을 생성하는 작업을 깔끔하게 캡슐화하는 Razor view template 을 사용하기 위해 HellowWorldController class 를 수정합니다.

여러분은 Razor 를 사용하는 view template file 을 생성합니다.

Razor 기반 View template 은 cshtml 확장자를 갖습니다.

C# 을 사용하여 HTML output 을 생성하는 우아한 방법을 제공합니다.

현재 index method 는 controller class 에서 hard-cord 된 string 의 message 를 반환합니다.

HelloWorldController class 의 index method 를 다음 코드로 변경합니다.

 

 

public IActionResult Index()
{
    return View();
}

 

진행되는 code 는 view object 를 반환합니다.

Browser 에 HTML 응답코드를 생성하기위해 view template 을 사용합니다.

위 index method 같은 Controller method (action method 로 알려진) 는 일반적으로 string과 같은 Primitive 한 형식이 아닌 IActionResult (또는 ActionResult 에서 파생된 class) 를 반환합니다.

Views Folder 를 오른쪽 클릭합니다., 그리고 Add > New folder 를 선택합니다. 그리고 folder 이름을 "HelloWorld" 로 지정합니다.

Views/HelloWorld folder 를 오른쪽 클릭합니다. 그리고 Add > New Item 을 선택합니다.

 

Add New Item - MvcMovie 대화창에서  

오른쪽 상단의 search 입력란에 view 를 입력합니다.

MVC View Page 를 Tap 합니다.

Name 입력란에 필요하다면 이름을 index.cshtml 로 변경합니다.

Add 를 Tap 합니다.

 

Add New Item dialog

 

Views/HelloWorld/index.cshtml Razor View 파일의 내용을 다음의 코드로 변경하십시오.

 

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>Hello from our View Template!</p>

 

http://localhost:xxx?HelloWorld 로 이동하십시오.

HelloWorldController 의 index method 는 많은 일을 하지 않습니다. 구문을 실행하고 View(); 를 반환하는 함수를 지정하는데, Browser 에 보낼 응답을 render 하기 위해서 View template 을 사용해야 합니다.

View template file 의 이름을 명확하게 지정하지 않았기 때문에 MVC 는 기본적으로 Views/HelloWorld 폴더내의 index.cshtml view file 을 사용합니다.

아래의 이미지는 View 에 Hard Cording된 "Hello from our View Template!" 이라는 문자열을 보여줍니다.

 

 

Browser window

 

만약 여러분의 browser 창이 작다면( 예를들어, mobile device 처럼 ), Home, About, Contact 링크를 보기위해서 우측상단의 Bootstrap navigation button 을 toggle (tap)할 필요가 있습니다.

 

Browser window highlighting the Bootstrap navigation button

 

View 와 Layout page 변경하기

menu link (MvcMovie, Home, About) 를 Tap 합니다.

각 페이지는 동일한 menu layout 을 보여줍니다.

menu layout 은 Views/Shared/_Layout.cshtml file 에 구현되어 있습니다.

Views/Shared/_Layout.cshtml 파일을 여십시오.

 

Layout template 을 사용하면 여러분 사이트의 HTML container layout 를 한곳에서 지정할 수있으며 여러분 사이트의 여러페이지에 적용됩니다.

@RenderBody() Line 을 찾으십시오.

RenderBody 는 여러분이 만든 모든 view page 가 layout page 상에 보이도록 wrapping 된 Placeholder 입니다.

예를 들어, 만약 여러분이 About link 를 선택한다면, Views/Home/About.cshtml View 가 RenderBody method 내부에 rendering 됩니다.

 

Layout file 에서 Title 과 Menu link 변경

Title 요소의 내용을 변경하십시오.

아래 Highlight 된 코드처럼 Layout template 의 anchor text 를 "Movie App" 으로 변경하십시오. 그리고 Controller 를 Home 에서 Movies 로 변경하십시오.

 

참고 : ASP.NET Core 2.0 version 은 약간 다릅니다.

@inject ApplicationInsights 와 @Html.Raw(JavaScriptSnippet.FullScript) 는 포함되어 있지 않습니다.

 

 

@inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie App</title>

    <environment names="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
    @Html.Raw(JavaScriptSnippet.FullScript)
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-area="" asp-controller="Movies" asp-action="Index" class="navbar-brand">MvcMovie</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2017 - MvcMovie</p>
        </footer>
    </div>

    <environment names="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment names="Staging,Production">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("Scripts", required: false)
</body>
</html>

 

 

경고

아직 Movies Controller 를 구현하지 않아서 해당 Link 를 클릭하면 404 (Not Found) 오류가 발생합니다. 

 

변경사항을 저장하고 About Link 를 Tap 하십시오.

browser tab 의 Title 에 About - Mvc Movie 대신에 About - Movie App 을 표시하는 방법에 주의하여 보십시오.

Contact Link 를 Tap 하여 Movie App 이 표시되는 것 또한 주의하여 보십시오.

Layout template 을 한번 변경하면 Site 의 전체 페이지에 새로운 링크와 새로운 title 이 반영하는 것이 가능했습니다.

Views/_ViewStart.cshtml file 을 검사하십시오.

 

@{
    Layout = "_Layout";
}

 

Views/_ViewStart.cshtml file 은 Views/shared/_Layout.cshtml file 을 각 View 에 전달합니다.

Layout property 에 다른 layout view 를 설정하거나  Null 을 설정하여 아무런 layout 을 사용하지 않도록 할 수 있습니다.

Index view 의  title 변경

Views/HelloWorld/Index.cshtml 을 엽니다. 두군데를 수정합니다.

browser 의 title 에 나타나는 text.

secondary header ( <h2> element )

코드의 어느부분을 변경하면 app 의 어느부분이 바뀌는지 약간의 차이점을 알수 있습니다.

 

 

@{
    ViewData["Title"] = "Movie List";
}

<h2>My Movie List</h2>

<p>Hello from our View Template!</p>

 

 

위 코드의 ViewData["Title"] = "Movie List"; 는 ViewData dictionary 의 Title 속성을 "Movie List" 로 설정합니다.

Title 속성은 Layout page 의 <title> HTML element 에서 사용됩니다.

 

 

<title>@ViewData["Title"] - Movie App</title>

 

변경사항을 저장하고 http://localhost:xxxx/HelloWorld 로 이동하십시오.

browser title, Primary Heading, Secondary Heading 이 변경되었는지 주의해서 살펴보십시오.

(만약 browser 에서 변경사항을 볼 수 없다면 Cache 된 내용일 것입니다. browser 에서 Ctrl+F5 를 눌러 서버의 response 를 강제로 load 하십시오.)

browser title 이 ViewData["Title"]로 생성되어 index.cshtml template 에서 설정되고 추가적으로 " - Movie App" 이 Layout file 에서 추가됩니다.

또, Views/Shared/_Layout.cshtml view template 과 browser 로 보내진 single html response 가 어떻게 병합되어 index.cshtml view template 의 content 가 만들어지는지 주의하여 살펴보십시오.

Layout templates 를 변경하여 적용하면 application 의 모든 페이지 걸쳐 정말 쉽게 변경됩니다.

 

더 자세한 내용은 Layout 을 참조하십시오.

 

Movie List view

 

약간의 data ( 여기서는 "Hello from our View Template" 이라는 message) 는 Hard coding 되어 있습니다.

이 MVC application 에는 "V" (view) 가 있고 "C" (controller) 를 만들었지만 아직 "M" (model) 은 없습니다.

 

Controller 에서 View 로 Data 전달하기

Controller 의 actions 는 들어오는 (incoming) URL request 에 대한 response 에서 호출됩니다.

controller class 는 들어오는 browser request 를 처리하는 코드를 작성하는 곳입니다.

controller 는 data source 로 부터 data 를 retrieve 하고 browser 에 돌려보낼 response 의 type 을 결정합니다.

View template 은 controller 에서 browser 로 보내질 HTML response 를 생성하고 형식을 지정할 수 있습니다.

controller 는 view template 이 response 를 rendering 하기위해 요구되는 data 를 제공해야할 책임이 있습니다.

 

모범 사례 : View template 은 business logic 을 수행하거나 database 와 직접 상호작용을 하면 안됩니다.

대신 view template 은 오직 controller 가 view 만들 위해 제공하는 data 와 작업해야합니다.

이 관심의 분리( "separation of concerns" ) 를 유지하면 여러분의 코드를 깨끗하고, 테스트 가능하고 유지보수가능하도록 하는데 도움이 됩니다.

현재 HelloWorldController class 의 Welcome method 는 name 과 ID 를 매개변수로 취하여 browser 로 값을 직접 출력합니다.

controller 가 response 를 string 으로 rendering 하도록 하기보다. controller 가 view template 을 대신 사용하도록 변경합시다.

 

view template 은 동적 response 를 생성합니다. 이 것은 response 를 생성하기 위해서 적절한 bit 의 data 를 controller 에서 view 로 전달해야할 필요가 있다는 것을 의미합니다.

view template 이 필요한 data 를 controller 에서 dynamic data( parameters) 인  view template 이 접근 가능한 ViewData dictionary 에 담음으로써 이 작업이 가능합니다.

HelloWorldController.cs file 로 돌아가서 ViewData dictionary 에 Message 와 NumTimes 를 추가하도록 Welcome method 를 변경합니다.

ViewData dictionary 는 dynamic object 입니다. 즉 여러분이 원하는 것은 어떤 것도 집어 넣을 수 있습니다.

ViewData object 는 여러분이 그 안에 무언가를 넣기 전까지 정의된 속성이 없습니다.

MVC model binding system 은 address bar 에 적힌 query string 에서  이름있는 매개변수( name 과 numTimes )를 추출하여 여러분이 만든 method 의 parameter 로 자동적으로 mapping 합니다.

완전한 HelloWorldController.cs 파일의 내용은 다음과 같습니다.

 

 

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult Welcome(string name, int numTimes = 1)
        {
            ViewData["Message"] = "Hello " + name;
            ViewData["NumTimes"] = numTimes;

            return View();
        }
    }
}

 

ViewData Dictionary 객체는 View 에 전달할 data 를 포함하고 있습니다.

Views/HelloWorld/Welcome.cshtml 라는 이름의 Welcome view template 을 생성하십시오.

Welcome.cshtml view template 내에 "Hello " NumTimes 를 표시할 Loop 를 생성합니다.

아래 코드로 Views/Helloworld/Welcome.cshtml 의 내용을 변경합니다.

 

 

@{
    ViewData["Title"] = "Welcome";
}

<h2>Welcome</h2>

<ul>
    @for (int i = 0; i < (int)ViewData["NumTimes"]; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul> 

 

변경사항을 저장하고 다음 URL 로 이동하십시오.
http://localhost:xxxx/HelloWorld/Welcome?name=Rick&numtimes=4

Data 를 URL 에서 가져와서  MVC model binder 를 이용하여 controller 에 전달합니다.

controller 는 data 를 ViewData dictionary 에 packages 하고 View 에 그  Object 를 전달합니다.

그 다음 view 는 HTML data 를 browser 에 render 합니다.

 

 

About view showing a Welcome label and the phrase Hello Rick shown four times

 

위 sample 에서 controller 로 부터 view 로 data 를 전달하기위해서 ViewData Dictionary 를 사용했습니다.

다음 tutorial 에서는 controller 에서 view 로 data 를 전달하기위해서 view model 을 사용합니다.

data 를 전달하는 view model 접근 (approach) 은 일반적으로 ViewData dictionary 접근 보다 훨씬 더 좋습니다.

자세한 사항은 ViewModel vs ViewData vs ViewBag vs TempData vs Session in MVC 를 참조하십시오.

그럼, 여기서 M 은 model 을 말하는 것이지 database 를 의미하지 않습니다.

배운 것을 바탕으로 Movie database 를 생성해 봅시다.

 

 

 

이상입니다.

번역?이 이상하고 맘에 들지 않지만 참고로 보시기 바랍니다.

 

 

 

행복한 고수되셔요.

 

 

woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\













저작자 표시 비영리 변경 금지
신고

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

[ASP.NET Core] Adding a view to an ASP.NET Core MVC app (3/10)  (0) 2017.10.27
[ASP.NET Core] MiddleWare  (0) 2017.07.10
[ASP.NET Core] Application Startup  (0) 2017.06.11
Posted by woojja
2017.10.24 20:30


Log4Net 을 사용하다가 다소 불편한 감이 있어서

File 에 Log 를 작성하는 Class 를 간단하게 작성했습니다.

그냥 동적으로 로그 파일을 만들어서 확확 적어버리고 싶었거든요. 




내용은 이렇습니다.


    public enum LogLevel

    {

        NONE,

        TRACE,

        INFO,

        DEBUG,

        WARNING,

        ERROR,

        FATAL,

        MANNUAL

    }


    public class Logger

    {        

        public Logger()

        {

        }

        

        /// <summary>

        /// Format a log message based on log level

        /// </summary>

        /// <param name="level">Log level</param>

        /// <param name="text">Log message</param>

        public static int WriteLog(string filePath, string fileName, string text, LogLevel level = LogLevel.INFO, bool withLevel = true, bool append = true)

        {

            string DatetimeFormat = "yyyy-MM-dd HH:mm:ss.fff";

            string pretext = DateTime.Now.ToString(DatetimeFormat);

            string strLevel = " : ";


            if (withLevel)

            {

                switch (level)

                {

                    case LogLevel.TRACE:

                        strLevel = " [TRACE]   : ";

                        break;

                    case LogLevel.INFO:

                        strLevel = " [INFO]    : ";

                        break;

                    case LogLevel.DEBUG:

                        strLevel = " [DEBUG]   : ";

                        break;

                    case LogLevel.WARNING:

                        strLevel = " [WARNING] : ";

                        break;

                    case LogLevel.ERROR:

                        strLevel = " [ERROR]   : ";

                        break;

                    case LogLevel.FATAL:

                        strLevel = " [FATAL]   : ";

                        break;

                    default: break;

                }

            }


            return WriteLine(filePath, fileName, pretext + strLevel + text);

        }


        /// <summary>

        /// Format a log message based on log level

        /// </summary>

        /// <param name="level">Log level</param>

        /// <param name="text">Log message</param>

        public static async Task<int> WriteLogAsync(string filePath, string fileName, string text, LogLevel level = LogLevel.INFO, bool withLevel = true, bool append = true)

        {

            string DatetimeFormat = "yyyy-MM-dd HH:mm:ss.fff";

            string pretext = DateTime.Now.ToString(DatetimeFormat);

            string strLevel = " : ";


            if (withLevel)

            {

                switch (level)

                {

                    case LogLevel.TRACE:

                        strLevel = " [TRACE]   : ";

                        break;

                    case LogLevel.INFO:

                        strLevel = " [INFO]    : ";

                        break;

                    case LogLevel.DEBUG:

                        strLevel = " [DEBUG]   : ";

                        break;

                    case LogLevel.WARNING:

                        strLevel = " [WARNING] : ";

                        break;

                    case LogLevel.ERROR:

                        strLevel = " [ERROR]   : ";

                        break;

                    case LogLevel.FATAL:

                        strLevel = " [FATAL]   : ";

                        break;

                    case LogLevel.MANNUAL:

                        strLevel = " [MANNUAL] : ";

                        break;

                    default: break;

                }

            }


            return await WriteLineAsync(filePath, fileName, pretext + strLevel + text);

        }

        

        /// <summary>

        /// Write a line of formatted log message into a log file

        /// </summary>

        /// <param name="text">Formatted log message</param>

        /// <param name="append">True to append, False to overwrite the file</param>

        /// <exception cref="System.IO.IOException"></exception>

        private static int WriteLine(string filePath, string fileName, string text, bool append = true)

        {

            int intReturn = 0;


            if (string.IsNullOrEmpty(filePath))

                throw new ArgumentNullException("filePath");


            if (string.IsNullOrEmpty(fileName))

                throw new ArgumentNullException("fileName");


            if (string.IsNullOrEmpty(text))

                throw new ArgumentNullException("text");


            if (!Directory.Exists(filePath))

            {

                Directory.CreateDirectory(filePath);

                Thread.Sleep(100);

            }

            

            fileName = fileName + "_" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";

            filePath = Path.Combine(filePath, fileName);


            text += "\r\n";

            //byte[] buffer = Encoding.Unicode.GetBytes(text);

            byte[] buffer = Encoding.UTF8.GetBytes(text);

            Int32 offset = 0;

            Int32 sizeOfBuffer = 4096;

            //FileStream fileStream = null;


            FileMode fileMode = FileMode.Append;

            if (!append)

                fileMode = FileMode.OpenOrCreate;


            try

            {

                using (FileStream fileStream = new FileStream(filePath, fileMode, FileAccess.Write,

                FileShare.None, bufferSize: sizeOfBuffer, useAsync: true))

                {

                    fileStream.Write(buffer, offset, buffer.Length);

                }


                intReturn = 1;

            }

            catch (Exception ex)

            {

                //Write code here to handle exceptions.

                string strMessage = ex.Message;

            }

            finally

            {

                //if (fileStream != null)

                //    fileStream.Dispose();

            }

            return intReturn;

        }


        static async Task<int> WriteLineAsync(string filePath, string fileName, string text, bool append = true)

        {

            int intReturn = 0;


            if (string.IsNullOrEmpty(filePath))

                throw new ArgumentNullException("filePath");


            if (string.IsNullOrEmpty(fileName))

                throw new ArgumentNullException("fileName");


            if (string.IsNullOrEmpty(text))

                throw new ArgumentNullException("text");


            if (!Directory.Exists(filePath))

            {

                Directory.CreateDirectory(filePath);

                Thread.Sleep(100);

            }


            fileName = fileName + "_" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";

            filePath = Path.Combine(filePath, fileName);


            text += "\r\n";

            //byte[] buffer = Encoding.Unicode.GetBytes(text);

            byte[] buffer = Encoding.UTF8.GetBytes(text);

            Int32 offset = 0;

            Int32 sizeOfBuffer = 4096;

            //FileStream fileStream = null;


            FileMode fileMode = FileMode.Append;

            if (!append)

                fileMode = FileMode.OpenOrCreate;


            try

            {

                using (FileStream fileStream = new FileStream(filePath, fileMode, FileAccess.Write,

                FileShare.None, bufferSize: sizeOfBuffer, useAsync: true)){

                    await fileStream.WriteAsync(buffer, offset, buffer.Length);

                }


                //fileStream = new FileStream(filePath, fileMode, FileAccess.Write,

                //FileShare.None, bufferSize: sizeOfBuffer, useAsync: true);

                //await fileStream.WriteAsync(buffer, offset, buffer.Length);

                intReturn = 1;

            }

            catch(Exception ex)

            {

                //Write code here to handle exceptions.

                string strMessage = ex.Message;

            }

            finally

            {

                //if (fileStream != null)

                //    fileStream.Dispose();

            }

            return intReturn;

        }


    }


사용은 ...


        private async void WriteLog(string anyLocation, string logMessage, LogLevel level = LogLevel.INFO)

        {

            string strRootPath = Application.StartupPath;

            string strPath = Path.Combine(strRootPath, anyLocation+ "_Logs");


            await SystemLogger.WriteLogAsync(strPath, strFileName, logMessage, level);

        }


이렇게 별도의 함수를 만들어 호출하여 사용하면 되겠습니다.

매번 async 를 붙이기도 귀찮더라고요. ^^;


            WriteLog(anyLocation, "Write some Log.");


이제부터는 개떡같이 쓰여졌더라도 찰떡같이 알아 보시는 쎈스를 동원하시면 되겠습니다. 


다른 방법이 있다면 알려주셔요~ ^^



행복한 고수되셔요. ^^


woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\













저작자 표시 비영리 변경 금지
신고

'.NET > C#' 카테고리의 다른 글

[C#] CreateDirectory  (0) 2017.11.15
[C#] Logging on File  (0) 2017.10.24
[C#] How do you check if a file is in use?  (0) 2017.07.27
[C#] 단일 Process 실행  (2) 2010.11.08
[C#] C# 은 VB.NET 따라쟁이...  (3) 2009.05.07
[C#] C# 컴파일러 오류  (0) 2009.03.06
Posted by woojja
2017.10.12 20:00

들어는 보셨을 Log4Net 을 소개해 드립니다.


Web 에서 간단하게 Log 를 쌓을 때 사용하던 녀석입니다.


이번 프로젝트는 WinForm 인데 Log 기능을 넣어달라고 하여 이 녀석을 추가해주려고 합니다.


일단은 파일로만 생성해 주렵니다.

공식웹사이트는 http://logging.apache.org/log4net 이며


GitHub Site 는 https://github.com/apache/logging-log4net/ 입니다.



Project 를 여시고요.

NuGet Manager Console 에서 


Install-Package log4net


이렇게 입력하시면 설치가 간단히 끝납니다.


그 다음은 app.config 또는 Web.config 파일에 Log4Net 을 사용하겠다고 알려주고요.


Log 에 대한 설정 사항을 입력해 주면 됩니다.


별도의 Log4Net.config 파일에 정의해 주어도 되겠습니다.


Log4Net.config 에서 설정을 관리하겠다면 첨부되어 있는 Logger.cs 파일의 initialize() 함수에서 처럼 로그를 관리하는 class 에 아래 구문을 추가해주시고요.


XmlConfigurator.ConfigureAndWatch(new FileInfo(logFilePath));


app.config 나 web.config 을 사용하시겠다면 

assemblyinfo.cs 이나 program.cs 파일에 아래 구문을 입력해 주셔요. ^^


[assembly: log4net.Config.XmlConfigurator(Watch = true)]



다음 설정은 App.Config 에 적어준 사항을 블로그에 맞게 약간 수정해서 기록합니다.


다른 사항들도 빼곡하게 적어 놓았는데 그 사항들을 여러분들이 사용하실때 주석을 풀어 사용하시면 되리라 생각하고 일단은 파일에 Log 를 쌓는 부분만 사용할 수 있게 주석을 풀어 놓았습니다.



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

<configuration>

  <startup> 

    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>

  </startup>

  <runtime>

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

      <probing privatePath="DLL" />

    </assemblyBinding>

  </runtime>


  <configSections>

    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

  </configSections>


  <log4net>


    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">


      <file type="log4net.Util.PatternString" value="Logs/%date{yyyy-MM-dd}_log4net.log"/>

      <datePattern value="yyyy-MM-dd"/>

      <appendToFile value="true" />

      <rollingStyle value="Date" />

      <staticLogFileName value="true" />

      <maxSizeRollBackups value="60" />

      <maximumFileSize value="15MB"/>

      <layout type="log4net.Layout.PatternLayout">

        <conversionPattern value="%d [%t] %-5p %c - %m%n" />

      </layout>


    </appender>

    

    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">

      <bufferSize value="1" />

      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

      <connectionString value="Data Source=DataSourceName;Initial Catalog=DatabaseName;integrated security=True" />

      <commandText value="INSERT INTO SADT_Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />

      <parameter>

        <parameterName value="@log_date" />

        <dbType value="DateTime" />

        <layout type="log4net.Layout.RawTimeStampLayout" />

      </parameter>

      <parameter>

        <parameterName value="@thread" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout">

          <conversionPattern value="%thread" />

        </layout>

      </parameter>

      <parameter>

        <parameterName value="@log_level" />

        <dbType value="String" />

        <size value="50" />

        <layout type="log4net.Layout.PatternLayout">

          <conversionPattern value="%level" />

        </layout>

      </parameter>

      <parameter>

        <parameterName value="@logger" />

        <dbType value="String" />

        <size value="255" />

        <layout type="log4net.Layout.PatternLayout">

          <conversionPattern value="%logger" />

        </layout>

      </parameter>

      <parameter>

        <parameterName value="@message" />

        <dbType value="String" />

        <size value="4000" />

        <layout type="log4net.Layout.PatternLayout">

          <conversionPattern value="%message" />

        </layout>

      </parameter>

      <parameter>

        <parameterName value="@exception" />

        <dbType value="String" />

        <size value="2000" />

        <layout type="log4net.Layout.ExceptionLayout" />

      </parameter>

    </appender>

    

    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">

      <layout type="log4net.Layout.PatternLayout">

        <conversionPattern value="%d [%t] %-5p %c - %m%n" />

      </layout>

    </appender>

    <appender name="OutputDebugStringAppender" type="log4net.Appender.OutputDebugStringAppender">

      <layout type="log4net.Layout.PatternLayout">

        <conversionPattern value="%-5p %m - %c -%n" />

      </layout>

    </appender>

    <appender name="TraceAppender" type="log4net.Appender.TraceAppender">

      <layout type="log4net.Layout.PatternLayout">

        <conversionPattern value="%d [%t] %-5p %c - %m%n" />

      </layout>

    </appender>

    <appender name="AspNetTraceAppender" type="log4net.Appender.AspNetTraceAppender">

      <layout type="log4net.Layout.PatternLayout">

        <conversionPattern value="%d [%t] %-5p %c - %m%n" />

      </layout>

    </appender>


    <root>

      <level value="DEBUG" />


      <appender-ref ref="RollingFileAppender" />


      <!--

      <appender-ref ref="AdoNetAppender" />

      <appender-ref ref="ConsoleAppender" />

      <appender-ref ref="OutputDebugStringAppender" />

      <appender-ref ref="TraceAppender" />

      <appender-ref ref="AspNetTraceAppender" />

      -->

    </root>


  </log4net>

  

</configuration>




내용은 설명을 달아 놓아야 할까 싶을 정도로 간단합니다.

제가 굵게 표시한 글자들만 보셔도 아하~~ 하실거라 생각합니다.


설명을 안할까 생각중인데... 헤헤헤 

에헤~~ 한번 찬찬히 봐 보셔요. ^^

설명 필요없을거예요. 






행복한 고수되셔요. ^^


woojja ))*

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
















저작자 표시 비영리 변경 금지
신고

'Tools' 카테고리의 다른 글

[Tools] GUID Maker Updated.  (0) 2017.10.31
[Tools] Log4Net  (0) 2017.10.12
[Tools] DotNetZip  (0) 2017.10.10
[Tools] 3 Ways to Change Bitrate on MP3 Files  (0) 2017.09.08
[Tools] NShape  (0) 2017.06.28
[Tools] GUID Maker  (0) 2017.06.21
Posted by woojja

티스토리 툴바