728x90

Web 로그인 화면을 띄우고 ID 와 PW를 입력하고 클릭하면 로그인된 화면이 보일 것이다.

이 기능을 C#에서 처리하는 방법이다.

아주 간단하게 기능만 테스트 해 본 거라 username 과 password 를 직접 입력하는 방식으로 구현해봤지만 자동로그인하면서 저장한 값을 불러다가 처리하는 것이 좋을 듯하다.


webBrowser1.Document.GetElementById("username").InnerText = "xxxxx";

대신에

webBrowser1.Document.GetElementById("username").SetAttribute("value", "xxxxx") ;

를 해도 결과는 동일하다.


InvokeMember("click") : 스크립트 언어로 현재 HTML 페이지에 정의된 함수를 실행한다.

WebBrowser 로딩이 끝났을 때 실행해야 한다.


webBrowser1_DocumentCompleted 메소드는 브라우져에 웹페이지가 모두 Load 되었을 때 발생하는 이벤트다.

이것과 동일하게 처리하는 것이

while (webBrowser1.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)
{
    Application.DoEvents();
}


Web 화면을 읽어오고 나서 Loading 이 완전히 끝나지 않은 상태에서 값을 전달하면 null 에러가 발생한다.



private void Form1_Load(object sender, EventArgs e)
{
   // From Web
    var url = "http://aaa.com/?r=home&system=iframe.login&iframe=Y&referer=%2F%3F";
    webBrowser1.Navigate(url);
    webBrowser1.ScriptErrorsSuppressed = true;
    while (webBrowser1.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)
    {
        Application.DoEvents();
    }


    HtmlDocument doc = webBrowser1.Document;

    doc.GetElementById("username").InnerText = "xxxxx";
    doc.GetElementById("password").InnerText = "yyyyy";
    // 특정 엘리먼트를 호출하여 이벤트 처리
    webBrowser1.Document.GetElementById("login_btn").InvokeMember("click");

}

private void SuppressScriptErrorsOnly(WebBrowser browser)
{
    // Ensure that ScriptErrorsSuppressed is set to false.
    browser.ScriptErrorsSuppressed = false;

    // Handle DocumentCompleted to gain access to the Document object.
    browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(
            webBrowser1_DocumentCompleted);
}

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    ((WebBrowser)sender).Document.Window.Error +=  new HtmlElementErrorEventHandler(Window_Error);          
}

private void Window_Error(object sender, HtmlElementErrorEventArgs e)
{
    // Ignore the error and suppress the error dialog box.
    e.Handled = true;
}


참고하면 도움될 사이트

https://stackoverflow.com/questions/32904235/c-sharp-get-element-by-name


https://stackoverflow.com/questions/16787495/click-on-html-element-by-class-using-webbrowser-c-sharp


https://ddingjo.blogspot.kr/2017/04/c-html.html

'C# > 통신' 카테고리의 다른 글

C# 과 Web  (0) 2018.03.10
C# Web 접속 로그인함수 만들기(HttpClient 방식)  (0) 2016.11.14
C# webFile 다운로드 함수  (0) 2016.11.12
C# GetAsyncDataFromWeb  (0) 2016.08.21
C# GetDataFromWeb 사용자 함수  (0) 2016.08.20
블로그 이미지

Link2Me

,

C# 과 Web

C#/통신 2018. 3. 10. 15:11
728x90

C# 에서 Web 페이지를 보여주는 코드다.

일부 jQuery 로 된 것을 읽어오지 못하는 것이 있기는 하지만 로그인처리라든가 이런것은 전부 잘 된다.


도구상자 => 공용콘트롤 => Webbrowser 를 선택하여 Form 에 Drop & Drop 한다.



private void Form1_Load(object sender, EventArgs e)
{

   // 폼 크기를 풀스크린으로
   FormBorderStyle = FormBorderStyle.Sizable;
   WindowState = FormWindowState.Maximized;

   // From Web
    var url = "http://aaa.com/";
    webBrowser1.Navigate(url);
    webBrowser1.ScriptErrorsSuppressed = true;
}

private void SuppressScriptErrorsOnly(WebBrowser browser)
{
    // Ensure that ScriptErrorsSuppressed is set to false.
    browser.ScriptErrorsSuppressed = false;

    // Handle DocumentCompleted to gain access to the Document object.
    browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(
            webBrowser1_DocumentCompleted);
}

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    ((WebBrowser)sender).Document.Window.Error +=  new HtmlElementErrorEventHandler(Window_Error);
}

private void Window_Error(object sender, HtmlElementErrorEventArgs e)
{
    // Ignore the error and suppress the error dialog box.
    e.Handled = true;
}

'C# > 통신' 카테고리의 다른 글

C# Web 자동로그인 처리  (1) 2018.03.15
C# Web 접속 로그인함수 만들기(HttpClient 방식)  (0) 2016.11.14
C# webFile 다운로드 함수  (0) 2016.11.12
C# GetAsyncDataFromWeb  (0) 2016.08.21
C# GetDataFromWeb 사용자 함수  (0) 2016.08.20
블로그 이미지

Link2Me

,
728x90

C# 에서 Web 접속방식으로 로그인 처리를 위한 방법을 소개한다.


http://link2me.tistory.com/970 에 기본적인 사항을 적어두었다.


HttpClient 방식으로 로그인하는 방법을 알아두면 여러모로 유용하다.

로그인 뿐만 아니라 Web 접속방식으로 데이터를 주고 받을 때 많이 활용된다.

json 형태로 데이터를 주고 받기 위한 함수만 추가로 만들어서 사용하면 된다.


string json 부분을 보면 PHP 로그인 함수 결과값을 받는다.

PHP 에서 도대체 어떤 걸 받는거지? 라고 하는 의문이 들 것이다.

PHP 결과를 받는 것은 echo 문의 결과값이다.

이 결과값이 배열일 수도 있고 단순한 텍스트일 수도 있다.

echo 문으로 출력되는 결과를 어떻게 만들 것인가 하는 것은 PHP 에서 고민하면 된다.

가령 성공하면 1, 실패하면 0, DB접속 실패하면 -1 이런식으로 PHP 로그인 함수를 만들어도 된다.

개발자의 취향에 따라 개발해서 연동하면 된다.


=== LoginForm.cs ====

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Http;
using System.Web.Script.Serialization;
using System.IO;
using System.Configuration;

namespace Dennis_Sentence
{
    public partial class frmLogin : Form
    {
        Boolean CK = false;
        private string strID;

        public frmLogin()
        {
            InitializeComponent();
        }

        public string getstrID   // ID를 알려주는 속성 설정
        {
            get { return strID; }
        }

        private void frmLogin_Load(object sender, EventArgs e)
        {
            txtID.Text = Properties.Settings.Default.LoginIDSave;
            txtPwd.Text = Properties.Settings.Default.SitePasswd;
            if (Properties.Settings.Default.LoginIDSave.Length > 0 && Properties.Settings.Default.SitePasswd.Length > 0)
            {
                IDSave.Visible = false;
                IDdelete.Visible = true;
            }
            else
            {
                IDSave.Visible = true;
                IDdelete.Visible = false;
            }
        }

        /// <summary>
        /// SQL 인젝션 필터 - Select 에서 조건절 필터링
        /// </summary>
        private static string Filtering(string inputSQL)
        {
            return inputSQL.Replace(":", "").Replace("+", "").Replace(";", "").Replace("--", "").Replace("\"", "");
        }

        private void frmLogin_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!CK)
            {
                Application.Exit();
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {

            if (this.txtID.Text == "")
            {
                MessageBox.Show("로그인 아이디를 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.txtID.Focus();
            }
            else if (this.txtPwd.Text == "")
            {
                MessageBox.Show("로그인 비밀번호를 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.txtPwd.Focus();
            }
            else
            {
                if (IDSave.Checked)
                {
                    Properties.Settings.Default.LoginIDSave = txtID.Text;
                    Properties.Settings.Default.SitePasswd = txtPwd.Text;
                    Properties.Settings.Default.Save();
                }

                if (IDdelete.Checked)
                {
                    Properties.Settings.Default.LoginIDSave = string.Empty;
                    Properties.Settings.Default.SitePasswd = string.Empty;
                    Properties.Settings.Default.Save();
                }

                mySqlLogin();
            }

        }

        private void mySqlLogin()
        {
            try
            {
                var client = new HttpClient();
                var postData = new List<KeyValuePair<string, string>>();
                string URL = "http://IP주소/Login.php";
                postData.Add(new KeyValuePair<string, string>("loginID", Filtering(txtID.Text.Trim())));
                postData.Add(new KeyValuePair<string, string>("loginPW", Filtering(txtPwd.Text.Trim())));
                var formContent = new FormUrlEncodedContent(postData);
                var result = client.PostAsync(URL, formContent).Result;
                string json = result.Content.ReadAsStringAsync().Result;
                //MessageBox.Show(json);
                if (json == "1") // PHP 로그인 함수에서 로그인 성공시의 echo 결과값
                {
                    CK = true;
                    strID = txtID.Text;
                    this.Close();  // 현재 폼 닫기
                }
                else
                {
                    MessageBox.Show("로그인 실패", "Login Fail", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    CK = false;
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error :" + ex.Message);
            }
        }       

        private void btnCancel_Click(object sender, EventArgs e)
        {
            //CK = false;
            Application.Exit();  // 취소버튼을 누르면 프로그램 완전 종료 처리
        }

        private void txtPwd_KeyDown(object sender, KeyEventArgs e)  // 엔터키를 눌렀다면...
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnOK_Click(sender, e);
            }
        }

        private void IDSave_CheckedChanged(object sender, EventArgs e)
        {
            if (IDdelete.Checked == true)
            {
                IDdelete.Checked = false;
            }
        }

        private void IDdelete_CheckedChanged(object sender, EventArgs e)
        {
            if (IDSave.Checked == true)
            {
                IDSave.Checked = false;
            }
        }
    }
       
}


=== Login.php ===

<?php
session_start();
@extract($_POST);
if(isset($loginID) && !empty($loginID) && isset($loginPW) && !empty($loginPW)) {

    require_once 'phpclass/dbinfo.php';
    require_once 'phpclass/dbClass.php';
    $conn=new MySQLDbClass(); // DB 함수 객체 생성
    $DB_CONNECT = $conn->isConnectDb($DB); // 안드로이드폰에서는 반드시 객체로 생성해야 정상접속
    require_once 'phpclass/loginClass.php';
    $c=new LoginClass(); // 로그인 객체 생성

    $row = $c->WebUserAuthCheck($loginID,$loginPW);  // 로그인 체크 함수
    if(is_array($row)) {
        if(!empty($row['id'])) {
            $_SESSION['userID'] = $row['id'];
            echo 1; // 로그인 성공
        } else {
            echo 0; // 로그인 실패
        }
    } else if($row == '0'){
        echo 0; // 로그인 실패
    } else {
        echo 0; // 로그인 실패
    }

}
?>


도움이 되셨다면 00 00 해 주세요. 좋은 글 작성에 큰 도움이 됩니다.

'C# > 통신' 카테고리의 다른 글

C# Web 자동로그인 처리  (1) 2018.03.15
C# 과 Web  (0) 2018.03.10
C# webFile 다운로드 함수  (0) 2016.11.12
C# GetAsyncDataFromWeb  (0) 2016.08.21
C# GetDataFromWeb 사용자 함수  (0) 2016.08.20
블로그 이미지

Link2Me

,
728x90

C#에서 Web 방식으로 파일을 다운로드하는 코드이다.

오래되어 기억은 가물가물하지만 구글링도하고 블로그 검색으로 찾은 걸 약간 수정한거 같기는 하다.

최근에 SSD 이상증상으로 데이터를 살리지 못한 경험도 있고 해서 블로그에 기록해둔다.


사용법 예시

사용법 예시는 전체적으로 동작되는 걸 보여주는게 아니라 이런식으로 활용할 수 있다는 것만 간략하게 기록


private void webFileDown(string mp3sub, string mp3file)
{
    // 파일 다운로드
    string webfilePath = string.Format("http://ipaddress/{0}/{1}", mp3folder, mp3file);
    string localfilePath = Folder.MyfilePath("abcdef", mp3file);
    if (webFile.WebExists(webfilePath))
    {
        int write = webFile.DownloadFile(webfilePath, localfilePath);  // 파일 사이즈를 반환
    }
    else
    {
        MessageBox.Show("다운받을 파일이 존재하지 않습니다");
        return;
    }
}             



코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Windows.Forms;

namespace NameSpace  // 수정해서 사용 필요
{
    class webFile
    {
        /// <summary>
        /// 웹파일 다운로드
        /// </summary>
        /// <param name="remoteFilename">웹 서버 파일</param>
        /// <param name="localFilename">PC 저장 파일</param>
        /// <returns>파일 크기를 반환</returns>
        public static int DownloadFile(String remoteFilename, String localFilename)
        {
            // Function will return the number of bytes processed to the caller. Initialize to 0 here.
            int bytesProcessed = 0;

            // Assign values to these objects here so that they can be referenced in the finally block
            Stream remoteStream = null;
            Stream localStream = null;
            WebResponse response = null;

            // Use a try/catch/finally block as both the WebRequest and Stream classes throw exceptions upon error
            try
            {
                WebRequest request = WebRequest.Create(remoteFilename); // 원격 파일 다운을 위한 객체 생성
                if (request != null)
                {
                    response = request.GetResponse(); // 서버로부터 WebResponse 오브젝트 받아옴
                    if (response != null)
                    {
                        // Once the WebResponse object has been retrieved, get the stream object associated with the response's data
                        remoteStream = response.GetResponseStream();
                        //localStream = File.Create(localFilename);  // local File 생성
                        localStream = new FileStream(localFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                        byte[] buffer = new byte[1024];  // 1k 버퍼 할당
                        int bytesRead;

                        // Simple do/while loop to read from stream until no bytes are returned
                        do
                        {
                            bytesRead = remoteStream.Read(buffer, 0, buffer.Length); // 1K 바이트씩 데이터 읽기
                            localStream.Write(buffer, 0, bytesRead); // PC에 데이터 저장
                            bytesProcessed += bytesRead;  // 전체 바이트 수 체크를 위해 누적
                        } while (bytesRead > 0);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (response != null) response.Close(); //WebResponse객체 Close
                if (remoteStream != null) remoteStream.Close();
                if (localStream != null) localStream.Close();
            }

            return bytesProcessed;  // 수신한 전체 바이트수를 리턴(파일의 크기)
        }

        /// <summary>
        /// 웹에 파일이 존재하는지 검사하여 있으면 true 반환
        /// </summary>
        /// <param name="url">Web 파일 경로</param>
        /// <returns></returns>
        public static bool WebExists(string url)
        {
            bool ret = true;
            if (url == null)
                return false;
            HttpWebResponse response = null;
            try
            {
                var request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "HEAD";
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException)
            {
                ret = false;
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
            return ret;
        }


    }
}


'C# > 통신' 카테고리의 다른 글

C# 과 Web  (0) 2018.03.10
C# Web 접속 로그인함수 만들기(HttpClient 방식)  (0) 2016.11.14
C# GetAsyncDataFromWeb  (0) 2016.08.21
C# GetDataFromWeb 사용자 함수  (0) 2016.08.20
C# comboBox 에 Text, Value 추가 및 POST, JSON  (0) 2016.08.19
블로그 이미지

Link2Me

,

C# GetAsyncDataFromWeb

C#/통신 2016. 8. 21. 23:36
728x90

HttpWebRequest 방식으로는 데이터를 가져오는 크기에 한도가 있는 거 같다.

아래 방식으로 하면 데이터를 많이 가져온다.


// GET 방식으로 Web 에 있는 데이터를 가져온다.

void GetAsyncDataFromWeb(string url)
{
    var client = new HttpClient();
    var response = client.GetAsync(url).Result;
    string resultContent = response.Content.ReadAsStringAsync().Result;
}



// POST 방식으로 Web 에 있는 데이터를 가져온다.

void GetAsyncDataFromWeb(string url)
{
    var client = new HttpClient();
    var postData = new List<KeyValuePair<string, string>>();
    postData.Add(new KeyValuePair<string, string>("UserName", "Grace"));
    postData.Add(new KeyValuePair<string, string>("userID ", "12345"));
    var formContent = new FormUrlEncodedContent(postData);

    var response = client.PostAsync(url, formContent).Result;
    string resultContent = response.Content.ReadAsStringAsync().Result;
}


postData 값을 넘기는 방법은 여러가지가 있다.

http://stackoverflow.com/questions/3001108/namevaluecollection-vs-dictionarystring-string

에 Dictionary<string,string> 와 NameValueCollection 차이점에 대한 문의 내용인데 간략한 답변이 나온다.

블로그 이미지

Link2Me

,
728x90

스승도 없이 독학으로 취미로 프로그램을 배우다보니 막히면 중단되고 방법을 찾으면 약간 진도가 나간다.

배우면서 느끼는 것은 기본기가 중요하다는 점이다.

기능 검색하다가 우연히 http://raago.tistory.com/20 에서 함수명을 직관적으로 이해되게 작성하는 것이 정말 중요하다는 걸 새삼 느꼈다.

앞으로는 자료 검색을 하더라도 허투루 보지 않고 응용해서 내것으로 만들어야겠다.


자료 검색을 하면 대부분 POST 처리 부분이 좀 부족하게 검색된다.

POST 데이터 입력부분까지 고려해서 만들었다.

서버에서 던져주는 결과를 가져오는 함수니까 GetDataFromWeb 으로 하면 맞다.

결과 형식이 JSON이면 Deserialize 하는 것은 별도로 처리해야 한다.


string GetJDataFromWeb(string url, string postData)
 {
     try
     {
         var webRequest = (HttpWebRequest)WebRequest.Create(url);

         if (postData != null)
         {
             webRequest.Method = "POST";
             byte[] sendData = UTF8Encoding.UTF8.GetBytes(postData);
             webRequest.ContentType = "application/x-www-form-urlencoded";
             webRequest.ContentLength = sendData.Length;

             Stream dataStream = webRequest.GetRequestStream();
             dataStream.Write(sendData, 0, sendData.Length);
             dataStream.Close();
         }

         var webResponse = (HttpWebResponse)webRequest.GetResponse();
         if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
         {
             var readStrem = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8, true);

             string reader = readStream.ReadToEnd().Trim();

             readStrem.Close();

             webResponse.Close();

             return @reader.ReadToEnd().Trim();
         }
         else
         {
             MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode));
             return null;
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
         return null;
     }
 }


파일을 첨부하는 경우는 테스트를 못해봤지만, 파일 첨부한 경우에는 별도 함수를 만들어야 할 것으로 예상된다.


가져온 데이터 형식이 JSON String 인 경우 이 문자열을 Deserialize 하는 함수 부분은

string URL = "http://IPaddress/cat1comboBox.php";
string json = GetJSONFromWeb(URL, null);
if (json != null)
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    // Json String 를 객체로 반환 (역직렬화)
    JsonHelper category1 = serializer.Deserialize<JsonHelper>(json);

    datagGridView1 에 연결하거나, comboBox 에 연결 처리 추가하면 된다.
}


구글링 결과가 대부분 외국 자료이다보니 영문 중심이라 한글을 제대로 보여주지 못한다.

JavaScriptSerializer serializer = new JavaScriptSerializer(); 는 한글을 제대로 표현해준다.


코드를 구현해서 실제 적용을 해보니 데이터를 많이 가져올 수 없다. ㅠㅠㅠ

블로그 이미지

Link2Me

,
728x90

C# comboBox 에서 POST 방식으로 서버에 값을 전달하고 서버에서 그 결과를 회신하는 코드에 대해 작성한다.


private void cat1comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
    if (cat1comboBox1.SelectedIndex > 0)
    {
        cat1name1 = ((KeyValuePair<string, string>)cat1comboBox1.SelectedItem).Key;
        cat1uid1 = ((KeyValuePair<string, string>)cat1comboBox1.SelectedItem).Value;
        cat2comboBox(cat1uid1, cat2comboBox1); // 두번째 comboBox 표시
    }
}

void cat2comboBox(string category1, ComboBox CB)
{
    Dictionary<string, string> cat2Source = new Dictionary<string, string>();
    cat2Source.Add("전체", "0");
    try
    {
        string URL = "http://IP주소/cat2comboBox.php";
        string json = POSTPHPJSON(URL, category1);
        if (json != null)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            JsonHelper2 category2 = serializer.Deserialize<JsonHelper2>(json);

            foreach (var dr in category2.result)
            {
                cat2Source.Add(dr.classname, dr.uid);
            }

            CB.DataSource = new BindingSource(cat2Source, null);
            CB.DisplayMember = "Key";
            CB.ValueMember = "Value";

            CB.SelectedIndex = 0;  // 첫번째 아이템 선택
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }

}

private void cat2comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
    if (cat2comboBox1.SelectedIndex > 0)
    {
        cat2name1 = ((KeyValuePair<string, string>)cat2comboBox1.SelectedItem).Key;
        cat2uid1 = ((KeyValuePair<string, string>)cat2comboBox1.SelectedItem).Value;
        MessageBox.Show(cat2name1 + " : " + cat2uid1);
    }
}

string POSTPHPJSON(string url, string Data)
{
    try
    {
        var webRequest = (HttpWebRequest)WebRequest.Create(url);
        var postData = string.Format("catagory1={0}", Data); 

        // 좀 더 정교한 함수로 처리하려면 이 부분은 함수 밖에서 처리하는게 좋다.

        webRequest.Method = "POST";
        byte[] sendData = UTF8Encoding.UTF8.GetBytes(postData);
        webRequest.ContentType = "application/x-www-form-urlencoded";
        webRequest.ContentLength = sendData.Length;

        Stream dataStream = webRequest.GetRequestStream();
        dataStream.Write(sendData, 0, sendData.Length);
        dataStream.Close();

        var webResponse = (HttpWebResponse)webRequest.GetResponse();
        if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
        {
            var reader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8, true);
            return @reader.ReadToEnd().Trim();
        }
        else
        {
            MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode));
            return null;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        return null;
    }
}

public class cat2comboBox
{
    public string uid { get; set; }
    public string classname { get; set; }
}

public class JsonHelper2
{
    public List<cat2comboBox> result { get; set; }
}


블로그 이미지

Link2Me

,
728x90

C# comboBox 에 DB 테이블 정보를 가져와서 List Up 하는 방법이다.


MySQL DB를 직접 접속하는 방식이 아니라, Web 서버 정보를 JSON 으로 파싱해서 연동하는 방법이다.

기본 사항은 http://net-informations.com/q/faq/combovalue.html http://stackoverflow.com/questions/3063320/combobox-adding-text-and-value-to-an-item-no-binding-source 참조하면 도움된다.


코드는 일반적인 형태와 약간 다르게 처리할 수 밖에 없었다.

일반적인 경우에는 CB.DataSource = new BindingSource(cat1Source, null); 대신에 CB.DataSource = category1.result; 로 하면 된다.

하지만 이렇게 하면 전체 라는 구분자가 보이지 않는다.

그래서 별도로 Dictionary 를 이용해서 저장한 다음에 다시 매핑을 시켰다.

서버 파일을 변경하여 연동 에러가 발생하게 하여 미처 고려하지 못한 버그도 수정 반영하였다.

화면에 보이는 Text 만 고려하지 않고 value 까지 고려한 이유는 comboBox 아이템을 선택했을 때 uid 를 이용하여 DB 테이블 조회를 하기 위해서다.


using System;
using System.Web;
using System.Web.Script.Serialization;
using System.Net;
using System.Windows.Forms;
using System.Collections.Generic;
using System.IO;
using System.Data;
using System.Text;

private void Form1_Load(object sender, EventArgs e)
{
    cat1comboBox(cat1comboBox1); // DB 테이블 정보 가져오기
}

void cat1comboBox(ComboBox CB)
{
    CB.Items.Clear();
    Dictionary<string, string> cat1Source = new Dictionary<string, string>();
    cat1Source.Add("전체", "0");  // DB에는 전체가 없어서 추가
    try
    {
        string URL = "http://IP주소/cat1comboBox.php";
        string json = GetPHPJSON(URL);
        if (json != null)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            JsonHelper category1 = serializer.Deserialize<JsonHelper>(json); // Json String 객체로 반환 (역직렬화)

            foreach (var dr in category1.result)
            {
                cat1Source.Add(dr.classname, dr.uid);
            }

            CB.DataSource = new BindingSource(cat1Source, null);
            CB.DisplayMember = "Key";
            CB.ValueMember = "Value";

            CB.SelectedIndex = 0;  // 첫번째 아이템 선택
        }               
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
   
}

private void cat1comboBox1_SelectedIndexChanged_1(object sender, EventArgs e)
{
    if (cat1comboBox1.SelectedIndex > 0)
    {
        string key = ((KeyValuePair<string, string>)cat1comboBox1.SelectedItem).Key;
        string value = ((KeyValuePair<string, string>)cat1comboBox1.SelectedItem).Value;
        MessageBox.Show(key + " : " + value);
    }
}

string GetPHPJSON(string url)
{
    try
    {
        var webRequest = (HttpWebRequest)WebRequest.Create(url);
        var webResponse = (HttpWebResponse)webRequest.GetResponse();
        if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
        {
            var reader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8, true);
            return @reader.ReadToEnd().Trim();
        }
        else
        {
            MessageBox.Show(string.Format("Status code == {0}", webResponse.StatusCode));
            return null;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        return null;
    }
}


public class cat1comboBox
{
    public string uid { get; set; }
    public string classname { get; set; }      
}

public class JsonHelper
{
    public List<cat1comboBox> result { get; set; }
}

블로그 이미지

Link2Me

,
728x90

PHP 서버에서 가져온 데이터 형식이라고 가정한다.

Local 에서 JSON 형식으로 데이터를 만들 이유는 없을 것이다.


public static string DeserializeNames()
{
    jsonData = "{\"name\":[{\"last\":\"Smith\"},{\"last\":\"Doe\"}]}";
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    JsonHelper myNames = serializer.Deserialize<JsonHelper>(jsonData);
    return ser.Serialize(myNames);
}

//Class descriptions
public class name
{
   public string last { get; set; }
}

public class JsonHelper
{
   public List<name> { get; set; }
}



두개는 같이 사용 가능하다.

List<name> myNames = ser.Deserialize<List<name>>(jsonData);
JsonHelper myNames = ser.Deserialize<JsonHelper>(jsonData);


PHP 서버에서 JSON 을 가져오는 소스코드는

string GetJSONFromPHP(string url)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    try
    {
        WebResponse response = request.GetResponse();
        using (Stream responseStream = response.GetResponseStream())
        {
            StreamReader reader = new StreamReader(responseStream, Encoding.UTF8, true);
            return @reader.ReadToEnd().Trim();
        }
    }
    catch (WebException ex)
    {
        WebResponse errorResponse = ex.Response;
        using (Stream responseStream = errorResponse.GetResponseStream())
        {
            StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
            String errorText = reader.ReadToEnd();
        }
        throw;
    }
}



jsonData = "{\"name\":[{\"last\":\"Smith\"},{\"last\":\"Doe\"}]}"; 대신에


using System.Web.Script.Serialization;
jsonData = GetJSONFromPHP(string url); 를 사용하면 된다.


dataGridView1 에다가 연결하는 방법은

JavaScriptSerializer serializer = new JavaScriptSerializer();
JsonHelper myNames = serializer.Deserialize<JsonHelper>(json);
dataGridView1.DataSource = myNames.name;


또는

JavaScriptSerializer serializer = new JavaScriptSerializer();
List<name> myNames = ser.Deserialize<List<name>>(jsonData);
dataGridView1.DataSource = myNames.ToArray();


로 하면 된다.    



블로그 이미지

Link2Me

,
728x90

Web 사이트에 C#에서 보내는 값을 저장하는 예제이다.

form 에서 보내는 데이터처럼 데이터를 보내는 식으로 값을 전달하면 저장된다.

테스트를 위해서 작성해본 것이라서 소스 내용이 정교하지는 못하다.

PostData 값을 전달하는 부분만 수정해서 사용하기 위해 작성해둔다.


private void btnSave_Click(object sender, EventArgs e)
{
    if (cat1name.Text.Trim() == "")
    {
        MessageBox.Show("카테고리1을 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.cat1name.Focus();
    }
    else if (cat2name.Text.Trim() == "")
    {
        MessageBox.Show("카테고리2을 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.cat2name.Focus();
    }
    else if (textBox1.Text.Trim() == "")
    {
        MessageBox.Show("이름을 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.textBox1.Focus();
    }
    else if (mobile1.Text.Trim() == "")
    {
        MessageBox.Show("휴대폰번호 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.mobile1.Focus();
    }
    else if (mobile2.Text.Trim() == "")
    {
        MessageBox.Show("휴대폰번호 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.mobile2.Focus();
    }
    else if (mobile3.Text.Trim() == "")
    {
        MessageBox.Show("휴대폰번호 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.mobile3.Focus();
    }
    else
    {
        NameValueCollection strqry = new NameValueCollection();
        strqry.Add("uid", uid.Text.Trim());
        strqry.Add("category1", cat1name.Text.Trim());
        strqry.Add("category2", cat2name.Text.Trim());
        strqry.Add("name", textBox1.Text.Trim());
        strqry.Add("email", textBox2.Text.Trim());
        strqry.Add("mobile_1", mobile1.Text.Trim());
        strqry.Add("mobile_2", mobile2.Text.Trim());
        strqry.Add("mobile_3", mobile3.Text.Trim());

        Address_DBSave(strqry);
    }           
}

private string Address_DBSave(NameValueCollection strqry)
{
    // 주소록 DB에 저장하는 메소드
    string url = "http://www.abc.com/";
    // PostData 코드 부분
    string boundary = "-----------------------------267631966917210";
    string end_boundary = "-----------------------------267631966917210--\r\n";

    StringBuilder sb = new StringBuilder();
    foreach (string fieldName in strqry.Keys)
    {
        string fieldValue = strqry.Get(fieldName);
        sb.AppendFormat("{0}\r\n" + "Content-Disposition: form-data; name={1}\r\n\r\n{2}\r\n", boundary, fieldName, fieldValue);
    }
    sb.Append(end_boundary);
    string PostData = sb.ToString();

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    byte[] sendData = UTF8Encoding.UTF8.GetBytes(PostData);
    // Web Header 분석기에서 구한 POST 정보를 여기에 적는다

    Stream dataStream = request.GetRequestStream();
    dataStream.Write(sendData, 0, sendData.Length);
    dataStream.Close();

    string resResult = string.Empty;
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader readerPost = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8, true);
    resResult = readerPost.ReadToEnd();
    readerPost.Close();
    response.Close();
    //MessageBox.Show(resResult);

    if (resResult.IndexOf("등록") != -1)
    {
        MessageBox.Show("등록되었습니다");
    }
    return null;
}


블로그 이미지

Link2Me

,
728x90

Web 사이트에서 로그인 처리를 C#에서 처리하는 방법을 간단하게 적어둔다.

로그인 버튼을 누르면 아이디와 패스워드 입력 값이 있는지 없는지 체크를 한다.


private void btnOK_Click(object sender, EventArgs e)
{
    if (this.txtID.Text == "")
    {
        MessageBox.Show("로그인 아이디를 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.txtID.Focus();
    }
    else if (this.txtPwd.Text == "")
    {
        MessageBox.Show("로그인 비밀번호를 입력하세요", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        this.txtPwd.Focus();
    }
    else
    {
        strSessionID = doLogin(txtID.Text, txtPwd.Text);
        if (strSessionID.Length > 0)
        {
            this.Close();
        }
    }
}


이제 실제 로그인 검사를 하는 doLogin(string ID, string PW) 함수를 만들어야 한다.

using System.Net;
using System.IO;

MessageBox.Show(resResult);  부분은 메시지 확인이 다 끝났으면 주석처리를 한다.

resResult.IndexOf 메소드를 이용하여 메시지에서 키워드를 추출하여 포함여부를 체크하여 로그인의 정상/비정상 메시지를 확인할 수 있게 한다.

Web Header 정보는 HTTP Analyzer V7 을 이용해서 확인할 수 있다.

로그인 함수는 만들기 나름이다.

postData 정보인 userID, userPW 정보를 보내서 받은 결과값(화면에 뿌리는 결과, PHP 에서는 echo 결과) 을 가지고 원하는 정보를 파싱해서 로그인 처리를 하게 된다.

만들기에 따라서는 간단하게 코드화를 해서 코드값만 결과로 받아서 처리할 수도 있다.


쿠키정보 값을 알아내려면

string cookie = webResponse.GetResponseHeader("Set-Cookie");
MessageBox.Show(cookie);
를 이용해서 쿠기값을 확인해볼 수가 있다.

그런 다음에 원하는 세션 정보만 추출해서 저장한다.


private string doLogin(string ID, string PW)
{
    string url = "http://www.abc.com/";
    // Web Header 분석기에서 구한 PostData 정보를 여기에 적는다
    string PostData = string.Format("r=home&a=login&id={0}&pw={1}", ID.Trim(), PW.Trim());


    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
    byte[] sendData = UTF8Encoding.UTF8.GetBytes(PostData);
    webRequest.Method = "POST";
    webRequest.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)";
    webRequest.ContentType = "application/x-www-form-urlencoded";
    webRequest.KeepAlive = true;
    webRequest.AllowAutoRedirect = false;

    Stream dataStrem = webRequest.GetRequestStream();
    dataStrem.Write(sendData, 0, sendData.Length);
    dataStrem.Close();

    HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
    StreamReader readStream = new StreamReader(webResponse.GetResponseStream(), System.Text.Encoding.UTF8, true);
    string resResult = readStream.ReadToEnd().Trim();
    MessageBox.Show(resResult);  // 패스워드 정상 / 비정상 메시지를 확인한다.
    readStream.Close();
    webResponse.Close();

    CK = false;
    if(resResult.IndexOf("history.go(-1);//]]>") < 0)  // 웹페이지 메세지가 없으면
    {
        if (webResponse.GetResponseHeader("Set-Cookie").IndexOf("PHPSESSID=") != -1)
        {
            CK = true;
            strSessionID = SSplit(SSplit(webResponse.GetResponseHeader("Set-Cookie"), "PHPSESSID=", 1), ";", 0);
            strID = txtID.Text;
        }
        else
        {
            strID = string.Empty;
        }
    }
    else
    {
        strID = string.Empty;
    }
    return strID;
}


public static string SSplit(string _body, string _parseString, int index)
{
    string varTemp = _body.Split(new string[] { _parseString }, StringSplitOptions.None)[index];
    return varTemp;
}


블로그 이미지

Link2Me

,
728x90

인터넷에 있는 파일을 읽어서 원하는 내용을 추출할 때 사용하는 코드이다.

이벤트 처리에 대한 개념이 잡히면서 MSDN 찾아보고 구글링 예제를 보면 점점 더 알게된다.


WebClient 클래스 : https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=KO-KR&k=k%28System.Net.WebClient%29;k%28TargetFrameworkMoniker-.NETFramework

using System.Net;

private void webFileRead()
{
    string serverfileName = "setup.txt";
    string URLPath = "http://www.abc.com/app/";

    WebClient client = new WebClient();
    Stream stream = client.OpenRead(URLPath + serverfileName);
    StreamReader reader = new StreamReader(stream);
    string readText = reader.ReadToEnd();
    //MessageBox.Show(readText);
    string serverVersion = SSplit(SSplit(readText, "[Version]", 1), "[", 0).Replace("\r\n", "").Trim();
    MessageBox.Show(serverVersion);
}

public static string SSplit(string _body, string _parseString, int index)
{
    string varTemp = _body.Split(new string[] { _parseString }, StringSplitOptions.None)[index];
    return varTemp;
}



WebRequest 클래스를 이용하여 웹 파일 내용을 확인하는 코드이다.

private string getSVersion()
{
    string serverfileName = "setup.txt";
    string URLPath = "http://www.abc.com/app/";

    WebRequest request = WebRequest.Create(URLPath + serverfileName);
    WebResponse response = request.GetResponse();
    string readText = new StreamReader(response.GetResponseStream()).ReadToEnd();
    string serverVersion = SSplit(SSplit(readText, "[Version]", 1), "[", 0).Replace("\r\n", "").Trim();

    return serverVersion;
}


웹 파일 다운로드 진행률 표시 처리 구현을 위한 준비 작업

WebClient 클래스의 이벤트를 찾아보면 파일 다운로드를 구현할 때 파일의 다운로드 진행상태 등을 알 수 있는 예제를 제공하고 있다.

https://msdn.microsoft.com/ko-kr/library/system.net.webclient.downloadprogresschanged%28v=vs.110%29.aspx


WebClient.DownloadProgressChanged 이벤트
// 비동기 다운로드 작업을 통해 데이터 전체 또는 일부를 성공적으로 전송하면 발생
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgress);
private void DownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
   progressBar1 = e.ProgressPercentage;
   label1.Text = progressBar1.Value.ToString() + "%";
}

WebClient.DownloadFileCompleted 이벤트
// 비동기 파일 다운로드 작업이 완료되면 발생
client.DownloadFileCompleted += new AsyncCompletedEventHandler (DownloadFileComplete);
private void DownloadFileComplete(object sender, AsyncCompletedEventArgs e)
{
   MessageBox.Show("다운로드가 완료되었습니다");
}


블로그 이미지

Link2Me

,