DevExpress에서 DxValidationProvider 를 사용하여 유효성 검사를 합니다.

 

using System.Windows.Forms;

using DevExpress.XtraEditors.DXErrorProvider;

namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            #region 유효성 검사 입니다.

            this.dxValidationProvider1.ValidationMode = DevExpress.XtraEditors.DXErrorProvider.ValidationMode.Manual;

            ConditionValidationRule validationRule = new ConditionValidationRule();

            validationRule.ConditionOperator = ConditionOperator.IsNotBlank;
            validationRule.Value1 = "";

            validationRule.ErrorText = "Please enter a value that equals to the first editor's value";
            validationRule.ErrorType = ErrorType.Critical;

            dxValidationProvider1.SetValidationRule(this.textEdit1, validationRule);

            #endregion

            #region 이벤트를 설정합니다.

            this.simpleButton1.Click += SimpleButton1_Click;

            #endregion
        }

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void SimpleButton1_Click(object sender, System.EventArgs e)
        {
            dxValidationProvider1.Validate();
        }
    }
}

폴더 브라우저 출력하기 입니다.

 

using System.Windows.Forms;

namespace Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.buttonEdit1.ButtonClick += buttonEdit1_ButtonClick;
        }

        #region buttonEdit1_ButtonClick() - 버튼 에디트의 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 에디트의 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void buttonEdit1_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            FolderBrowserDialog folderBrowser = new FolderBrowserDialog();

            if(folderBrowser.SelectedPath != null)
            {
                folderBrowser.SelectedPath = this.buttonEdit1.Text;
            }

            if(folderBrowser.ShowDialog() == DialogResult.OK)
            { 
                this.buttonEdit1.Text = folderBrowser.SelectedPath;
            }
        }

        #endregion
    }
}

DevExpress를 사용하여 로컬 드라이브에서 TreeList를 사용하여 디렉토리 구조를 확인할 수 있습니다.

 

예제 결과 입니다.

using System.IO;
using System.Windows.Forms;

using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Columns;
using DevExpress.XtraTreeList.Nodes;

namespace DevTestForm
{
    /// <summary>
    /// 메인폼 클래스 입니다.
    /// </summary>
    public partial class MainForm : Form
    {   
        // Constructor (Public)

        #region MainForm() - 생성자 입니다.

        /// <summary>
        /// 생성자 입니다.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
            InitTreeList();
            InitData();

            #region 이벤트를 설정합니다.

            #endregion
        }

        #endregion

        private void InitTreeList()
        {
            TreeListColumn fullNameColumn = new TreeListColumn();
            TreeListColumn nameColumn     = new TreeListColumn();
            TreeListColumn typeColumn     = new TreeListColumn();
            TreeListColumn sizeColumn     = new TreeListColumn();

            fullNameColumn.Caption   = "FullName";
            fullNameColumn.FieldName = "FullName";

            nameColumn.Caption      = "Name";
            nameColumn.FieldName    = "Name";
            nameColumn.MinWidth     = 27;
            nameColumn.VisibleIndex = 0;
            nameColumn.Width        = 274;

            typeColumn.Caption      = "Type";
            typeColumn.FieldName    = "Type";
            typeColumn.VisibleIndex = 1;
            typeColumn.Width        = 112;

            sizeColumn.AppearanceCell.Options.UseTextOptions = true;
            sizeColumn.AppearanceCell.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Far;
            sizeColumn.Caption                               = "Size(Bytes)";
            sizeColumn.FieldName                             = "Size";
            sizeColumn.Format.FormatType                     = DevExpress.Utils.FormatType.Numeric;
            sizeColumn.Format.FormatString                   = "n0";
            sizeColumn.VisibleIndex                          = 2;
            sizeColumn.Width                                 = 123;

            this.devTreeList.Columns.AddRange(new TreeListColumn[]
            {
                fullNameColumn, nameColumn, typeColumn, sizeColumn
            });

            this.devTreeList.Dock                                   = DockStyle.Fill;
            this.devTreeList.OptionsBehavior.AutoChangeParent       = false;
            this.devTreeList.OptionsBehavior.AutoNodeHeight         = false;
            this.devTreeList.OptionsBehavior.CloseEditorOnLostFocus = false;
            this.devTreeList.OptionsBehavior.Editable               = false;
            this.devTreeList.OptionsBehavior.ShowToolTips           = false;
            this.devTreeList.OptionsBehavior.SmartMouseHover        = false;
            this.devTreeList.OptionsSelection.KeepSelectedOnClick   = false;

            this.devTreeList.StateImageList = this.imageList;

            #region 이벤트를 설정합니다.

            this.devTreeList.AfterCollapse += devTreeList_AfterCollapse;
            this.devTreeList.AfterExpand   += devTreeList_AfterExpand;
            this.devTreeList.BeforeExpand  += devTreeList_BeforeExpand;

            #endregion

        }

        // Event Method (Private)

        #region devTreeList_AfterCollapse(sender, e)

        /// <summary>
        /// 트리리스트의 노드가 접힌 후에 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void devTreeList_AfterCollapse(object sender, NodeEventArgs e)
        {
            if(e.Node.StateImageIndex != 1)
            { 
                e.Node.StateImageIndex = 0;
            }
        }

        #endregion

        #region devTreeList_AfterExpand(sender, e)

        /// <summary>
        /// 트리리스트의 노드가 펼쳐진 후에 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void devTreeList_AfterExpand(object sender, NodeEventArgs e)
        {
            if (e.Node.StateImageIndex != 1)
            {
                e.Node.StateImageIndex = 2;
            }
        }

        #endregion

        #region devTreeList_BeforeExpand(sender, e)

        /// <summary>
        /// 트리리스트의 노드가 펼쳐지기 전에 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void devTreeList_BeforeExpand(object sender, BeforeExpandEventArgs e)
        {
            if(e.Node.Tag != null)
            { 
                Cursor currentCursor = Cursor.Current;
                Cursor.Current = Cursors.WaitCursor;
                InitFolders(e.Node.GetDisplayText("FullName"), e.Node);
                e.Node.Tag = null;
                Cursor.Current = currentCursor;
            }
        }

        #endregion

        #region InitData() - 데이터를 초기화합니다.

        /// <summary>
        /// 데이터를 초기화합니다.
        /// </summary>
        private void InitData()
        { 
            InitFolders(Directory.GetDirectoryRoot(Directory.GetCurrentDirectory()), null);
        }

        #endregion

        #region InitFolders(path, node) - 폴더를 초기화 합니다.

        /// <summary>
        /// 폴더를 초기화 합니다.
        /// </summary>
        /// <param name="path">경로 입니다.</param>
        /// <param name="node">노드 입니다.</param>
        private void InitFolders(string path, TreeListNode node)
        {
            this.devTreeList.BeginUnboundLoad();
            
            TreeListNode treeListNode;
            DirectoryInfo directoryInfo;

            try
            {
                string[] root = Directory.GetDirectories(path);

                foreach(string item in root)
                {
                    try
                    {
                        directoryInfo = new DirectoryInfo(item);
                        treeListNode                 = this.devTreeList.AppendNode
                        (
                            new object[] { item, directoryInfo.Name, "Folder", null }, node
                        );
                        treeListNode.StateImageIndex = 0;
                        treeListNode.HasChildren     = HasFiles(item);

                        if (treeListNode.HasChildren)
                        {
                            treeListNode.Tag = true;
                        }
                    }
                    catch{ }
                    
                }
            }
            catch{ }

            InitFiles(path, node);
            this.devTreeList.EndUnboundLoad();
        }

        #endregion

        #region InitFiles(path, node) - 파일을 초기화 합니다.

        /// <summary>
        /// 파일을 초기화 합니다.
        /// </summary>
        /// <param name="path">경로 입니다.</param>
        /// <param name="node">노드 입니다.</param>
        private void InitFiles(string path, TreeListNode node)
        {
            TreeListNode treeListNode;

            FileInfo fileInfo;

            try
            {
                string[] root = Directory.GetFiles(path);

                foreach(string item in root)
                {
                    fileInfo = new FileInfo(item);

                    treeListNode                 = this.devTreeList.AppendNode
                    (
                        new object[] { item, fileInfo.Name, "File", fileInfo.Length }, node
                    );

                    treeListNode.StateImageIndex = 1;
                    treeListNode.HasChildren     = false;
                }
            }
            catch { }
        }

        #endregion

        #region HasFiles(path) - 파일의 존재 여부를 확인합니다.

        /// <summary>
        /// 파일의 존재 여부를 확인합니다.
        /// </summary>
        /// <param name="path">경로 입니다.</param>
        /// <returns>파일 유무를 리턴합니다.</returns>
        private bool HasFiles(string path)
        {
            string[] root = Directory.GetFiles(path);

            if(root.Length > 0)
            { 
                return true;
            }

            root = Directory.GetDirectories(path);

            if(root.Length > 0)
            { 
                return true;
            }

            return false;
        }

        #endregion
    }
}

DevExpress에서 TreeList에서 노드 추가하기 입니다.

 

TreeList에서 노드 추가한 결과 입니다.

using System.Windows.Forms;

using DevExpress.XtraEditors;
using DevExpress.XtraLayout;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Columns;
using DevExpress.XtraTreeList.Nodes;

namespace DevTestForm
{
    /// <summary>
    /// 메인폼 클래스 입니다.
    /// </summary>
    public partial class MainForm : Form
    {   
        // Constructor (Public)

        #region MainForm() - 생성자 입니다.

        /// <summary>
        /// 생성자 입니다.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            CreateColumns(this.devTreeList);
            CreateNodes(this.devTreeList);

            #region 이벤트를 설정합니다.

            #endregion
        }

        #endregion


        #region CreateColumns(treeList) - 컬럼을 생성합니다.

        /// <summary>
        /// 컬럼을 생성합니다.
        /// </summary>
        /// <param name="treeList">TreeList 입니다.</param>
        private void CreateColumns(TreeList treeList)
        { 
            treeList.BeginUpdate();

            TreeListColumn column1 = treeList.Columns.Add();
            column1.Caption      = "Customer";
            column1.VisibleIndex = 0;

            TreeListColumn column2 = treeList.Columns.Add();
            column2.Caption      = "Location";
            column2.VisibleIndex = 1;

            TreeListColumn column3 = treeList.Columns.Add();
            column3.Caption      = "Phone";
            column3.VisibleIndex = 2;

            treeList.EndUpdate();
        }

        #endregion

        #region CreateNodes(treeList)

        /// <summary>
        /// 노드를 생성합니다.
        /// </summary>
        /// <param name="treeList">TreeList 입니다.</param>
        private void CreateNodes(TreeList treeList)
        { 
            treeList.BeginUnboundLoad();

            TreeListNode parentForRootNodes = null;
            TreeListNode rootNode = treeList.AppendNode
            (
                new object[]{"AAAAAA", "BBBBBB", "000-0000-0000"}, parentForRootNodes
            );

            treeList.AppendNode
            (
                new object[] { "CCCCCC", "DDDDDDD", "1111-1111-1111" }, rootNode
            );

            treeList.AppendNode
            (
                new object[] { "ABB", "ADDADA", "222-2222-1111" }, rootNode
            );

            treeList.EndUnboundLoad();
        }

        #endregion

    }
}

DevExpress로 탭 그룹을 생성하는 코드 입니다.

 

탭 그룹 생성 예제

 

using System.Windows.Forms;

using DevExpress.XtraEditors;
using DevExpress.XtraLayout;

namespace DevTestForm
{
    /// <summary>
    /// 메인폼 클래스 입니다.
    /// </summary>
    public partial class MainForm : Form
    {   
        // Constructor (Public)

        #region MainForm() - 생성자 입니다.

        /// <summary>
        /// 생성자 입니다.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            CreateTabGroup();

            #region 이벤트를 설정합니다.

            #endregion
        }

        #endregion

        #region CreateTabGroup() - 탭 그룹을 생성합니다.

        /// <summary>
        /// 탭 그룹을 생성합니다.
        /// </summary>
        private void CreateTabGroup()
        { 
            LayoutControl layoutControl = new LayoutControl();

            layoutControl.Dock = DockStyle.Fill;
            this.Controls.Add(layoutControl);

            layoutControl.BeginUpdate();

            try
            {
                // 루트 그룹에 탭 그룹을 생성합니다.
                TabbedControlGroup tabbedGroup = layoutControl.Root.AddTabbedGroup();
                tabbedGroup.Name = "TabbedGroup";

                // 하나의 탭에 사진 그룹을 추가합니다.
                LayoutControlGroup groupImage = tabbedGroup.AddTabPage() as LayoutControlGroup;
                groupImage.Name = "layoutGroupPhoto";
                groupImage.Text = "Photo";

                // 이미지 그룹에 이미지가 출력되도록 레이아웃 아이템을 추가합니다.
                LayoutControlItem layoutItemImage = groupImage.AddItem();
                layoutItemImage.Name        = "layoutItemPhoto";
                layoutItemImage.Control     = new PictureEdit(){ Name = "pictureEdutPhoto"};
                layoutItemImage.TextVisible = false;

                // 하나의 탭에 노트 그룹을 추가합니다.
                LayoutControlGroup groupNotes = tabbedGroup.AddTabPage() as LayoutControlGroup;
                groupNotes.Name = "layoutGroupNotes";
                groupNotes.Text = "Notes";

                // 노트 그룹에 노트가 출력되도록 레이아웃 아이템을 추가합니다.
                LayoutControlItem layoutItemNotes = groupNotes.AddItem();
                layoutItemNotes.Name        = "layoutItemNotes";
                layoutItemNotes.Control     = new MemoEdit(){ Name = "memoEditNotes"};
                layoutItemNotes.TextVisible = false;

                // 첫번째 탭이 출력됩니다.
                tabbedGroup.SelectedTabPage = groupImage;
            }
            finally
            {
                layoutControl.EndUpdate();
            }

        }

        #endregion
    }
}

입력된 URL을 얼마만에 받을 수 있는지 확인하는 예제 입니다.

 

한 버튼은 동기 방식으로 동작을 하고

 

다른 한 버튼은 비동기 방식 및 병렬 처리를 하여 동작을 합니다.

 

동기 방식일 경우에는 시간도 오래 걸리고 버튼 클릭 시 다른 UI들이 반응을 하지 않지만

 

비동기 방식일 경우에는 시간도 단축되며 버튼 클릭 하여도 다른 UI들의 동작도 가능합니다.

 

실행 예제 입니다.

 

비동기 호출의 병렬 처리 하기 입니다.

 

아래의 예제는 병렬 처리 하기 전입니다.

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace TaskSample
{
    class Program
    {

        static void Main(string[] args)
        {
            int result3 = Method3();
            int result5 = Method5();

            Console.WriteLine(result3 + result5);
        }

        private static int Method3()
        {
            Thread.Sleep(3000); // 3초가 걸리는 작업을 대신해서 sleep 처리
            return 3;
        }

        private static int Method5()
        {
            Thread.Sleep(5000); // 5초가 걸리는 작업을 대신해서 sleep 처리
            return 5;
        }
    }
}

 

병렬로 처리 했을 경우 8초 걸릴 작업을 5초로 줄일 수 있습니다.

아래의 예제는 병렬 처리 방식이며 Task<TResult> 타입으로 구현한 예제 입니다.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskSample
{
    class Program
    {

        static void Main(string[] args)
        {
            // Task를 이용해 병렬로 처리하기
            var task3 = Method3Async();
            var task5 = Method5Async();

            // task3 작업과 task5 작업이 완료될 때까지 현재 스레드를 대기
            Task.WaitAll(task3, task5);

            Console.WriteLine(task3.Result + task5.Result);
        }

        private static Task<int> Method3Async()
        { 
            return Task.Factory.StartNew(() =>
            { 
                Thread.Sleep(3000);

                return 3;
            });
        }

        private static Task<int> Method5Async()
        {
            return Task.Factory.StartNew(() =>
            {
                Thread.Sleep(5000);

                return 5;
            });
        }
    }
}

위의 예제는 모든 작업이 완료 될때까지 대기를 해야합니다.

 

Task<TResult>와 await을 사용하여 동시에 비동기 호출로 처리할 수 있습니다.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskSample
{
    class Program
    {
        static void Main(string[] args)
        {
            // await을 이용하여 병렬로 비동기 호출: 5초 소요됨.
            DoAsyncTask();
            
            Console.ReadLine();
        }

        private static async Task DoAsyncTask()
        {
            var task3 = Method3Async();
            var task5 = Method5Async();

            await Task.WhenAll(task3, task5);

            Console.WriteLine(task3.Result + task5.Result);
        }

        private static Task<int> Method3Async()
        { 
            return Task.Factory.StartNew(() =>
            { 
                Thread.Sleep(3000);

                return 3;
            });
        }

        private static Task<int> Method5Async()
        {
            return Task.Factory.StartNew(() =>
            {
                Thread.Sleep(5000);

                return 5;
            });
        }
    }
}

ReadAllText 메서드를 비동기로 처리하기 입니다.

 

별도의 스레드를 이용하거나 델리게이트의 BeginInvoke로 처리하여 비동기를 적용하는 예제입니다.(복잡함)

using System;
using System.IO;

namespace TaskSample
{
    class Program
    {
        public delegate string ReadAllTextDelegate(string path);

        static void Main(string[] args)
        {
            string filePath = @"C:\windows\system32\drivers\etc\HOSTS";

            ReadAllTextDelegate func = File.ReadAllText;
            func.BeginInvoke(filePath, actionCompleted, func);

            Console.ReadLine();
        }

        static void actionCompleted(IAsyncResult asyncResult)
        {
            ReadAllTextDelegate func = asyncResult.AsyncState as ReadAllTextDelegate;
            string fileText = func.EndInvoke(asyncResult);

            Console.WriteLine(fileText);
        }
    }
}


위의 예제를 Task<TResult>로 바꾸면 await을 이용하여 쉽게 비동기 호출을 적용할 수 있습니다.

 

Async 메서드로 제공되지 않은 모든 동기 방식의 메서드를 비동기로 변환 가능합니다.

using System;
using System.IO;
using System.Threading.Tasks;

namespace TaskSample
{
    class Program
    {
        public delegate string ReadAllTextDelegate(string path);

        static void Main(string[] args)
        {
            string filePath = @"C:\windows\system32\drivers\etc\HOSTS";

            AwaitFileRead(filePath);

            Console.ReadLine();
        }

        static Task<string> ReadAllTextAsync(string filePath)
        {
            return Task.Factory.StartNew(() =>
            {
                return File.ReadAllText(filePath);
            });
        }

        private static async Task AwaitFileRead(string filePath)
        {
            string fileText = await ReadAllTextAsync(filePath);

            Console.WriteLine(fileText);
        }
    }
}

 

await 없이 Task타입을 단독으로 사용하는 예제 입니다.

 

Task 타입은 반환값이 없는 경우 사용되며,

Task<TResult> 타입은 TResult 형식 매개 변수로 지정된 반환값이 있는 경우로 구분됩니다.

 

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskSample
{
    class Program
    {
        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem((obj) =>
            {
                Console.WriteLine("process workItem");
            }, null);

            Task task1 = new Task(() =>
            {
                Console.WriteLine("Process taskItem");
            });

            task1.Start();

            Task task2 = new Task((obj) =>
            {
                Console.WriteLine("process taskItem(obj)");
            }, null);

            task2.Start();

            Console.ReadLine();
        }
    }
}

 

네이버 Open API 이용하여 로그인 및 접근 토큰 / 인증코드 / 상태 코드 구하기 입니다.

 

 

using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Web;
using System.Windows.Forms;

namespace NaverLogin
{
    /// <summary>
    /// 메인폼 클래스 입니다.
    /// </summary>
    public partial class MainForm : Form
    {
        #region MainForm() - 생성자 입니다.

        /// <summary>
        /// 생성자 입니다.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            #region 이벤트를 설정합니다.

            this.naverLoginButton.Click         += naverLoginButton_Click;
            this.callBackButton.Click           += callBackButton_Click;
            this.accessTokenRequestButton.Click += accessTokenRequestButton_Click;
            this.accessTokenDeleteButton.Click  += accessTokenDeleteButton_Click;

            #endregion
        }

        #endregion

        // Event Method (Private)

        #region naverLoginButton_Click() - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void naverLoginButton_Click(object sender, EventArgs e)
        {
            string clientID    = "클라이언트 아이디";
            string redirectURL = "등록한 리다이렉트 주소";

            string state       = (new Random()).Next().ToString();

            NameValueCollection listAuthURL_QueryString = HttpUtility.ParseQueryString(string.Empty);

            listAuthURL_QueryString["response_type"] = "code";
            listAuthURL_QueryString["client_id"    ] = clientID;
            listAuthURL_QueryString["redirect_uri" ] = redirectURL;
            listAuthURL_QueryString["state"        ] = state;

            string autoURL = "https://nid.naver.com/oauth2.0/authorize?" + listAuthURL_QueryString.ToString();

            this.naverLoginWebBrowser.Navigate(new Uri(autoURL));
        }

        #endregion
        #region callBackButton_Click() - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void callBackButton_Click(object sender, EventArgs e)
        {
            NameValueCollection query = HttpUtility.ParseQueryString(this.naverLoginWebBrowser.Url.Query);

            this.resultRichTextBox.Text += "콜백 URL 인증 정보 : " + query.ToString() + Environment.NewLine;
        }

        #endregion
        #region accessTokenRequestButton_Click() - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void accessTokenRequestButton_Click(object sender, EventArgs e)
        {
            string clientID     = "클라이언트 아이디";
            string clientSecret = "Client Secret 입니다.";
            string authCode     = this.authCodeTextBox.Text;
            string authState    = this.authStateCodeTextBox.Text;

            WebClient webClient;

            string accessToken_URL = "https://nid.naver.com/oauth2.0/token";

            webClient = new WebClient();

            webClient.QueryString.Add("grant_type"   , "authorization_code");
            webClient.QueryString.Add("client_id"    , clientID            );
            webClient.QueryString.Add("client_secret", clientSecret        );
            webClient.QueryString.Add("code"         , authCode            );
            webClient.QueryString.Add("state"        , authState           );

            Stream stream = webClient.OpenRead(accessToken_URL);

            string resultJson = new StreamReader(stream).ReadToEnd();

            this.resultRichTextBox.Text += "접속 토큰 요청 결과 : " + Environment.NewLine;
            this.resultRichTextBox.Text += resultJson + Environment.NewLine;

        }

        #endregion

        #region accessTokenDeleteButton_Click() - 버튼 클릭시 동작합니다.

        /// <summary>
        /// 버튼 클릭시 동작합니다.
        /// </summary>
        /// <param name="sender">이벤트 발생자 입니다.</param>
        /// <param name="e">이벤트 인자 입니다.</param>
        private void accessTokenDeleteButton_Click(object sender, EventArgs e)
        {
            string clientID        = "클라이언트 아이디";
            string clientSecret    = "Client Secret 입니다.";
            string accessToken     = this.accessCodeTextBox.Text;
            string serviceProvider = "NAVER";

            WebClient webClient;

            string accessToken_URL = "https://nid.naver.com/oauth2.0/token";

            webClient = new WebClient();

            webClient.QueryString.Add("grant_type"      , "delete"       );
            webClient.QueryString.Add("client_id"       , clientID       );
            webClient.QueryString.Add("client_secret"   , clientSecret   );
            webClient.QueryString.Add("access_token"    , accessToken    );
            webClient.QueryString.Add("service_provider", serviceProvider);

            Stream stream = webClient.OpenRead(accessToken_URL);

            string resultJson = new StreamReader(stream).ReadToEnd();

            this.resultRichTextBox.Text += "접속 토큰 삭제 결과 : " + resultJson + Environment.NewLine;
        }

        #endregion

    }
}

+ Recent posts