Category: การพัฒนา Web Application

  • ASP.NET Core Part I

    asp.net core คือ cross-platform framework สำหรับการพัฒนา web application ที่ทำงานบน .net core หรือ  full .net framework เดิม ( .net core สามารถใช้งานได้ทั้ง Windows , Linux และ MacOS โดยที่ส่วนประกอบต่างๆของ .net core ไม่ว่าจะเป็น runtime, libraries, compiler, language และเครื่องมือต่างๆ เป็น open source ทั้งหมด )  ซึ่ง asp.net core ได้รับการออกแบบใหม่ให้มีประสิทธิภาพดีกว่า asp.net เดิมโดยแบ่งส่วนต่างๆออกเป็น module ย่อยเพื่อลด overhead ในการเริ่มต้นทำงาน ซึ่ง asp.net core ประกอบไปด้วยกลุ่มของ NuGet package แทนที่การใช้งาน System.Web.dll ใน asp.net เดิม ซึ่งผู้พัฒนาสามารถเลือกเฉพาะ package ที่ต้องใช้งานเท่านั้น ทำให้ application มีขนาดเล็กลง มีประสิทธิภาพเพิ่มขึ้น,การพัฒนา Web UI และ Web API จะใช้ libraries เดียวกัน, สนับสนุนการใช้งาน dependency injection, web application สามารถใช้งานบน IIS หรือ self-host ภายใต้ process ของตัวเอง

    ในการพัฒนา asp.net core เราสามารถใช้เครื่องมือที่เป็น text editor ธรรมดาหรือจะใช้เครื่องมือช่วยในการพัฒนาอย่างเช่น Visual Studio ก็ได้ ในส่วนของโครงสร้างของ project asp.net core จะเปลี่ยนไปจากเดิม โดยการกำหนดค่า config ของ project สามารถกำหนดได้ที่ project.json

    {
     "title": "asp.net.core",
     "version": "1.0.0",
    
     "dependencies": {
       "NETStandard.Library": "1.6.0",
       "Newtonsoft.Json": "9.0.1"
     },
    
     "frameworks": {
       "netstandard1.6": {
          "imports": "dnxcore50"
        }
      }
    }

    การ reference ไปยัง NuGet package ที่ต้องการใช้งานใน project สามารถกำหนดได้ใน project.json โดยพิมพ์ชื่อ NuGet package ที่ต้องการพร้อมทั้งระบุ vesrion ในส่วน “dependencies” ซึ่งเมื่อทำการบันทึก project.json เครื่องมืออย่างเช่น visual studio จะทำการ restroe NuGet package ให้กับ project โดยอัตโนมัติ

    asp.net core ได้รับการออกแบบให้รองรับ client-side framework ต่างๆเช่น AngularJS หรือ bootstrap โดยใช้เครื่องมือที่เป็น package manager ในติดตั้ง client-side package ที่ต้องการใช้งาน อย่างเช่น Bower ที่จะกำหนด package ที่ต้องการใช้งานใน bower.json

    {
     "name": "asp.net",
     "private": true,
     "dependencies": {
       "bootstrap": "3.3.6",
       "jquery": "2.2.0",
       "jquery-validation": "1.14.0",
       "jquery-validation-unobtrusive": "3.2.6"
     }
    }

    หรือ npm ที่จะกำหนด package ที่ต้องการใช้งานใน package.json

    {
     "name": "asp.net",
     "version": "1.0.0",
     "private": true,
     "devDependencies": {
       "gulp": "3.8.11",
       "gulp-concat": "2.5.2",
       "gulp-cssmin": "0.1.7",
       "gulp-uglify": "1.2.0",
       "rimraf": "2.2.8",
       "typings": "1.0.5"
     },
     "dependencies": {
       "core-js": "^2.4.0",
       "reflect-metadata": "^0.1.3",
       "rxjs": "5.0.0-beta.6",
       "systemjs": "0.19.27",
       "zone.js": "^0.6.12"
     }
    }

    โดยเมื่อทำการบันทึก package manager จะทำการ restore package ที่ระบุ (bower.json หรือ package.json) ให้กับ project โดยอัตโนมัติ โดยที่ Bower จะติดตั้งลงใน /wwwroot/lib ในขณะที่ npm จะติดตั้งลงไปที่ folder /node_modules

    ในส่วนของ web root ของ asp.net core project จะอยู่ที่ folder /wwwroot ซึ่งต่างจาก asp.net เดิมที่ใช้ root folder ของ project เป็น web root โดยที่ /wwwroot จะเป็น folder ที่เก็บพวก static resources ต่างๆเช่น css, js และ image files

    entry point สำหรับ asp.net core application จะอยู่ที่ class “Startup” ซึ่งจะเป็น class ที่ใช้ในการกำหนด configuration และ service ต่างๆที่จะใช้ใน application โดย asp.net จะทำการค้นหา class ที่มีชื่อ startup ใน primary assembly (ในทุก namespace และไม่สนใจว่า class Startup จะเป็น public class หรือไม่ก็ตาม) ใน class Startup จะต้องมี method “Configure” ซึ่ง asp.net จะเรียกใช้งานตอนเริ่มต้น application (สำหรับ method “ConfigureServices” จะมีหรือไม่ก็ได้)

    สำหรับ Configure method จะต้องรับ parameter type “IApplicationBuilder” และอาจจะระบุ service ที่ต้องการใช้งานเช่น IHostingEnvironment และ ILoggerFactory ซึ่ง service เหล่านี้จะถูก inject โดย server โดยอัตโนมัติ

    IApplicationBuilder ถูกใช้ในการสร้าง application request pipeline ซึ่งสามารถเข้าถึงได้ผ่านทาง Configure method ใน Startup เท่านั้น

    IHostingEnvironment จะใช้เพื่อเข้าถึงข้อมูลสภาพแวดล้อมของ application เช่น EnvironmentName, ContentRootPath, WebRootPath และ web root file provider

    ILoggerFactory ให้ความสามารถในการทำ logging ซึ่งสามารถเข้าถึงได้ผ่านทาง Startup constructor และ Configure method ใน Startup เท่านั้น

     public void Configure(IApplicationBuilder app, 
                           IHostingEnvironment env,
                           ILoggerFactory loggerFactory)
     {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
    
        if (env.IsDevelopment())
        {
          app.UseDeveloperExceptionPage();
          app.UseDatabaseErrorPage();
          app.UseBrowserLink();
        }
        else
        {
          app.UseExceptionHandler("/Home/Error");
        }
    
        app.UseStaticFiles();
    
        app.UseMvc(routes =>
        {
           routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}");
         });
    }

    จะเห็นว่ามีการใช้ “Use” extension method เพื่อเพิ่ม middleware เข้าไปสู่ request pipeline ของ asp.net ตัวอย่างเช่น “UseMvc” extension method จะเป็นการเพิ่ม routing middleware เข้าไปสู่ request pipeline

    ใน part I นี้ได้กล่าวถึงส่วนหลักๆของ asp.net core (asp.net 5)  ที่เปลี่ยนไปจาก asp.net เดิม ทั้งในส่วนของ framework และการรองรับการพัฒนา client-side ในส่วนต่อไปเราจะเริ่มต้นพัฒนา asp.net core โดยการสร้าง asp.net core web application project ในแบบง่ายๆ

    อ้างอิง : https://docs.asp.net

  • การสร้างแผนที่ออนไลน์ (Web Map) ด้วยลิงค์ KML/KMZ

    นักพัฒนาเว็บหลายคนคงจะคุ้นเคยกับการสร้าง web map ด้วย google map api กันนะคับ (เป็นที่นิยมเลยล่ะ) แต่ในยุคปัจจุบันที่มีการเผยแพร่ข้อมูลที่เป็น near real time กันมากยิ่งขึ้น จะเห็นได้จากหลายหน่วยงานมีการเผยแพร่ Web Map Services กันเยอะมากยิ่งขึ้น และแย่งชิงความเป็นผู้นำในการนำเสนอข้อมูลที่เป็นปัจจุบันทันด่วนที่สุด

    แต่ด้วยปัจจัยในการต้องติดตั้งโปรแกรมบน Web Map Server เพื่อให้สามารถใช้งาน web map ผ่าน server ได้ (เสียงบประมาณเพิ่ม)
    ***ใครมี ArcGIS Server จะลองทำ การสร้างเว็บแผนที่จุดความร้อน(Hotspot) โดยใช้ WMS บน ArcGIS Server ดูได้นะคับ

     

    วันนี้เลยจะขอนำเสนอโค้ดง่ายๆ ในการนำลิงค์ KML/KMZ จากเว็บที่ให้บริการฟรี! มาสร้างเป็นหน้าเว็บเพจของเราโดยที่ไม่ต้องติดตั้ง map server กันคับ ^^ ที่สำคัญ ต้นทางข้อมูลอัพเดทข้อมูล หน้าเว็บเราก็อัพเดทไปด้วย อิอิ

    ขั้นตอนการสร้าง

    1. เปิดหน้าเว็บที่ให้บริการลิงค์ ***ตัวอย่างเว็บ http://slb-gis.envi.psu.ac.th

    2. เลือกชั้นข้อมูลที่ต้องการ แล้วคลิกขวา > copy link address

    00

    3. สร้างไฟล์ gmap.html แล้วเปิด edit ด้วยโปรแกรม notepad หรือ text editor

    4. copy โค้ดนี้ไปวาง

    <!DOCTYPE html>
    <html>
    <head>
    <meta name=”viewport” content=”initial-scale=1.0″>
    <meta charset=”utf-8″>
    <title>การสร้างแผนที่ออนไลน์ (Web Map) ด้วยลิงค์ KML/KMZ</title>
    <style>
    html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    }
    #map {
    height: 100%;
    }
    </style>
    </head>
    <body>
    <div id=”map”></div>
    <script>

    function initMap() {
    var map = new google.maps.Map(document.getElementById(‘map’), {
    zoom: 11,
    center: {lat: 100.756297, lng: 14.790059}
    });

    var ctaLayer = new google.maps.KmlLayer({
    url: ‘ที่อยู่ kml/kmz ลิงค์‘,
    map: map
    });
    }

    </script>
    <script async defer
    src=”https://maps.googleapis.com/maps/api/js?key=google map api key“>
    </script>
    </body>
    </html>

    4. วางลิงค์ที่ copy มาจากเว็บตรงurl: ‘http://slb-gis.envi.psu.ac.th/home1/images/download/kmz/gcs_slbforu.kmz‘,

    และใส่ google map api key ***ถ้าไม่มีให้ไปที่ https://developers.google.com/maps/documentation/javascript/get-api-key

    01

    5. ลองเปิดผ่าน http://localhost/gmap.html จะได้ตามรูป

    02

    6. หากคลิกที่ข้อมูล จะมี pop-up แสดงข้อมูลขึ้นมา

    03

    7. เว็บไซต์ของท่านก็จะมีหน้าเว็บแมพไว้ใช้งานได้แบบง่ายๆ โดยไม่ต้องติดตั้ง web map server ^^

     

    ****บริการฟรี! ชั้นข้อมูลลุ่มน้ำทะเลสาบสงขลาเพิ่มเติมได้ที่ โครงการการพัฒนาฐานข้อมูลสารสนเทศภูมิศาสตร์ลุ่มน้ำทะเลสาบสงขลา โดย สถานวิจัยสารสนเทศภูมิศาสตร์ทรัพยากรธรรมชาติและสิ่งแวดล้อม คณะการจัดการสิ่งแวดล้อม มหาวิทยาลัยสงขลานครินทร์

  • ASP.NET MVC Part3: สร้าง Model ด้วย Entity Framework

    จากบทความก่อนหน้า ซึ่งอาจจะนานมากพอสมควรที่ได้แนะนำ MVC ไปไว้แล้วในเบื้องต้น (ASP.NET MVC Part 1 : ทำความรู้จักกับ ASP.NET MVC และ ASP.NET MVC Part2: เริ่มต้นสร้างเว็บด้วย MVC with Bootstrap) บทความนี้จะมาแนะนำในส่วนของการสร้าง Model ในการเชื่อมต่อกับฐานข้อมูล ในการ query และจัดการกับข้อมูล เพื่อส่งให้กับ Controller และ View เรียกใช้ในลำดับต่อไป

    Model คือ ส่วนหนึ่งในองค์ประกอบของการพัฒนาเว็บแอพพลิเคชันตามรูปแบบ MVC Framework (Model-View-Controller) โดยจะเป็นส่วนที่ทำหน้าที่ Business Model หรือส่วนที่ติดต่อกับฐานข้อมูล โดยบทความนี้นำเสนอการนำเครื่องมือ Entity Framework มาใช้ในการสร้างและจัดการ Model ในการเชื่อมต่อกับฐานข้อมูล สำหรับการพัฒนาเว็บแอพพลิเคชันตามรูปแบบ MVC Framework

    Entity Framework
    Entity Framework คือ tools ที่ทำหน้าที่จัดการกับฐานข้อมูล โดยแนวคิดของ Entity Framework อยู่ในรูปแบบของ O/RM (Object/Relational Mapping) คือ Entity Framework จะสร้าง Layer ทำหน้าที่เป็น Database Model ขึ้นมาเป็น Class ใน Project ของเรา โดยจะทำหน้าที่ Mapping ตัว Class ที่จะสร้างขึ้น กับ Table , View และ Stored Procedure จากฐานข้อมูบ มาไว้บน Project ซึ่งทำให้เราเราสามารถเรียกใช้มันผ่าน Class ที่อยู่ใน Project เราได้เลย ส่วนการเขียน Query หรือจัดการกับข้อมูลผ่านตัว Entity Model จะใช้ Syntax ของ LINQ to Entities ซึ่งเป็น syntax ที่สามารถเข้าใจได้ง่ายตามรูปแบบของภาษาเช่น VB.Net หรือ C#

    ex_entity
    ตัวอย่างการใช้งาน Entity Framework

     

    วิธีการใช้งาน Entity Framework เบื้องต้น

    1. เปิด solution ที่ต้องการใช้ขึ้นมา (ในบทความนี้เป็น project แบบ MVC Framework)

    2. คลิกขวาที่โฟลเดอร์ Model แล้วเลือก Add =>New Item

    3. ที่ tab ด้านซ้ายมือ เลือก Data จากนั้นเลือก ADO.NET Entity Data Model และทำการตั้งชื่อ และกดปุ่ม Add

    new_entityModel

     

    4. เมื่อเข้าสู่หน้าจอให้เลือก Model Content ให้เลือก EF Desiner from DataBase และกด Next จะเข้าสู่ขั้นตอนต่อไป

    choose_content

     

    5.ขั้นตอนถัดมาคือการเลือก Data Connection เป็นการเลือกการติดต่อกับฐานข้อมูลว่าจะให้ Entity ติดต่อกับฐานข้อมูลไหน โดยครั้งแรกหากยังไม่มี ฐานข้อมูลมาให้เลือกใน comboBox จะต้อง New Connection ขึ้นมาก่อน และทำตามขั้นตอนไปได้เลย แต่ถ้ามีแล้วให้เลือก Connection จาก ComboBox หลังจากนั้นให้กดเลือก Yes,include the sensitive data in connection string และเลือก Checkbox ให้ Save Connection string เข้าสู่ Web.Config และตั้งชื่อให้กับ Conection string โดย default ชื่อจะเป็น “Entities” และกดปุ่ม Next เข้าสู่ขั้นตอนต่อไปchoose_dataConrection

     

    6.ขั้นตอนนี้เป็นขั้นตอนสุดท้าย สำหรับเลือกว่า เราจะติดต่อ Entity กับ Table, View หรือ Storeprocdure อะไรบ้าง ให้กด expand และเลือก Table, View หรือ Storeprocdure ที่ต้องการ หลังจากนั้นให้กดปุ่ม Finish เป็นอันเสร็จกระบวนการสร้าง Entity Data Model ในการติดต่อกับฐานข้อมูล

    choose_table

     

    การเรียกใช้งานจากฝั่ง Controller

    1.ที่ไฟล์ xxxController.cs ทำการ using เพื่อเรียกใช้งาน

    using MVCBootstrap.Models;
    

    2.ประกาศตัวแปรขึ้นมา new object เพื่อจะเข้าถึง entity model ที่เราได้ทำการสร้างไว้ก่อนหน้านี้

    var db = new Budget_Entities();
    

    3.เข้าถึงแต่ละ Entity โดยใช้ syntax linq  โดยขอยกตัวอย่างในส่วนของการเข้าถึงและจัดการข้อมูลเบื้องต้น

    • Query ข้อมูล
     public ActionResult QueryData()
            {
                var db = new Budget_Entities();
                var listCampus = db.VF_CAMPUS.Where(w => w.CAMP_NAME_THAI.Contains("วิทย"));
                return View(listCampus);
            }
    
    • Insert ข้อมูล

    public ActionResult InsertData()
            {
                bool isSuccess = true;
                I_ITEM item = new I_ITEM();
                item.ITEM_NO = "001";
                item.ITEM_THAI_NAME = "รายการวัสดุทางการศึกษา";
                db.SaveChanges();
                return View(isSuccess);
            }
    
    • Update ข้อมูล

     public ActionResult UpdateData(int itemID)
            {
                bool isSuccess = true;
                var db = new Budget_Entities();
                var itemForUpdate = db.I_ITEM.Find(itemID);
                itemForUpdate.ITEM_THAI_NAME = "รายการวัสดุแก้ไข";
                db.SaveChanges();
                return View(isSuccess);
            }
    
    • Remove ข้อมูล
     public ActionResult RemoveData(int itemID)
            {
                bool isSuccess = true;
                var db = new Budget_Entities();
                var itemForRemove = db.I_ITEM.Find(itemID);
                db.I_ITEM.Remove(itemForRemove);
                db.SaveChanges();
                return View(isSuccess);
            }
    

     

    ซึ่งจากทั้ง 4 ตัวอย่างจะมีการประกาศตัวแปร var db = new Budget_Entities(); เป็นการ new object ขึ้นมาเพื่อที่จะเข้าถึง entity ภายใน และทำการ query ข้อมูล, set ค่าให้กับ attribute หรือลบข้อมูล หลังจากที่จัดการกับตัว entity เสร็จแล้ว จะเรียกใช้งาน method SaveChanged() ซึ่งเป็นการสั่งให้ entity Model ทำการ execute และเปลี่ยนแปลงข้อมูลตามที่เราได้เขียน code ไว้ไปยังฐานข้อมูล เป็นอันเสร็จกระบวนการในการเปลี่ยนแปลงข้อมูลที่กระทำกับฐานข้อมูล จากนั้นเราจะเอาค่านั้นไปใช้ต่อหรือ จะ return ค่า ไปยัง View เพื่อแสดงผลต่อไปก็แล้วแต่ผู้ใช้เลยค่ะ

     

    บทความถัดไป : ASP.NET MVC Part 4: ทำความรู้จักกับ ViewData, ViewBag และ TempData

    บทความก่อนหน้า : ASP.NET MVC Part2: เริ่มต้นสร้างเว็บด้วย MVC with Bootstrap

    แหล่งข้อมูลอ้างอิง :

    [1] http://www.asp.net/mvc/overview/getting-started/database-first-development/creating-the-web-application

    [2] https://msdn.microsoft.com/en-us/library/bb399760(v=vs.100).aspx

  • การเรียกใช้งานเมธอดในฝั่งเซิร์ฟเวอร์/เว็บเซอร์วิสแบบ Ajax ด้วย jQuery (C#)

              ก่อนจะพูดถึงวิธีการเรียกใช้งานเมธอดในฝั่งเซิร์ฟเวอร์/เว็บเซอร์วิสแบบ Ajax ด้วย jQuery ผู้เขียนขอเกริ่นนำเกี่ยวกับที่มาที่ไปเกี่ยวกับแนวคิดแบบ Ajax เพื่อให้ผู้อ่านบางท่านที่ยังอาจงงๆได้ทำความเข้าใจเสียก่อน ว่าโดยปกติแล้วนั้น ในการพัฒนาเว็บไซต์(Web application)ของ ASP.NET จะประกอบด้วย 2 ส่วน คือ Client side และ Server side ซึ่งการทำงานในส่วนของ Client side จะหมายถึงส่วนของ browser หรือหน้าจอการทำงานของผู้ใช้ เช่น Google Chrome Firefox และ Internet explorer ส่วนในฝั่งเซิร์ฟเวอร์จะมีการรับคำร้องขอ(request) จากฝั่ง Client ทำการประมวลผลและส่งค่าผลลัพธ์คืนกลับมายังฝั่ง Client อีกครั้งเพื่อให้ผู้ใช้เห็นผลลัพธ์การตอบกลับนั้นได้ ซึ่งโดยปกติแล้วนั้นการพัฒนาจะประกอบด้วยโค้ด 2 ส่วน คือ

    • Server-side code ซึ่งเป็นเทคโนโลยีของการทำงานในการติดต่อไปยังฝั่งเซิร์ฟเวอร์ และถูกนำมาใช้ในการพัฒนา Web application ซึ่งใน ASP.NET นั้นนับว่าได้รับความนิยมเป็นอย่างมาก โดยจะมีการใช้งานผ่านทาง .NET Framework ในรูปแบบของภาษา C# VB หรือภาษาอื่นๆที่มีใน .NET ในการประมวลผลเพื่อติดต่อกับฐานข้อมูล หรือแหล่งข้อมูลอื่นๆจากคำร้องขอในฝั่ง Client และทำการส่งผลลัพธ์ที่ได้กลับมายังฝั่ง Client อีกครั้ง หลังจากมีการส่งผลลัพธ์ตอบกลับมาเรียบร้อยแล้วนั้น จะมีการ render หน้าจอดังกล่าวขึ้นอีกครั้งเพื่อแสดงผลลัพธ์ที่ได้ ทำให้เพจหรือหน้าจอที่ใช้งานมีการโหลดหรือ refresh เกิดขึ้น ซึ่งอาจส่งผลเสียทำให้ผู้ใช้รู้สึกล่าช้าในการรอการตอบกลับการประมวลผลพร้อมทั้งการแสดงผลจากฝั่งเซิร์ฟเวอร์ โดยโค้ดในลักษณะนี้ผู้พัฒนาบางท่านอาจรู้จักกันในนามของ code behind นั่นเอง
    • Client-side code อาจเรียกได้ว่าเป็น client-side script ที่ถูกฝังไว้ในฝั่ง client และมีการประมวลผลในส่วนของ Browser ของผู้ใช้ ซึ่งสคริปต์ที่นิยมใช้ในการพัฒนาโดยส่วนใหญ่จะเป็น JavaScript และโต้ตอบกลับมาโดยตรงด้วย element ที่มีใน HTML เช่น textbox ปุ่ม หรือตาราง เป็นต้น นอกจากนี้ยังมีการใช้งานของโค้ดภาษา HTML และ CSS(Cascading Style Sheets) ร่วมด้วย แต่การพัฒนาในส่วนนี้ต้องมีการคำนึงถึงภาษาและโค้ดที่รองรับในแต่ละ browser ของผู้ใช้ด้วย ซึ่งการพัฒนาด้วยโค้ดในส่วนนี้ จะทำให้การตอบโต้กับผู้ใช้งานเกิดขึ้นภายในเวลาอันสั้น เกิด overhead น้อย แต่ก็มีข้อเสียเกี่ยวกับการเลือกใช้ภาษาในการพัฒนาให้ครอบคลุมในความหลากหลายของ browser ที่ผู้ใช้ใช้งานในการเปิดเว็บไซต์ได้

    Ajax (Asynchronous JavaScript and XML)
              เทคโนโลยีและแนวคิดแบบ Ajax ได้เข้ามามีบทบาทในการเปลี่ยนแปลงแนวคิดและหลักการทำงานโดยทั่วไปที่มีอยู่เดิมของ web application เล็กน้อย คือจะมีการส่งคำร้องขอจากฝั่ง Client ไปยังฝั่งเซิร์ฟเวอร์โดยตรงเพื่อตอบโต้กับ object ที่มีในฝั่งเซิร์ฟเวอร์ เช่น ฐานข้อมูล หรือไฟล์ เป็นต้น โดยปราศจากการ postback โดยแนวคิดของ Ajax จะเกี่ยวข้องกับเทคโนโลยีที่มีอยู่เดิม เช่น ข้อมูลในฝั่งเซิร์ฟเวอร์ เว็บเซอร์วิส และการเขียนสคริปต์ในฝั่ง client โดย client-side script จะใช้ในการเรียกใช้เว็บเซอร์วิสเพื่อประมวลผลกับฐานข้อมูลตามคำร้องขอ ซึ่งคำร้องขอดังกล่าวอาจเป็นการบันทึกหรืออ่านค่าข้อมูลจากฐานข้อมูล และการเรียกใช้แบบ Ajax นี้จะเป็นลักษณะ Asynchronous คือ เมื่อผู้ใช้มีการส่งคำร้องขอไปยังเว็บเซอร์วิส ในหน้าจอการทำงานจะไม่ถูกล็อคไว้ และสามารถทำงานในส่วนอื่นต่อได้โดยไม่จำเป็นต้องรอกระบวนการทำงานให้เสร็จทีละส่วน สามารถทำคู่ขนานกันไปได้ และหากส่วนใดเสร็จสิ้นการประมวลผลแล้วนั้นตัวเว็บเซอร์วิสก็จะส่งผลลัพธ์กลับมาให้แสดงยังฝั่งผู้ใช้เอง
              โดยเทคโนโลยีที่ถือว่ามีความสำคัญและจำเป็นสำหรับ client-side script นั่นก็คือ jQuery ที่เรารู้จักกันดี ซึ่งเป็นที่นิยม เนื่องจากประมวลผลได้เร็ว มีขนาดเล็ก และมีคุณสมบัติอีกหลายประการที่จะเข้ามาช่วยทำให้การพัฒนาโปรแกรมมีประสิทธิภาพมากยิ่ง
    จากข้อความข้างต้น แสดงให้เห็นว่าการพัฒนาเว็บไซต์โดยหลีกเลี่ยงการ postback เมื่อมีการเรียกใช้งานไปยังฝั่งเซิร์ฟเวอร์ ถือเป็นอีกทางเลือกของนักพัฒนาที่จะหยิบมาใช้ เพื่อลด over head ให้กับตัว web server และสามารถตอบสนองต่อผู้ใช้ได้รวดเร็วขึ้น ลดจำนวนในการโหลดเพจ และรอการตอบสนองทุกครั้งที่มีการส่งคำร้องขอ ผู้เขียนจึงขอแนะนำวิธีการเรียกใช้หรือส่งคำร้องขอไปยังฝั่งเซิร์ฟเวอร์แบบ Ajax ด้วย jQuery ดังนี้

    • การเรียกใช้เมธอดในฝั่งเซิร์ฟเวอร์ตามแนวคิดของ Ajax ด้วย jQueryหลักการเขียนเพื่อเรียกใช้เมธอดในฝั่งเซิร์ฟเวอร์/เว็บเซอร์วิส
      CheckUserNameAvailability-2
      ที่มาของภาพ :http://www.aspsnippets.com/Articles/Call-ASPNet-Page-Method-using-jQuery-AJAX-Example.aspx
       

      • ตัวอย่างที่ 1 : การเรียกใช้งานเมธอดแบบส่งค่ากลับเป็น string แบบไม่มีการส่งค่าพารามิเตอร์
        ฝั่ง Client(aspx)
       function CallServerMethodString() {
                          $.ajax({
                              type: "POST", //ชนิดในการส่งค่า
                              contentType: "application/json",
                              ///ที่อยู่ของเมธอดที่ต้องการเรียก (ชื่อเพจ/ชื่อเมธอด)
                              url: "TestPageMethod.aspx/getDataRetString", 
                              dataType: "json", ///ส่งค่าแบบ json
                              beforeSend: function () {
                              ///  เป็นส่วนการแสดง loading progress bar ในขณะที่กำลังทำงานอยู่
                                  $("#loadingmessage").show();
                              },
                             //////เป็นส่วนที่เกิดขึ้น เมื่อเกิดข้อผิดพลาดในการเรียกใช้เมธอด
                              error: function (XMLHttpRequest, textStatus, errorThrown) {
                                  alert("Request: " + XMLHttpRequest.toString() + "\n\nStatus: " + textStatus + "\n\nError: " + errorThrown);
                              },
                            //////เป็นส่วนที่เกิดขึ้น เมื่อการเรียกใช้เมธอดเสร็จสิ้นสมบูรณ์
                              success: function (response) {
      ///ล้างค่าข้อมูลใน div และนำผลลัพธ์ที่ได้จากการเรียกใช้(response.d) มาแสดงใน div ที่กำหนด
                                  $("#dvResult").html("");
                                  $("#dvResult").append(response.d);
      ///ซ่อน loading progress bar เมื่อเสร็จสิ้นการทำงาน
                                  $("#loadingmessage").hide(); 
                              }
      
                          });
                      }
      

      ฝั่ง Server (c#)

       [System.Web.Services.WebMethod]
       public static string getDataRetString()
       {
           string Result = "";
           string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
           var results = from p in digits
                            select p;
           foreach (var d in digits)
           {
               Result= Result+ "Result is :" + d.ToString() + "<br>";
           }
              return Result;
          }
       }
      

      คำอธิบาย : เป็นตัวอย่างการสร้างเมธอดในฝั่งเซิร์ฟเวอร์ โดยในการสร้างเมธอดต้องมีการกำหนด [System.Web.Services.WebMethod] ไว้ในส่วนบนของเมธอด และมีชนิดเป็น static โดยในส่วนนี้ตามความเป็นจริงจะเป็นส่วนที่อาจมีการดึงมาจากฐานข้อมูล เพื่อคืนค่ากลับไปให้ฝั่ง Client แสดงผล แต่ในที่นี้จะขอสร้างเป็นเพียงข้อมูลสมมุติของอาร์เรย์ที่เป็นข้อความขึ้นมาเท่านั้น

      ผลลัพธ์

      result1

      • ตัวอย่างที่ 2 : แบบส่งค่ากลับเป็น object โดยมีการส่งพารามิเตอร์มายังฝั่งเซิร์ฟเวอร์ด้วย
        ฝั่ง Client (aspx)
      <script type="text/javascript">
       function CallServerMethodObject() {
                          $.ajax({
                              type: "POST",
                              contentType: "application/json",
                              url: "TestPageMethod.aspx/getDataRetObj",
               ///ส่งค่าพารามิเตอร์จากการเลือกประเภทสถานศึกษาให้กับเมธอดฝั่งเซิร์ฟเวอร์
                              data: "{'CategoryID' : " + ddlMain.val() + "}",
                              dataType: "json", ///ส่งค่าแบบ json
              /// เป็นส่วนการแสดง loading progress bar ในขณะที่กำลังทำงานอยู่
                              beforeSend: function () {
                                  $("#loadingmessage").show();
                              }, 
                              error: function (XMLHttpRequest, textStatus, errorThrown) {
                                  alert("Request: " + XMLHttpRequest.toString() + "\n\nStatus: " + textStatus + "\n\nError: " + errorThrown);
                              },
              ///เป็นส่วนที่จะทำงานเมื่อมีการเรียกใช้เมธอดเสร็จสิ้นโดยไม่มีข้อผิดพลาดใดๆ
                              success: function (response) {
                  ///ประกาศตัวแปรของคอนโทรล dropdownlist ที่ชื่อว่า ddlResult และล้างค่าข้อมูล
                                  var ddlResult = $("[id*=ddlResult]");
                                  ddlResult.empty().append('กรุณาเลือกชื่อสถานศึกษา');
                   ///วนรอบเพื่อดึงค่าจาก obj ที่ถูกส่งกลับมาเพื่อ populate ลงใน dropdownlist 
                                 $.each(response.d, function (index, item) {
                             ddlResult.append($("").val(item.SubCategory).html(item.title));
                                  });
                   ////ซ่อน loading progress bar เมื่อการทำงานสิ้นสุด
                                $("#loadingmessage").hide();
                              }
                          });
                      }
        </script>
       <asp:DropDownList ID="ddlMain" runat="server" onchange="CallServerMethodObject()" >
       <asp:ListItem Selected="True" Value="0">กรุณาเลือกประเภทสถานศึกษา</asp:ListItem>
       <asp:ListItem Value="1">มหาวิทยาลัย</asp:ListItem>
       <asp:ListItem Value="2">โรงเรียน</asp:ListItem>
       </asp:DropDownList>
       <asp:DropDownList ID="ddlResult" runat="server" >
      <asp:ListItem Value="0">กรุณาเลือกชื่อสถานศึกษา</asp:ListItem>
      </asp:DropDownList>
      

      คำอธิบาย : เป็นตัวอย่างการสร้าง Cascading dropdownlist อย่างง่าย โดยหากมีการเลือกประเภทสถานศึกษา จะมีการเรียกใช้ฟังก์ชั่น CallServerMethodObject() และส่งค่าที่เลือก(รหัสประเภทสถานศึกษา) ให้กับการเรียกใช้เมธอดในฝั่งเซิร์ฟเวอร์ในพารามิเตอร์ที่ชื่อว่า CategoryID เพื่อดึงค่าของชื่อสถานศึกษาตามประเภทที่เลือก

      ฝั่ง server (c#)

       [System.Web.Services.WebMethod]
          public static object getDataRetObj()
          {
      ///สมมุติให้ในส่วนนี้ เป็นการสร้างข้อมูลที่เป็น object และนำผลลัพธ์ที่ได้ส่งกลับไปยั่งฝั่ง Client เพื่อแสดงผล
        var obj = new { Category = 1, SubCategory=1, title = "มหาวิทยาลัยสงขลานครินทร์"};
        var objList = (new[] { obj }).ToList();
        objList.Add(new { Category = 1, SubCategory=2,  title = "มหาวิทยาลัยราชภัฎสงขลา" });
        objList.Add(new { Category = 2, SubCategory=3, title = "โรงเรียนมหาวชิราวุธ"});
        objList.Add(new { Category = 2, SubCategory=4, title = "โรงเรียนหาดใหญ่วิทยาลัย" });
      ////ดึงค่าชื่อสถานศึกษาตามรหัสประเภทสถานศึกษา CategoryID
              var results = from p in objList.Where(p=>p.Category==int.Parse(CategoryID))
                            select p;
      
              return results;
          }

      คำอธิบาย : เป็นตัวอย่างการสร้างเมธอดในฝั่งเซิร์ฟเวอร์ โดยในการสร้างเมธอดต้องมีการกำหนด [System.Web.Services.WebMethod] ไว้ในส่วนบนของเมธอด และมีชนิดเป็น static โดยในส่วนนี้ตามความเป็นจริงจะเป็นส่วนที่อาจมีการดึงมาจากฐานข้อมูลตามเงื่อนไขของพารามิเตอร์ที่ส่งมา เพื่อคืนค่ากลับไปให้ฝั่ง Client แสดงผล แต่ในที่นี้จะขอสร้างเป็นเพียงข้อมูลสมมุติของ object ขึ้นมาเท่านั้น

      ผลลัพธ์

      result3

    • การเรียกใช้เว็บเซอร์วิสตามแนวคิดของ Ajax ด้วย jQuery
      • ตัวอย่างที่ 1 : เป็นการเรียกใช้เมธอดจากเซอร์วิสในการแสดงผล

      ฝั่ง Client(aspx)

     <script type="text/javascript">
     function CallWebservice() {
                        var ddlMain = $("[id*=ddlMain]");
    
                        $.ajax({
                            type: "POST",
                            contentType: "application/json",
                            url: "WebServiceTest.asmx/getDataRetOddEven",
                            ///ส่งค่าพารามิเตอร์จากการเลือกประเภทชนิดข้อมูลตัวเลขให้กับเมธอดที่สร้างในเซอร์วิส
                            data: "{'CategoryID' : " + ddlMain.val() + "}",
                            dataType: "json",
                            beforeSend: function () {
                                $("#loadingmessage").show();
                            }, error: function (XMLHttpRequest, textStatus, errorThrown) {
                                alert("Request: " + XMLHttpRequest.toString() + "\n\nStatus: " + textStatus + "\n\nError: " + errorThrown);
                            },
                            success: function (response) {
                                $("#dvResult").html("");
                                $("#dvResult").append(response.d);
                                $("#loadingmessage").hide();
                            }
    
                        });
                    }
     </script>
     <asp:DropDownList ID="ddlMain" runat="server" onchange="CallWebservice()" >
     <asp:ListItem Selected="True" Value="-1">กรุณาเลือกประเภทตัวเลข</asp:ListItem>
     <asp:ListItem Value="0">เลขคู่</asp:ListItem>
     <asp:ListItem Value="1">เลขคี่</asp:ListItem>
     </asp:DropDownList>
    

    คำอธิบาย : เป็นตัวอย่างการเรียกใช้เมธอดจากเว็บเซอร์วิส เพื่อทำการดึงค่าข้อมูลตัวเลขตามประเภทของตัวเลขที่เลือกจาก dropdownlist ซึ่งในตัวอย่างนี้จะเป็นการเรียกใช้เมธอดที่มีชื่อว่า getDataRetOddEven ในเว็บเซอร์วิส WebServiceTest.asmx โดยลักษณะการเรียกใช้จะคล้ายกับตัวอย่างของการเรียกใช้เมธอดจากฝั่งเซิร์ฟเวอร์ที่กล่าวไว้แล้วก่อนหน้านี้ มีเพียงส่วนของการกำหนด url ที่เมธอดนั้นอยู่เท่านั้นที่ต้องให้มาอ้างจากเมธอดในเว็บเซอร์วิสแทน

    ฝั่งเว็บเซอร์วิส (WebServiceTest.asmx)

     [WebMethod]
        public string getDataRetOddEven(string CategoryID)
        {
             string result = "";
             int[] numbers = { 0, 1, 2, 3,4, 5, 6, 7,8, 9 };
    
             var results = from p in numbers.Where(p => p % 2 == int.Parse(CategoryID))
                          select p;
             foreach (var d in results)
             {
                 result = result + "Result is :" + d.ToString() + "
    ";
             }
             return result;
        }
    

    คำอธิบาย : เป็นตัวอย่างการสร้างเมธอดในเว็บเซอร์วิสเพื่อรับค่าชนิดของตัวเลข(คู่/คี่) เพื่อนำมาใช้ในการดึงข้อมูลตามเงื่อนไข โดยในการสร้างเมธอดต้องมีการกำหนด [WebMethod] ไว้ในส่วนบนของเมธอด และมีเพิ่ม [System.Web.Script.Services.ScriptService] ในส่วนบนของไฟล์ เพื่อให้สามารถรันสคริปต์ผ่านเว็บเซอร์วิสได้ โดยในส่วนนี้ตามความเป็นจริงจะเป็นส่วนที่อาจมีการดึงมาจากฐานข้อมูล เพื่อคืนค่ากลับไปให้ฝั่ง Client แสดงผล แต่ในที่นี้จะขอสร้างเป็นเพียงข้อมูลสมมุติของอาร์เรย์ที่เป็นข้อความขึ้นมาเท่านั้น
    หมายเหตุ : 

    ผลลัพธ์

    result4result5

    เพิ่มเติม : 
    Namespace ที่ต้องอ้างอิงเพิ่มเติมหากมีการใช้งานเกี่ยวกับ LINQ คือ using System.Linq;

              มาถึงตรงนี้ ผู้เขียนหวังเป็นอย่างยิ่งว่า เนื้อหาและตัวอย่างที่มีในบทความนี้ จะช่วยเพิ่มความเข้าใจในเบื้องต้นเกี่ยวกับการเรียกใช้งานเมธอดในฝั่งเซิร์ฟเวอร์/เว็บเซอร์วิสแบบ Ajax ด้วย jQuery เพื่อช่วยในการเพิ่มประสิทธิภาพทำงานของระบบที่พัฒนา และน่าจะช่วยให้การประมวลผลไปยังฝั่งเซิร์ฟเวอร์รวดเร็วขึ้น เกิดความพึงพอใจในการใช้งานของผู้ใช้มากยิ่งขึ้น อีกทั้งยังอาจเป็นอีกหนึ่งทางเลือกในการพัฒนาต่อยอดและประยุกต์ใช้ให้เหมาะกับงานของผู้พัฒนาแต่ละท่านได้ หากมีส่วนใดผิดพลาด ผู้เขียนขออภัยไว้ ณ ที่นี้ด้วย ขอบคุณค่ะ

    แหล่งข้อมูลอ้างอิง :
    http://www.seguetech.com/blog/2013/05/01/client-side-server-side-code-difference
    http://www.aspsnippets.com/Articles/Call-ASPNet-Page-Method-using-jQuery-AJAX-Example.aspx

  • ข้อแตกต่างระหว่างการลงนามเอกสารด้วย Electronic Signature กับ Digital Signature

    ที่ผ่านมาได้มีโอกาสเดินทางไปดูงานระบบเอกสารอิเล็กทรอนิกส์ของหน่วยงานภาครัฐในภาคตะวันออกเฉียงเหนือ และภาคกลางด้วยความอยากรู้ว่าหน่วยงานอื่นๆ เขาพัฒนาระบบนี้กันไปถึงไหนแล้ว เพื่อจะได้นำมาเป็นแนวทางในการพัฒนาปรับปรุงระบบของม.อ.เราต่อไป จากการดูงานที่ผ่านมาพบว่า ระบบที่มีการใช้งานกันส่วนใหญ่ยังไม่ได้รับการพัฒนาให้รองรับงานด้านสารบรรณอย่างเต็มรูปแบบสักเท่าไหร่ บางที่ยังเป็นแค่ระบบที่ใช้ในการเก็บเอกสารแต่ยังไม่สามารถติดตามการดำเนินการต่างๆ ที่เกิดขึ้นกับเอกสารเรื่องนั้นๆ ได้ ซึ่งต่างจากของม.อ. เราที่สามารถติดตามเส้นทางการดำเนินการต่างๆ ที่เกิดขึ้นได้ทั้งหมด

    และเป็นที่ทราบกันดีว่าวัตถุประสงค์หลักของระบบเอกสารอิเล็กทรอนิกส์คือ การดำเนินการต่างๆ ด้านงานสารบรรณทั้งหมดในรูปแบบไฟล์อิเล็กทรอนิกส์แทนการใช้งานกระดาษ นั่นหมายความว่าเป้าหมายที่สำคัญของระบบนี้คือการดำเนินการทั้งหมดจะต้องดำเนินการผ่านระบบคอมพิวเตอร์ได้ 100% โดยไม่มีการใช้กระดาษเลย แต่ในปัจจุบันระบบยังไม่สามารถทำแบบนั้นได้ โดยเฉพาะในเรื่องของการลงนามเอกสาร เนื่องจากผู้ใช้ยังไม่มั่นใจรูปแบบการลงนามเอกสารในรูปแบบอิเล็กทรอนิกส์เท่าที่ควร จึงเลือกที่จะพิมพ์เอกสารเป็นกระดาษแล้วลงนามกันด้วยปากกาเช่นเดิม อย่างไรก็ตามเทคโนโลยีนี้กำลังจะได้รับการยอมรับมากยิ่งขึ้น เนื่องจากมีกฎหมายออกมารองรับ และสามารถใช้เป็นหลักฐานในชั้นศาลได้แล้ว

    จากการเดินทางไปศึกษาดูงานพบว่ามีระบบของสถาบันแห่งหนึ่งในภาคกลาง มีความสามารถในการลงนามเอกสาร โดยผู้ใช้จะต้องใช้รหัสผ่านที่ 2 เพื่อยืนยันตัวตนอีกครั้งหนึ่งก่อนการลงนาม จากนั้นระบบจะดึงรูปภาพลายเซ็นของผู้ลงนามมาแปะลงในเอกสารตามตำแหน่งที่กำหนดไว้ ข้อดีของวิธีการนี้คือในเอกสารจะมีรูปภาพลายเซ็นแปะอยู่ ทำให้ผู้อ่านคนอื่นๆ รับทราบได้ทันทีว่าใครเป็นคนลงนาม แต่ข้อเสียคือ รูปภาพลายเซ็นดังกล่าวสามารถคัดลอกแล้วนำไปแปะในเอกสารอื่นๆ ได้ง่าย จึงทำให้การลงนามแบบนี้ยังขาดคุณสมบัติด้านความปลอดภัย

    จากการศึกษาข้อมูลจากแหล่งต่างๆ พบว่าวิธีการในการลงนามเอกสารแบบอิเล็กทรอนิกส์นั้นมี 2 วิธีหลักๆ คือ  Electronic signature และ Digital Signature ซึ่งมีความหมายและข้อแตกต่างกันดังนี้

    Electronic Signature

    เป็นการทำสัญลักษณ์ หรือลายเซ็นที่อยู่ในรูปแบบอิเล็กทรอนิกส์โดยบุคคล เพื่อเป็นการยืนยันหรือลงนามในเอกสาร สัญลักษณ์ที่นิยมใช้กันได้แก่ รูปภาพลายเซ็นที่เซ็นด้วยหมึกปากกาลงในกระดาษแล้วสแกนเข้าสู่ระบบคอมพิวเตอร์ การใช้เมาส์ หรือนิ้วมือ หรือ stylus วาดรูปลายเซ็นบนหน้าจอคอมพิวเตอร์ ลายเซ็นที่แนบท้ายอีเมล์ การพิมพ์ชื่อด้วยคีย์บอร์ด รูปภาพลายนิ้วมือ การคลิก “I Agree” ใน Electronic form ต่างๆ เป็นต้น

    [ที่มา : https://www.signinghub.com/electronic-signatures]
    [ที่มา : https://www.signinghub.com/electronic-signatures]

    Digital Signature

    Digital Signature เป็น Subset ของ Electronic Signature เนื่องจากเป็นลายเซ็นที่อยู่ในรูปแบบของอิเล็กทรอนิกส์เหมือนกัน แต่ได้เพิ่มเติมคุณสมบัติด้านความปลอดภัยเข้าไป เพื่อให้มีความน่าเชื่อถือมากยิ่งขึ้น คุณสมบัติดังกล่าวประกอบด้วย

    1. Signer Authentication เป็นความสามารถในการพิสูจน์ว่าใครเป็นคนเซ็นเอกสาร ตัวลายเซ็นจะสามารถใช้ในการเชื่อมโยงไปยังบุคคลที่เซ็นเอกสารได้
    2. Data Integrity เป็นความสามารถในการตรวจสอบ หรือพิสูจน์ได้ว่ามีการแก้ไขเอกสารหลังจากที่ได้มีการเซ็นไปแล้วหรือไม่
    3. Non-repudiation การไม่สามารถปฏิเสธความรับผิดชอบได้ เนื่องจากลายเซ็นที่สร้างขึ้นมีเอกลักษณ์ สามารถพิสูจน์ในชั้นศาลได้ว่าใครเป็นผู้เซ็นเอกสาร

    [ที่มา : https://www.signinghub.com/electronic-signatures]
    สรุปข้อดีข้อเสียของ Electronic Signatures และ Digital Signature

    ข้อดี ข้อเสีย
    Electronic Signature – ใช้สัญลักษณ์ หรือรูปภาพลายเซ็นที่ผู้ใช้สามารถเห็นได้ง่าย ทำให้ทราบได้ว่าใครเป็นเจ้าของลายเซ็น (ทราบได้จากการดูรูปลายเซ็น) – ถูกคัดลอกจากเอกสารฉบับหนึ่งไปยังอีกฉบับหนึ่งได้ง่าย

    – ไม่สามารถตรวจจับการแก้ไขเนื้อหา หรือข้อความในเอกสารที่เกิดขึ้นหลังจากการเซ็นได้

    – วิธีการนี้ยังขาดความชัดเจน ไม่สามารถพิสูจน์ได้ว่าเจ้าของลายเซ็นเป็นผู้ลงนามจริงหรือไม่ จึงอาจโดนปฏิเสธความรับผิดชอบในชั้นศาลได้

    Digital Signature – เอกสารที่ผ่านการเซ็นแล้วจะไม่สามารถแก้ไขได้ หากมีการแก้ไขก็จะสามารถตรวจสอบได้ และส่งผลให้ลายเซ็นหมดสภาพไป

    – ผู้เซ็นเอกสารสามารถกำหนดระดับความน่าเชื่อถือได้

    – ผู้เซ็นเอกสารจะไม่สามารถปฏิเสธความรับผิดชอบได้

    – สามารถใช้เป็นหลักฐานในชั้นศาลได้เทียบเท่ากับการเซ็นเอกสารในกระดาษด้วยหมึกปากกา

    – ขึ้นอยู่กับการเข้ารหัสลับ และมีความยุ่งยากในการเชื่อมโยงกับลายเซ็นบนกระดาษ

     

    จะเห็นว่าการลงนามเอกสารแบบอิเล็กทรอนิกส์ทั้ง 2 วิธีนั้น มีข้อดี และข้อเสียต่างกัน การเลือกรูปแบบไหนมาใช้ในการพัฒนานั้นก็ขึ้นอยู่กับว่าเราต้องการให้ระบบเราทำอะไรได้บ้าง เมื่อพิจารณาจากความต้องการของผู้ใช้งานระบบเอกสารอิเล็กทรอนิกส์มหาวิทยาลัยสงขลานครินทร์ พบว่ามีความต้องการให้สามารถลงนามเอกสารผ่านระบบได้ และแนวทางที่เหมาะสมคือการนำข้อดีของทั้ง 2 วิธีมารวมกันเพื่อใช้ในการพัฒนาต่อไป

     

    แหล่งข้อมูลอ้างอิง : https://www.signinghub.com/electronic-signatures/

  • Convert Solution Visual Studio 2005 to 2013

    ในบทความนี้ ผู้เขียนจะขอกล่าวถึงเครื่องมือในการพัฒนาตัวหนึ่งที่ชื่อว่า Visual Studio โดยจะนำเสนอวิธีการ Convert Solution ASP.NET จากเวอร์ชั่นเก่าไปยังเวอร์ชั่นใหม่โดยไม่ต้องสร้างโปรเจคขึ้นมาใหม่ ตัวอย่างในวันนี้จะแสดงการ Convert Project Solution ที่พัฒนาด้วย Visual Studio 2005 ไปพัฒนาบน Visual Studio 2013 ซึ่งแน่นอนครับว่าจะต้องมีการ config ค่าเพิ่มเติมต่างๆ ผู้เขียนจะกล่าวไว้ช่วงท้ายนะครับ เราเริ่มขั้นตอนการ Convert กันเลยดีกว่าครับ

    ขั้นตอนแรก : เตรียมข้อมูลให้พร้อม

    1. เตรียม solution ตัวเก่าของเราให้พร้อม (ในที่นี้เราใช้ solution ของ Visual Studio 2005 ชื่อ GSMISII )

    Capture

    รูปที่ 1 Folder Project Solution Visual Studio 2005

    Capture2

    รูปที่ 2 ไฟล์ Project Solution Visual Studio 2005

         2. เตรียม Visual Studio 2013 ให้พร้อม

    Capture3

    รูปที่ 3 Visual Studio 2013

    ขั้นตอนที่สอง : เริ่ม Convert

          1. เราจะทำการ Convert Solution โดยคลิกขวาไฟล์ Solution ( xxx.sln ) ตามรูปที่ 2 เลือก Open with… ก็จะปรากฎดังรูป

    Capture4

    รูปที่ 4 Keep using Microsoft Visual Studio Version Selector

     

    2. เลือก Keep using Microsoft Visual Studio Version Selector

    Capture5

    รูปที่ 5 Review Project And Solution Changes

         3. Visual Studio จะตรวจสอบว่ามีโปรเจคหรือ Solution ใดบ้าง ตามตัวอย่างมีแค่ 1 Solution กด OK

    Capture10

    รูปที่ 6 Loading solution projects…

          กรณีมีการใช้ Crystal Report จะมีการให้ Backup ก่อนที่จะ Convert (ซึ่งหากต้องการใช้ Crystal Report จะต้องลง SAP Version ที่รองรับกับ Visual Studio 2013 ก่อน)Capture11

    รูปที่ 7 Loading solution projects…

         กรณีที่มีการใช้ Source Control จะมีให้เลือกว่าจะ remove ออกหรือไม่

    Capture9

    รูปที่ 8 Source Control remove

         เสร็จเรียบร้อยแล้ว… จริงหรือ??

    Capture12 

    รูปที่ 9 Solution in Visual Studio 2013

         เรามาลอง Build Solution กันดีกว่า…

    Capture13

    รูปที่ 10 Error Build Solution 

        Oops! Error!!  ไม่ต้องตกใจกันนะครับ เพราะ error พวกนี้ส่วนใหญ่จะเป็นค่า config ที่อยู่ใน file web.config ที่ไม่รองรับกับ control เวอร์ชั่นใหม่อยู่แล้ว ซึ่งรวมไปถึง crystal report ด้วย ตามแก้ให้เรียบร้อย (ใช้ความอดทนเล็กน้อย ให้สังเกตุว่า error assembly ตัวใด สังเกตุเวอร์ชั่นด้วย) แล้วลอง Build ใหม่กันอีกครั้ง

         ปล. สำหรับ Crystal Report สำหรับ Visual Studio 2013 สามารถ Download ได้ที่
    http://scn.sap.com/docs/DOC-7824

  • จับตา Bootstrap 4 Beta

    เมื่อช่วงเดือนสิงหาคม 2015 ผู้พัฒนา Bootstrap ได้เปิดตัว Bootstrap 4 Beta ออกมาให้ผู้พัฒนาเว็บไซต์ได้ทดลองใช้งานกัน โดยได้มีการแก้ไข bug ที่เจอในเวอร์ชั่น 3 และเพิ่มเติมความสามารถต่างๆ เข้าไป ทำให้การพัฒนาเว็บไซต์สามารถทำได้ง่าย และเป็นที่น่าสนใจได้มากขึ้น โดยในเวอร์ชั่นนี้มีการปรับปรุงจากเวอร์ชั่น 3 ค่อนข้างเยอะ แต่ที่เด่นๆ ได้แก่

    bootstrap 4

     

    • ใช้ Sass แทน Less ทำให้ compile ได้เร็วขึ้น ข้อดีของการใช้ Sass คือการมี community ขนาดใหญ่เป็นตัวช่วยสำหรับนักพัฒนาในการค้นคว้าหาความรู้เพิ่มเติม หรือขอความช่วยเหลือต่างๆ จาก community ได้
    • ปรับปรุง Grid System ให้รองรับกับขนาดหน้าจอของอุปกรณ์ต่างๆ ให้มากยิ่งขึ้น
    • สนับสนุนการใช้งาน flexbox grid system และ component
    • ใช้ Card component แทนการใช้ wells, thumbnails และ panel
    • รวม HTML Reset ทั้งหมดไว้ใน Module เดียวกันชื่อ Reboot
    • เพิ่ม option ในการ customize ก่อนการดาวน์โหลดมาใช้งาน เช่นการกำหนด gradients, transitions, shadows ให้กับ component ต่างๆ โดยเก็บไว้ในตัวแปร Sass แล้ว recompile เป็น CSS มาใช้งาน
    • ยกเลิกการสนับสนุน IE8 แล้ว ส่งผลทำให้เราสามารถใช้ประโยชน์จาก Style sheet ได้อย่างเต็มประสิทธิภาพ และในเวอร์ชั่นนี้ก็ได้เปลี่ยนการใช้งานหน่วย pixel มาเป็น rems และ ems แทน เนื่องจากหน่วยทั้ง 2 แบบนี้ จะช่วยให้การพัฒนาเว็บไซต์ในรูปแบบ Responsive ทำได้ง่ายขึ้น ทั้งในส่วนของ Typography และ component sizing แต่ถ้าหากยังอยากให้เว็บไซต์รองรับ IE8 ด้วย ทางผู้พัฒนา Bootstrap แนะนำว่าให้ใช้ Bootstrap Version 3 ตามเดิม
    • เขียน Javascript plugin ใหม่ทั้งหมด
    • ปรับปรุง auto-placement หรือการจัดวางตำแหน่งของ tooltips และ popovers
    • ปรับปรุงเอกสาร Documentation ให้อ่าน และค้นหาได้ง่ายขึ้น
    • และอื่นๆ เช่น Custom form control, มีคลาสสำหรับ margin และ padding ให้ใช้งานได้ง่ายขึ้น และ Utility Class สำหรับอำนวยความสะดวกในการพัฒนาเว็บไซต์ เป็นต้น

     

    จะเห็นว่าจากรายการที่เปลี่ยนแปลงต่างๆข้างต้นนั้นมีความน่าสนใจมาก ทางผู้พัฒนาจึงได้สร้างเว็บไซต์ตัวอย่างไว้ให้ดูโดยสามารถดูได้จาก http://expo.getbootstrap.com/

  • การใช้ LINQ ในการจัดการข้อมูลอย่างง่าย สำหรับมือใหม่(Ep.1)

              ก่อนที่จะไปถึงในส่วนของวิธีการจัดการข้อมูลด้วย LINQ เรามาพูดถึงที่มาที่ไปอย่างคร่าวๆ ของ LINQ กันสักเล็กน้อยนะคะ LINQ มีชื่อเต็มว่า “Language-Intergrated Query” ถือเป็นภาษาใหม่ที่ขยายความสามารถในการเขียนโปรแกรมโดยเลียนแบบภาษา SQL จึงทำให้มีการใช้งาน keyword ที่คุ้นเคยกันดีในคำสั่ง SQL เช่น select from where เป็นต้น ซึ่งมีความนิยมกับการทำงานด้านฐานข้อมูลมากขึ้นในปัจจุบัน และได้ถูกนำมารวมกับภาษาพัฒนาโปรแกรมทำให้การพัฒนาโปรแกรมควบคุมข้อมูลให้อยู่ในแนวการเขียนโปรแกรมเดียวกัน และช่วยอำนวยความสะดวกรวมถึงเพิ่มความคล่องตัวให้กับผู้พัฒนาในการจัดการข้อมูลมากยิ่งขึ้น โดย LINQ นี้ถูกนำมาใช้ตั้งแต่ .NET Framework 3.5 ที่มากับ Visual studio 2008 ซึ่งจะมีการติดต่ออยู่ด้วยกัน 3 ประเภท คือ

    • ข้อมูลประเภท Object
    • ข้อมูลประเภทฐานข้อมูลเชิงสัมพันธ์ ซึ่งมีรูปแบบการใช้งานแตกต่างกันไป จึงแยกออกเป็น
      • LINQ to Dataset
      • LINQ to SQL
      • LINQ to Entity
    • ข้อมูล XML

              โดยในบทความนี้ผู้เขียนจะขอแยกวิธีการจัดการข้อมูลออกเป็นเรื่องๆ ที่ถือเป็นพื้นฐานที่มือใหม่ควรรู้ และเน้นยกตัวอย่างหลายๆกรณีเพื่อให้ผู้อ่านเข้าใจการทำงาน และมีแนวทางในการนำไปใช้มากขึ้น ดังนี้

    • การดึงข้อมูลแบบทั่วไปโดยใช้คำสั่ง Select

    ตัวอย่างที่ 1 : กรณีดึงข้อมูลจาก Object มาแสดง

    List<Customer> customers= GetCustomer ();
    var qCustomers = from cust in customers
    select cust;
    

    คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นว่า มีการใช้คำสั่ง select ในการดึงข้อมูลจาก object list ของ class ที่มีชื่อว่า Customer ทั้งหมดมาใส่ในตัวแปร qCustomers โดยมีการประกาศเป็น var ไว้ เนื่องจาก LINQ เองจะสามารถแปลงค่าของข้อมูลตัวแปรที่รับมาโดยไม่ต้องมีการระบุชนิดของข้อมูล และ compiler จะทำการแปลงรูปแบบและชนิดของตัวแปรได้อัตโนมัติ โดยสามารถนำผลลัพธ์ที่ได้มาวนแสดง ดังนี้

    Console.WriteLine("Customer name list:");
    foreach (var custlist in qCustomers )
    {
    Console.WriteLine(custlist.name);
    }

    ตัวอย่างที่ 2 : กรณีจากตัวแปรอาร์เรย์

    int[] numbers = { 2,7,5,3,1,6 };
    var result = from n in numbers
    select n -1;
    Console.WriteLine("Result:");
    foreach (var i in result)
    {
    Console.WriteLine(i);
    }
    

    คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นว่า มีการใช้คำสั่ง select ในการดึงข้อมูลจากตัวแปรอาร์เรย์ที่มีชื่อว่า numbers ทั้งหมดมาใส่ในตัวแปร result โดยเพิ่มเติมให้มีการนำค่าที่ดึงมาได้ -1 และนำมาวนแสดง

    ผลลัพธ์ที่ได้ : 1 6 4 2 0 5

    ตัวอย่างที่ 3 : การแปลงค่าข้อมูลจากตัวแปรอาร์เรย์ที่มีชนิดเป็น string ให้เป็นตัวอักษรพิมพ์เล็กและพิมพ์ใหญ่ ดังนี้

    string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
    var upperLowerWords =
    from w in words
    select new { Upper = w.ToUpper(), Lower = w.ToLower() };
    foreach (var ul in upperLowerWords)
    {
    Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower);
    }
    

    คำอธิบาย : เป็นการนำข้อมูลจากตัวแปรอารย์เรย์ที่เป็นชนิด string มาแปลงเป็นตัวอักษรพิมพ์ใหญ่และกำหนดให้อยู่ในฟิลด์ใหม่ที่มีชื่อว่า Upper และแปลงอักษรที่อ่านได้เป็นตัวพิมพ์เล็กให้อยู่ในฟิลด์ใหม่ที่มีชื่อว่า Lower โดยเมื่อมีการเรียกใช้เพื่อดึงค่ามาแสดง เราสามารถเรียกใช้ผ่านทางชื่อที่เรากำหนดขึ้นใหม่ได้ เช่น ul.Upper นั่นเอง

    ผลลัพธ์ที่ได้ :
    Uppercase: APPLE, Lowercase: apple
    Uppercase: BLUEBERRY, Lowercase: blueberry
    Uppercase: CHERRY, Lowercase: cherry

    • การค้นหาข้อมูลโดยใช้ Where เพื่อเป็นการเพิ่มเงื่อนไขในการดึงข้อมูล ซึ่งมีทั้งวิธีที่ใช้ operator ที่มีชื่อว่า Where และแบบที่ใช้ เมธอด Where ซึ่งจะอธิบายและยกตัวอย่างดังนี้

    ตัวอย่างที่ 1 : เป็นการดึงข้อมูลสินค้าที่หมดในสต็อก โดยใช้ operator ที่มีชื่อว่า Where

    List<Product> products = GetProductList();
    var soldOutProducts = from p in products
     where p.UnitsInStock == 0
    select p;
    
    Console.WriteLine("Sold out products:");
    foreach (var product in soldOutProducts)
    {
    Console.WriteLine("{0} is sold out!", product.ProductName);
    }
    

    คำอธิบาย : เป็นการดึงข้อมูลจาก object list ของคลาส Product มาแสดง โดยใช้ operator ที่ชื่อว่า Where ซึ่งมีลักษณะการใช้งานคำสั่งคล้ายกับในการเขียนคำสั่ง SQL ซึ่งเงื่อนไขที่ใช้ในการดึงข้อมูลคือจะต้องมีจำนวนใน stock เป็น 0 และนำชื่อของสินค้าที่หมดในสต็อกมาวนแสดงโดยเรียกใช้ properties ที่ชื่อว่า ProductName

    ตัวอย่างที่ 2 : เป็นลักษณะการดึงข้อมูลแบบมีเงื่อนไขโดยใช้เมธอด Where

    string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
    var shortDigits = digits.Where((digit, index) => digit.Length < index);
    
    Console.WriteLine("Short digits:");
    foreach (var d in shortDigits)
    {
    Console.WriteLine("The word {0} is shorter than its value.", d);
    }
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการดึงข้อมูลตามเงื่อนไข ด้วยเมธอด Where ซึ่งเงื่อนไขข้างต้นจะดึงข้อมูลเฉพาะรายการที่มีความยาวของตัวอักษรน้อยกว่าค่า index ของข้อมูลอาร์เรย์

    • การเรียงลำดับข้อมูล

    ตัวอย่างที่ 1 : เป็นการเรียงลำดับข้อมูลโดยทั่วไป ด้วยคีย์เวิร์ด Order by

    var movies = from row in _db.Movies
    orderby row.Category, row.Name descending
    select row;
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการดึงข้อมูลโดยมีการเรียงลำดับข้อมูลตามฟิลด์ Category และ Name ที่มีการเรียงลำดับจากมากไปน้อย ตามลำดับ โดย keyword ที่ใช้ในการเรียงลำดับ คือ เรียงจากน้อยไปมากใช้ ascending แต่หากต้องการเรียงลำดับจากมากไปน้อยให้ใช้ descending แต่หากไม่ระบุลักษณะการเรียงลำดับไว้ จะมีค่าตั้งต้นเป็นการเรียงลำดับจากน้อยไปมาก(ascending) นั่นเอง

    ตัวอย่างที่ 2 : เป็นการเรียงลำดับของข้อมูลมากกว่า 1 คอลัมน์ ด้วยเมธอด OderBy และ ThenBy

    var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการดึงข้อมูลโดยมีการเรียงลำดับข้อมูลตามฟิลด์ Category และ Name ที่มีการเรียงลำดับจากมากไปน้อย ตามลำดับ โดยใช้เมธอด OrderBy ตามด้วย ThenBy

    • การจัดกลุ่มข้อมูล Group by

    ตัวอย่างที่ 1 :

    var orderGroups =
    from p in products
    group p by p.Category into g
    select new { Category = g.Key, Products = g };
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการจัดกลุ่มข้อมูลด้วยฟิลด์ Category โดยใช้คีย์เวิร์ด group by

    ตัวอย่างที่ 2 :

    var query = source.GroupBy(x => new { x.Column1, x.Column2 });
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการดึงข้อมูลแบบมีการจัดกลุ่มโดยใช้เมธอด GroupBy แบบมากกว่า 1 คอลัมน์

              สำหรับบทความนี้ ผู้เขียนจะขอพูดถึงการใช้งานพื้นฐานของการเขียน LINQ เบื้องต้นไว้เพียงเท่านี้ก่อน แต่ในความเป็นจริงแล้วประโยชน์และความสามารถของ LINQ นี้ยังมีอีกมากมาย ซึ่งผู้เขียนจะขอหยิบยกและพูดถึงเพิ่มเติมในหัวข้อที่คิดว่าผู้พัฒนาน่าจะนำไปใช้ประโยชน์ได้เพิ่มเติมในบทความถัดไป(Ep.2) เช่น การกำจัดข้อมูลที่ซ้ำกัน การคำนวณค่าผลรวม และการเชื่อมข้อมูล(join) ตาราง เป็นต้น หากบทความนี้มีเนื้อหาหรือส่วนใดของบทความผิดพลาด ผู้เขียนขออภัยไว้ ณ ที่นี้ด้วย ทั้งนี้ผู้อ่านสามารถเสนอแนะและแลกเปลี่ยนความคิดเห็นร่วมกันได้ ขอบคุณค่ะ
    ปล.อย่าลืมติดตามเนื้อหาต่อใน Ep.2 นะคะ ^^

    แหล่งข้อมูลอ้างอิง :
    https://code.msdn.microsoft.com/LINQ-Restriction-Operators-b15d29ca
    http://stackoverflow.com/questions/847066/group-by-multiple-columns

  • ทำอย่างไรให้สามารถกำหนดจุดพิกัดบนแผนที่ Google map แบบจุดเดียวและหลายจุดจากฐานข้อมูลได้ด้วย ASP.NET C# (ภาคต่อ)

                 จากบทความที่แล้ว ผู้เขียนได้เขียนไว้เกี่ยวกับเรื่องวิธีการกำหนดจุดพิกัดบนแผนที่กันไปบ้างแล้ว ในหัวข้อ “ทำอย่างไรให้สามารถกำหนดจุดพิกัดบนแผนที่ Google map แบบจุดเดียวและหลายจุดจากฐานข้อมูลได้ด้วย ASP.NET C#” สำหรับในบทความนี้ผู้เขียนจึงขอพูดถึงในส่วนของการดึงค่าละติจูด ลองจิจูดของสถานที่ ซึ่งนับว่าเป็นส่วนประกอบสำคัญในการแสดงผลพิกัดบนแผนที่ ซึ่งเดิมทีแล้วนั้น ผู้ใช้อาจต้องค้นหาข้อมูลพิกัดดังกล่าวจาก Google map เองและนำพิกัดดังกล่าวมากรอกลงฐานข้อมูลหรือมาระบุเพื่อการแสดงพิกัดนั้นๆในการเขียนโปรแกรม คงเป็นการดี หากการแสดงผลพิกัดจากฐานข้อมูลนั้น จะมีตัวช่วยอำนวยความสะดวกให้กับผู้ใช้ในการดึงค่าละติจูด และลองจิจูดโดยการกรอกข้อมูลชื่อสถานที่ลงไปเพื่อใช้ในการค้นหา ซึ่งน่าจะเป็นประโยชน์และทำให้ผู้ใช้สามารถใช้งานได้ง่ายขึ้นในการนำพิกัดเหล่านั้นไประบุบนแผนที่นั่นเอง

                 โดยการดึงค่าพิกัดละติจูด-ลองจิจูดของสถานที่ สามารถทำได้หลายวิธี ขึ้นอยู่กับการนำไปประยุกต์ใช้ ซึ่งในบทความนี้ผู้เขียนขอแนะนำ 2 วิธี ดังนี้

    • การเรียกใช้เซอร์วิสของ Google Geocoding API  โดยการส่งพารามิเตอร์เป็นที่อยู่ของสถานที่ดังกล่าว

    ฝั่ง C#

        private void getLatAndLong()
        {
            try
            {
             ////เป็นการกำหนด url ที่จะใช้ในการเรียกเซอร์วิสของ Google Geocoding API 
    โดยมีการส่งค่าพารามิเตอร์เป็นข้อมูลที่อยู่
                string url = "http://maps.google.com/maps/api/geocode/xml?address=" + txtLocation.Text + "&sensor=false";
                WebRequest request = WebRequest.Create(url);
                using (WebResponse response = (HttpWebResponse)request.GetResponse())
                {
            ////ผลลัพธ์จะอยู่ในรูปแบบของ XML หรือ JSON และจะถูกอ่านให้อยู่ในรูปแบบ Dataset 
    โดยใช้ StreamReader
                     using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                    {
                        DataSet dsResult = new DataSet();
                        dsResult.ReadXml(reader);
           ////จัดทำโครงสร้างตาราง(datatable) ที่จะใช้ในการแสดงผลใน Gridview
                        DataTable dtCoordinates = new DataTable();
                        dtCoordinates.Columns.AddRange(new DataColumn[4] { new DataColumn("Id", typeof(int)),
                            new DataColumn("Address", typeof(string)),
                            new DataColumn("Latitude",typeof(string)),
                            new DataColumn("Longitude",typeof(string)) });
    
           ////ดึงค่าผลลัพธ์จากตารางต่างๆ เพื่อนำค่าที่จำเป็นมาแสดงผลตามต้องการ
                        foreach (DataRow row in dsResult.Tables["result"].Rows)
                        {
                            string geometry_id = dsResult.Tables["geometry"].Select("result_id = " + row["result_id"].ToString())[0]["geometry_id"].ToString();
                            DataRow location = dsResult.Tables["location"].Select("geometry_id = " + geometry_id)[0];
                             dtCoordinates.Rows.Add(row["result_id"],  row["formatted_address"], location["lat"], location["lng"]);
                        }
           ////แสดงผลข้อมูลของค่าที่ดึงมาได้ใน Gridview (ถ้ามี)
                        if (dtCoordinates.Rows.Count > 0)
                        {
                            gvLatLong.DataSource = dtCoordinates;
                            gvLatLong.DataBind();
                        }
                        else
                        {
                            gvLatLong.DataSource = null;
                            gvLatLong.DataBind();
                            ScriptManager.RegisterStartupScript(Page, Page.GetType(), "alert", "alert('Can not find Latitude and Longitude!'); ", true);
    
                        }
                    }
                }
            }
            catch (Exception ex) {
                ScriptManager.RegisterStartupScript(Page, Page.GetType(), "alert", "alert('Can not find Latitude and Longitude!'); ", true);
                gvLatLong.DataSource = null;
                gvLatLong.DataBind();
            }
        
        }
     protected void btnSearch_Click(object sender, EventArgs e)
     {
        getLatAndLong();
     }
    

                 จากโค้ดข้างต้น เป็นการค้นหาละติจูด-ลองจิจูดจากที่อยู่ของสถานที่นั้นๆ โดยใช้ Google Maps Geocoding API ซึ่งเซอร์วิสของ Google Geocoding API มีการส่งค่าโดยใช้ WebRequest โดยจะรับค่าที่อยู่ของสถานที่เป็นพารามิเตอร์และส่งกลับเป็นพิกัดและข้อมูลอื่นๆมาในรูปแบบของ XML หรือ JSON นั่นเอง และค่าที่ส่งกลับมาในรูปแบบ XML นั้นจะถูกอ่านให้อยู่ในรูปแบบ Dataset โดยใช้ StreamReader ซึ่งค่าที่ส่งกลับมานั้นจะมีด้วยกันหลายตาราง และมีการดึงค่าข้อมูลที่เกี่ยวข้องที่จะนำมาใช้เพิ่มลงในตารางที่ถูกสร้างขึ้นใหม่ และนำไปแสดงในกริดวิวนั่นเอง

    ฝั่ง .aspx (Client side)

    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
     <title>GetLatitude-Longitude</title>
    <!-- การอ้างอิงเพื่อให้สามารถเรียกใช้งาน Autocomplete ได้-->
     <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
    </head>
    <body>
     <form id="form1" runat="server">
     <div>
     <asp:TextBox ID="txtLocation" runat="server" Width="450px"></asp:TextBox><asp:Button ID="btnSearch" runat="server" Text="Search" OnClick="btnSearch_Click" />
     </div>
     <br />
     <div>
     <asp:GridView ID="gvLatLong" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None">
     <AlternatingRowStyle BackColor="White" />
     <EditRowStyle BackColor="#2461BF" />
     <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
     <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
     <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
     <RowStyle BackColor="#EFF3FB" />
     <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
     <SortedAscendingCellStyle BackColor="#F5F7FB" />
     <SortedAscendingHeaderStyle BackColor="#6D95E1" />
     <SortedDescendingCellStyle BackColor="#E9EBEF" />
     <SortedDescendingHeaderStyle BackColor="#4870BE" />
     </asp:GridView>
     </div>
     </form>
     <script type="text/javascript">
     google.maps.event.addDomListener(window, 'load', function () {
    ////การกำหนดคอนโทรล textbox ที่จะเพิ่มความสามารถ place auto-complete 
    เพื่อให้สามารถค้นหาสถานที่ตั้งได้ง่ายขึ้นเมื่อผู้ใช้พิมพ์ข้อมูลชื่อสถานที่ในกล่อง textbox
     var txtplaces = document.getElementById('<%= txtLocation.ClientID %>');
     var places = new google.maps.places.Autocomplete(document.getElementById('<%= txtLocation.ClientID %>'));
     });
     </script>
    </body>
    </html>
    

                 จากโค้ดข้างต้น นอกจากจะเป็นการเรียกใช้เซอร์วิสโดยการคลิกปุ่ม “btnSearch” และรับค่าข้อมูลที่อยู่จากกล่อง textbox แล้ว ยังมีการเพิ่มส่วนของการเพิ่มความสามารถในการค้นหาข้อมูล “ที่อยู่” โดยการกรอกข้อมูล “ชื่อสถานที่” โดยใช้ feature ที่มีของ Google Places API (หรืออาจเรียกว่า place Autocomplete ) เนื่องจากหากมีการเรียกใช้เซอร์วิสดังกล่าวโดยตรง ผู้ใช้จำเป็นที่จะต้องกรอกข้อมูล “ที่อยู่” เพื่อเป็นพารามิเตอร์ให้กับเซอร์วิสที่เรียกใช้ให้ส่งค่าผลลัพธ์กลับมา ซึ่งความน่าจะเป็นที่ผู้ใช้จะสามารถทราบข้อมูลชื่อสถานที่นั้นย่อมเป็นไปได้มากกว่าการทราบข้อมูลที่อยู่ของสถานที่นั้นๆ ผู้เขียนจึงนำมาประยุกต์ใช้งานเข้าด้วยกันกับการเรียกเซอร์วิสที่กล่าวไว้แล้วก่อนหน้านั่นเอง โดยจะแนะนำวิธีการใช้งานเพิ่มเติมในหัวข้อต่อจากนี้

     เพิ่มเติม :
      Place Autocomplete: เป็นfeature ที่มีของ Google Places API เปรียบเสมือนตัวช่วยคำค้นเมื่อมีการป้อนข้อมูลชื่อสถานที่ลงไป โดย feature ดังกล่าวจะแสดงข้อมูลสถานที่ที่ใกล้เคียงกับคำค้นขึ้นมาให้กับผู้ใช้ได้เลือกนั่นเอง

    โดยมีวิธีการเรียกใช้ place autocomplete  ดังนี้
    1. อ้างอิงการเพื่อเรียกใช้งาน Google Places API

    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>

    2. กำหนดคอนโทรล textbox ที่ต้องการเพิ่มความสามารถ place autocomplete

     var input = document.getElementById('<%= txtSearch.ClientID %>');
     var div = document.getElementById('result');
     var autocomplete = new google.maps.places.Autocomplete(input);

    ตัวอย่างหน้าจอที่ได้เมื่อมีการพิมพ์คำค้น

    place_service1

    ผลลัพธ์

    place_service2

    เพิ่มเติม : Namespace ที่ต้องอ้างอิงเพิ่มเติมในการใช้งานโค้ดที่กล่าวไว้ข้างต้น มีดังนี้
                –  System.IO
                –  System.Net
                –  System.Data
                –  System.Text
    • แบบใช้ place Autocomplete ซึ่งเป็น feature ของ Google Places API ที่จะช่วยในการค้นหาที่อยู่จากชื่อสถานที่ได้และประยุกต์เพิ่มเติมเพื่อดึงค่ามาแสดงเมื่อมีการเลือกรายการสถานที่นั้นๆ
    <!DOCTYPE html>
    <html>
     <head>
    <!-- การอ้างอิงเพื่อให้สามารถเรียกใช้งาน Autocomplete ได้-->
     <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
     <title>Place Autocomplete</title>
     <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
     <meta charset="utf-8">
     </head>
     <body>
     <form runat="server">
     <asp:TextBox ID="txtSearch" runat="server" placeholder="Enter a location" Width="350px"></asp:TextBox> 
     <div id="result"></div>
     
     <script>
     function initialize() {
    ////การกำหนดคอนโทรล textbox ที่จะเพิ่มความสามารถ place auto-complete 
    เพื่อให้สามารถค้นหาสถานที่ตั้งได้ง่ายขึ้นเมื่อผู้ใช้พิมพ์ข้อมูลชื่อสถานที่ในกล่อง textbox
     var input = document.getElementById('<%= txtSearch.ClientID %>');
     var div = document.getElementById('result');
     var autocomplete = new google.maps.places.Autocomplete(input);
     google.maps.event.addListener(autocomplete, 'place_changed', function () {
    
    ////ดึงค่าที่ได้เมื่อมีการเลือกรายการจากสถานที่ที่อยู่ที่ขึ้นมา และนำไปใช้ในการแสดงผล
     var place = autocomplete.getPlace();
     if (!place.geometry) {
     return;
     }
     else {
    ////นำค่าที่ดึงได้มาแสดงผลในพื้นที่ที่ต้องการ (result)
     div.innerHTML = '<br><div><strong>' + place.name + '</strong><br>' +
     '<strong>Address :</strong> ' + place.formatted_address + '<br><strong>Latitude :</strong> ' + place.geometry.location.lat() + ' <strong>Longitude:</strong>' + place.geometry.location.lng() + '</div>';
     }
     });
     }
     ////สั่งรันฟังก์ชั่น initialize() ตอนมีการโหลดหน้าจอ
     google.maps.event.addDomListener(window, 'load', initialize); 
     </script>
     </form>
     </body>
    </html>
    

                 จากโค้ดข้างต้น เป็นการดึงค่าละติจูดและลองจิจูดโดยใช้ feature ที่มีของ Google Places API (place Autocomplete) เพื่ออำนวยความสะดวกให้กับผู้ใช้ในการพิมพ์ชื่อสถานที่ลงใน textbox โดย feature นี้จะมีความสามารถในการดึงข้อมูลสถานที่และชื่อที่ใกล้เคียงขึ้นมาแสดงให้ผู้ใช้เลือก(ตามที่ได้กล่าวมาแล้วข้างต้น) และได้มีการสร้าง event เพิ่มเติมเมื่อผู้ใช้เลือกรายการใดขึ้นมา ก็จะมีการเรียกใช้เมธอด getPlace() เพื่อดึงค่าข้อมูลต่างๆมาใช้งานต่อไปรวมถึงค่าละติจูดและลองจิจูดที่เราต้องการใช้ในการกำหนดพิกัดด้วย

    ตัวอย่างหน้าจอการค้นหาข้อมูลที่อยู่ เมื่อมีการพิมพ์คำค้น

    place_auto1

    ผลลัพธ์ที่ได้จากการค้นหา

    place_auto2

                 วิธีการที่ได้กล่าวไว้ในบทความนี้เป็นเพียงแนวทางให้กับผู้พัฒนาสามารถนำไปประยุกต์ใช้ตามความต้องการเท่านั้น ซึ่งผลลัพธ์ที่ได้อาจมีความคลาดเคลื่อนเกี่ยวกับค่าของละติจูด และลองจิจูดเล็กน้อยในบางสถานที่ แต่ยังคงถือว่าอยู่ในเกณฑ์ที่รับได้ เมื่อนำไปลงพิกัดจุดไม่คลาดเคลื่อนหรือแตกต่างกันมากนัก อีกทั้งยังช่วยอำนวยความสะดวกให้กับผู้ใช้ได้ระดับหนึ่งที่จะไม่ต้องไปค้นหาพิกัดจากแหล่งข้อมูลอื่นอีก และผู้เขียนหวังเป็นอย่างยิ่งว่า บทความนี้จะเป็นประโยชน์และช่วยอำนวยความสะดวกให้กับการพัฒนาโปรแกรมที่เกี่ยวกับการกำหนดพิกัดจุดบนแผนที่โดยมีการดึงมาจากฐานข้อมูล หรือการพัฒนาโปรแกรมอื่นๆ ที่จำเป็นต้องมีค่าข้อมูลละติจูดลองจิจูดร่วมด้วยไม่มากก็น้อย หากมีส่วนใดของเนื้อหาบทความที่มีความผิดพลาด ผู้เขียนขออภัยไว้ ณ ที่นี้ และหากท่านใดมีข้อมูลเพิ่มเติม หรือพบวิธีการอื่นๆที่สามารถดึงค่าละติจูด-ลองจิจูดนอกเหนือจากวิธีที่กล่าวมาข้างต้นสามารถชี้แนะและแลกเปลี่ยนประสบการณ์ร่วมกันได้นะคะ ขอบคุณค่ะ ^^

    แหล่งข้อมูลอ้างอิง :
    http://www.aspsnippets.com/Articles/Find-Co-ordinates-Latitude-and-Longitude-of-an-Address-Location-using-Google-Geocoding-API-in-ASPNet-using-C-and-VBNet.aspx
    https://developers.google.com/places/javascript/