Category: Developer

งานพัฒนาระบบ, เขียนโปรแกรม

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

              ความเดิมตอนที่แล้ว… ผู้เขียนได้ทิ้งท้ายไว้เกี่ยวกับเรื่องการใช้งาน LINQ ในการจัดการข้อมูลในเบื้องต้น ได้แก่ วิธีการดึงข้อมูลโดยทั่วไป(Select) การดึงข้อมูลแบบมีเงื่อนไข(Where) และการเรียงลำดับ(OrderBy) เป็นต้น หากใครที่ยังไม่เคยอ่านบทความที่แล้ว และต้องการศึกษาในส่วนดังกล่าวสามารถหาอ่านได้จากลิงค์ “การใช้ LINQ ในการจัดการข้อมูลอย่างง่าย สำหรับมือใหม่(Ep.1)” เพื่อเพิ่มความเข้าใจพื้นฐานในการใช้งานเบื้องต้น LINQ เพิ่มเติม และสำหรับในบทความนี้ ผู้เขียนจะขอพูดถึงการใช้งาน LINQ ในส่วนอื่นๆที่นอกเหนือจากการทำงานทั่วไป ที่คิดว่าน่าจะเป็นประโยชน์กับผู้พัฒนาที่มีความสนใจในการใช้งาน LINQ จัดการข้อมูล ดังนี้

    • การคำนวณค่าร่วม/นับจำนวน

    ตัวอย่างที่ 1 : การคำนวณค่าผลรวมของฟิลด์ที่ดึงข้อมูลโดยใช้เมธอด Sum

    decimal sumLineTotal = (from od in orderdetailscollection
    select od.LineTotal).Sum();
    

    หรือ

    decimal sumLineTotal = orderdetailscollection.Sum(od => od.LineTotal);
    

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

    ตัวอย่างที่ 2 : เป็นการคำนวณค่าเฉลี่ยตามรหัส

    double RatingAverage = ctx.Rates.Where(r => r.Id == Id).Average(r => r.Rating);
    

    หรือ

    var RatingAverage = (from a in ctx.Rates where a. Id.Equals(id)
    select a.Rating).Average();
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการคำนวณหาค่าเฉลี่ยของฟิลด์ Rating โดยใช้เมธอด Average ภายใต้เงื่อนไขรหัส Id ในการดึงข้อมูล

    ตัวอย่างที่ 3 : เป็นตัวอย่างการคำนวณผลรวม และการนับจำนวนแถวของการอ่านข้อมูลโดยมีการจัดกลุ่มข้อมูลร่วมด้วย

    var ListByOwner = list.GroupBy(l => l.Owner)
    .Select(lg => new {
    Owner = lg.Key,
    Boxes = lg.Count(),
    TotalWeight = lg.Sum(w => w.Weight),
    AverageVolume = lg.Average(w => w.Volume)
    });
    

    คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นได้ว่าเป็นการจัดกลุ่มของข้อมูลตาม Owner โดยใช้เมธอด GroupBy และมีการนับจำนวนแถวเก็บไว้ในฟิลด์ Boxes คำนวณผลรวมของคอลัมน์ Weight และหาค่าเฉลี่ยของคอลัมน์ Volume ใส่ในฟิลด์ TotalWeight และ AverageVolume นั่นเอง

    ตัวอย่างที่ 4 : เป็นการนับจำนวนข้อมูลตามเงื่อนไขที่กำหนดโดยใช้เมธอด Count

    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    
    int oddNumbers = numbers.Count(n => n % 2 == 1);
    

    คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นว่า เป็นการดึงค่าจากตัวแปรอาร์เรย์ที่ชื่อว่า numbers และนับจำนวนตัวเลขเฉพาะที่เป็นเลขคี่(หารด้วยสองและมีค่าเศษ 1)เท่านั้นด้วยเมธอด Count ซึ่งในส่วนของเงื่อนไขดังกล่าว ผู้อ่านสามารถนำไปประยุกต์ใช้กับงานของตนในการนับจำนวนข้อมูลได้

    ผลลัพธ์ : จากการอ่านข้อมูลจากตัวแปร numbers ส่งผลให้ oddNumbers มีค่าเท่ากับ 5 นั่นคือในการดึงข้อมูลพบเลขที่มีค่าเป็นเลขคี่ดังนี้ 5,1,3,9,7

    • การค่าที่น้อยที่สุดและมากที่สุดโดยใช้เมธอด Min/Max

    ตัวอย่างที่ 1 : การหาค่าที่น้อยที่สุดโดยใช้เมธอด Min

    string[] words = { "cherry", "apple", "blueberry" };
    
    int shortestWord = words.Min(w => w.Length);
    

    คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นว่า เป็นการอ่านค่าจากตัวแปรอาร์เรย์ที่ชื่อว่า words และหาค่าที่น้อยที่สุดของจำนวนความยาวตัวอักษรจากค่าที่อ่านได้ด้วยเมธอด Min

    ผลลัพธ์shortestWord มีค่าเท่ากับ 5 ซึ่งก็คือค่าความยาวตัวอักษรของคำว่า “apple” ที่มีค่าเท่ากับ 5 ซึ่งเป็นค่าที่น้อยที่สุดนั่นเอง

    ตัวอย่างที่ 2 : เป็นการหาราคาที่ถูกที่สุดจากรายการสินค้าที่อ่านได้แต่ละประเภท(จัดกลุ่มตามประเภทสินค้า) โดยใช้เมธอด Min

    List<Product> products = GetProductList();
    var categories =
    from p in products
    group p by p.Category into g
    select new { Category = g.Key, CheapestPrice = g.Min(p => p.UnitPrice) };
    

    คำอธิบาย : จากตัวอย่างข้างต้น เป็นการหาค่าที่น้อยที่สุดของราคาในคอลัมน์ UnitPrice จาก list ของคลาส Product ที่ดึงมาได้ และมีการจัดกลุ่มตามประเภทของสินค้า นั่นหมายถึง ค่าที่ได้จากการอ่านข้อมูลนี้จะเป็นค่าของราคาสินค้าต่อหน่วยที่น้อยที่สุดในแต่ละประเภทสินค้านั่นเอง

    หมายเหตุ : การใช้งานเมธอด Max จะมีลักษณะการทำงานเช่นเดียวกับเมธอด Min แต่เป็นการหาค่าที่มากที่สุดจากการอ่านข้อมูล ซึ่งผู้อ่านสามารถนำไปใช้แทนกันได้ตามตัวอย่างการใช้งานเมธอด Min ข้างต้นได้

    • การใช้งาน set operator
      • การกำจัดข้อมูลที่ซ้ำกัน

      ตัวอย่างที่ 1 : เป็นการจำกัดข้อมูลที่ซ้ำกันด้วยเมธอด Distinct/DistinctBy

      List<Product> products = GetProductList();
      var categoryNames = (
      from p in products
      select p.Category).Distinct();
      

      หรือ 

      List<Product> products = GetProductList();
      var categoryNames = products.DistinctBy(x=> x.Category);
      

      คำอธิบาย : เป็นการดึงข้อมูลประเภทสินค้าที่ไม่ซ้ำกันไว้ในตัวแปร categoryNames โดยใช้เมธอด Distinct และ DistinctBy (ที่เรียกใช้จาก MoreLinq Library)
      หมายเหตุ : หากต้องการกำจัดข้อมูลที่ซ้ำกันมากกว่า 1 คอลัมน์ สามารถทำได้ ดังนี้

      List<Product> products = GetProductList();
      var categoryNames = products.DistinctBy(a => new { a.Category, a.Code });
      

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

      List<Product> products = GetProductList();
      var categoryNames = products
       .GroupBy(a => a.Category )
       .Select(g => g.First());
      

      คำอธิบาย : เป็นการดึงข้อมูลประเภทสินค้าที่ไม่ซ้ำกันไว้ โดยใช้เมธอดการจัดกลุ่มข้อมูลตามประเภทสินค้าด้วยเมธอด GroupBy และดึงค่าแรกสุดของแต่ละกลุ่มมาแสดงด้วยเมธอด First ตามลำดับ

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

      var total = items.Select(item => item.Value).Distinct().Count();
      

      คำอธิบาย : เป็นการนับจำนวนของข้อมูลที่ไม่ซ้ำกันโดยใช้เมธอด Distinct และเมธอด Count

      • การผสานข้อมูลโดยใช้ Union

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

      int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
      int[] numbersB = { 1, 3, 5, 7, 8 }; 
      var uniqueNumbers = numbersA.Union(numbersB); 
      

      คำอธิบาย : เป็นการรวมข้อมูลจาก 2 แหล่ง ด้วยเมธอด Union
      ผลลัพธ์ : uniqueNumbers = {0, 2, 4, 5, 6, 8, 9,1, 3, 7, 8}

      • การเลือกเฉพาะข้อมูลที่ซ้ำกันจากข้อมูล 2 แหล่งมาแสดงด้วยเมธอด Intersect

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

      var infoQuery =
       (from cust in db.Customers
       select cust.Country)
       .Intersect
       (from emp in db.Employees
       select emp.Country);
      

      คำอธิบาย : เป็นการอ่านข้อมูลจาก 2 ส่วน คือ ในตาราง Customers และ Employees เพื่อเปรียบเทียบค่าคอลัมน์ Country จาก 2 แหล่ง หากมีซ้ำกันทั้ง 2 ที่จะดึงมาเก็บไว้ในตัวแปร infoQuery

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

       int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
       int[] numbersB = { 1, 3, 5, 7, 8 }; 
       
       var commonNumbers = numbersA.Intersect(numbersB); 
      

      คำอธิบาย : เป็นการอ่านข้อมูลจาก 2 ส่วน คือ ในตัวแปรอาร์เรย์ numbersA และ numbersB เพื่อเปรียบเทียบค่า หากมีซ้ำกันทั้ง 2 ที่จะดึงมาเก็บไว้ในตัวแปร commonNumbers
      ผลลัพธ์ : commonNumbers = { 5, 8}

      • การยกเว้นการอ่านข้อมูลโดยใช้ Except

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

       List<Product> products = GetProductList(); 
       List<Customer> customers = GetCustomerList(); 
       
       var productFirstChars = 
       from p in products 
       select p.ProductName[0]; ///ดึงอักษรตัวแรกของชื่อสินค้า
       var customerFirstChars = 
       from c in customers 
       select c.CompanyName[0]; ///ดึงอักษรตัวแรกของชื่อบริษัท
       
       var productOnlyFirstChars = productFirstChars.Except(customerFirstChars); 
      

      คำอธิบาย : เป็นการอ่านข้อมูลจาก 2 ส่วน คือ ในส่วนของลิสต์ products และ customers โดยเอาเฉพาะอักษรตัวแรกของข้อมูลมาเพื่อเปรียบเทียบค่าโดยเทียบจาก productFirstChars หากพบว่าซ้ำกับในตัวอักษรแรกของข้อมูลชื่อบริษัทที่เก็บไว้ในตัวแปร customerFirstChars จะข้ามไป ไม่ดึงมาเก็บไว้ในตัวแปร productOnlyFirstChars แต่หากไม่ซ้ำ จะนำมาเก็บไว้ ผลลัพธ์สุดท้ายที่ได้จึงจะมีเฉพาะที่มีใน productFirstChars และไม่ซ้ำกับในข้อมูล customerFirstChars เท่านั้น
      ตัวอย่างที่ 2 :

       int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; 
       int[] numbersB = { 1, 3, 5, 7, 8 }; 
       
       IEnumerable<int> aOnlyNumbers = numbersA.Except(numbersB); 
      

      คำอธิบาย : เป็นการอ่านข้อมูลจาก 2 ส่วน คือ ในตัวแปรอาร์เรย์ numbersA และ numbersB เพื่อเปรียบเทียบค่าโดยเทียบจาก numbersA เทียบกับ numbersB จะเอาเฉพาะที่มีใน numbersB แต่ไม่มีใน numbersB มาเก็บไว้ในตัวแปร aOnlyNumbers
      ผลลัพธ์ : aOnlyNumbers = { 0, 2, 4, 6, 9}

      • การอ่านข้อมูลจาก 2 แหล่งข้อมูลด้วยวิธีการ join
        • การ join แบบ innerjoin

        ตัวอย่างที่ 1 : เป็นการเชื่อมตาราง 2 ตารางโดยจะเอาเฉพาะข้อมูลแถวที่มี key ร่วมกันจากทั้ง 2 แหล่ง

        var result = from p in Person.BuiltPersons()
         join a in Address.BuiltAddresses() ///ระบุตารางที่นำมาเชื่อมกัน
         on p.IdAddress equals a.IdAddress ///กำหนด key ร่วมจาก 2 ตาราง
         select new 
         { ///เลือกคอลัมน์ที่ต้องการนำมาใช้
         Name = a.MyPerson.Name,
         Age = a.MyPerson.Age,
         PersonIdAddress = a.MyPerson.IdAddress,
         AddressIdAddress = a.MyAddress.IdAddress,
         Street = a.MyAddress.Street
         }; 
        

        คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นเป็นการเชื่อมตาราง 2 ตารางเข้าด้วยกัน และเลือกเฉพาะข้อมูลที่มีรหัส IdAddress ตรงกันมาแสดงเท่านั้น

        หรือ 

        var resultJoint = Person.BuiltPersons().Join( /// Source Collection
         Address.BuiltAddresses(), /// Inner Collection
         p => p.IdAddress, /// กำหนด key จากตาราง Person.BuiltPersons()
         a => a.IdAddress, /// กำหนด key จากตาราง Address.BuiltAddresses()
         (p, a) => new { MyPerson = p, MyAddress = a }) /// Result Collection
         .Select(a => new
         {
         Name = a.MyPerson.Name,
         Age = a.MyPerson.Age,
         PersonIdAddress = a.MyPerson.IdAddress,
         AddressIdAddress = a.MyAddress.IdAddress,
         Street = a.MyAddress.Street
         });
        • การ join แบบ leftjoin

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

        string[] categories = new string[]{ 
         "Beverages", 
         "Condiments", 
         "Vegetables", 
         "Dairy Products", 
         "Seafood" }; 
          List<Product> products = GetProductList(); 
          
         var q = 
         from c in categories 
         join p in products on c equals p.Category into ps 
         from p in ps.DefaultIfEmpty() 
        ///ถ้าไม่มีข้อมูลจะแสดงข้อความ (No products)
         select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName }; 
        

        คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นได้ว่าเป็นการเชื่อมข้อมูล 2 แหล่ง โดยยึดตามแหล่งข้อมูลแรก ในที่นี้คือข้อมูล categories และเทียบกับข้อมูลใน products หากข้อมูลที่เปรียบเทียบมีใน categories แต่ไม่มีใน products ก็จะนำมาแสดง โดยให้ค่าของ ProductName เป็น (No products) แทน(ตามหลักการ join แบบ leftjoin ) หรืออธิบายง่ายๆว่า จะแสดงทุกรายการที่มีใน categories นั่นเอง

        • การ join แบบ rightjoin

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

        var rightOuterJoin = from last in lastNames
         join first in firstNames
         on last.ID equals first.ID
         into temp
         from first in temp.DefaultIfEmpty(new { last.ID, Name = default(string) })
         select new
         {
         last.ID,
         FirstName = first.Name,
         LastName = last.Name,
         };
        

        คำอธิบาย : จากตัวอย่างข้างต้น จะเห็นได้ว่าเป็นการเชื่อมข้อมูล 2 แหล่ง โดยยึดตามแหล่งข้อมูลแรก ในที่นี้คือข้อมูล lastNames และเทียบกับข้อมูลใน firstNames โดยยึดข้อมูลจาก firstNames หากข้อมูลที่เปรียบเทียบมีใน firstNames แต่ไม่มีใน lastNames ก็จะนำมาแสดง โดยให้ค่าของ default(string) แทน(ตามหลักการ join แบบ rightjoin ) หรืออธิบายง่ายๆว่า จะแสดงทุกรายการที่มีใน firstNames นั่นเอง

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

      แหล่งข้อมูลอ้างอิง :
      https://code.msdn.microsoft.com/LINQ-Aggregate-Operators-c51b3869

      http://stackoverflow.com/questions/61870/sum-of-items-in-a-collection

      http://stackoverflow.com/questions/17983024/finding-average-of-value-based-on-count-of-rows-in-linq?rq=1

      https://code.msdn.microsoft.com/LINQ-Set-Operators-374f34fe

      http://www.codeproject.com/Articles/535374/DistinctBy-in-Linq-Find-Distinct-object-by-Propert
      https://code.msdn.microsoft.com/LINQ-Join-Operators-dabef4e9

      http://www.codeproject.com/Articles/488643/LinQ-Extended-Joins

  • จับตา 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/

  • การ Encrypt/Decrypt ข้อมูลในไฟล์ Web.config

    การเข้ารหัส (Encrypt) ไฟล์ Web.config ถือเป็นวิธีการหนึ่งในการช่วยเพิ่มความปลอดภัยและช่วยป้องกันการถูกโจมตีจากผู้บุกรุกในการเชื่อมต่อกับฐานข้อมูล เนื่องจากไฟล์ web.config เป็นที่รวมการ config ค่าต่างๆ ของ web application ของเราไว้ เช่น ข้อมูลรหัสผ่านสำหรับการเชื่อมต่อฐานข้อมูล (ConnectionString), AppSetting, คีย์ API หรือข้อมูลสำคัญอื่นๆ ที่เกี่ยวกับการตั้งค่าต่างๆ โดยบทความนี้นำเสนอการเข้ารหัสและการถอดรหัส (Encrypt/Decrypt) ไฟล์ Web.config ด้วยคำสั่งผ่าน Command line โดยใช้ tools ที่มากับ .NET Framework ดังนั้นเครื่องคอมพิวเตอร์ของเราจะต้องมีการติดตั้ง .NET Framework ไว้อยู่ก่อนแล้ว สำหรับข้อมูลในไฟล์ Web.config จะถูกแบ่งออกเป็น section หลายๆ section ด้วยกัน โดยผู้เขียนจะขอยกตัวอย่างการ Encrypt/Decrypt ข้อมูลในส่วนของ section<connectionString>ดังนี้

     

    ก่อนทำการ Encrypt Web.config

    ที่ section <connectionStrings> ซึ่งเก็บข้อมูล config ค่าต่างๆ ของ Database sever ไว้ เช่น user/password เป็นต้น

    <configuration>
    <connectionStrings>
    <add name="SqlServices" connectionString="Data Source=localhost;PASSWORD=1234;Integrated Security=SSPI;Initial Catalog=Northwind;" />
    </connectionStrings>
    </configuration>

     

    Encrypt Web.config

    1.เปิด Command Prompt ขึ้นมา (อย่าลืมเปิดแบบ Run as administrator ด้วยนะคะ)

    2.พิมพ์คำสั่ง ดังนี้(Version ของ.NET Framework ขึ้นอยู่กับที่ลงไว้ที่เครื่อง) :

    cd C:\Windows\Microsoft.NET\Framework\v4.0.30319

    step1

    3.เข้าไปที่ directory path ที่เก็บไฟล์ web.config แล้วพิมพ์คำสั่ง ดังนี้

    aspnet_regiis.exe -pef connectionStrings  C:\inetpub\wwwroot

    step2

    หมายเหตุ: “connectionString” เป็น case sensitive ตัวพิมพ์เล็ก พิมพ์ใหญ่ ต้องพิมพ์ให้ถูกต้อง

     

    หลังทำการ Encrypt Web.config

    หลังจากทำการ Encrypt แล้วจะเห็นว่า ที่ section connectionString จะเป็นรหัสที่ไม่สามารถอ่านเข้าใจได้

    <connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">
       <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
         xmlns="http://www.w3.org/2001/04/xmlenc#">
         <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
         <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
           <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
             <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
             <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
               <KeyName>Rsa Key</KeyName>
             </KeyInfo>
             <CipherData>
               <CipherValue>SryXAF+wpnIpZ8P3HMP8ffMDBorz9j08/oX2vXDA+9LkMHY1i50qeCqYmOYnQXK4C6iNhyIZx9R+AcE7yY7AQeHzzPhZ/bZ04NPuOpd7wD+NL82CWeec/fToTIBbHvE6zNBgenUSE+8zTv9II357tsqpjH1xaII+zmZbgo5+fnhjAD8nVffqd+NQ0x+IXDwyBraeT50TlEXx4lJlAph7jqdglg1Xf/yjSTfwrOB2NcVIHVaVWN3CrelWgQKASftGXdDVingbRn2RXphyooTuVsZgJdzbFMpd7H6fJHggORSPwOud1ZU5vE4aNAMHDa4fb6FOA3I8R0urWD4sT34YRg==</CipherValue>
             </CipherData>
           </EncryptedKey>
         </KeyInfo>
         <CipherData>
           <CipherValue>iKttnP9CEMRfq+mhcHqN8f5GiwsySBLw0CWeiAxSQVIfoEQMNutubrRFruoNIb+m0XJnPL5FIypqqQ72dqZ4DSeQdUJwAVyO4HSlM5F3b+Jnogz9aMAuwdoww5QKdI94yH9fx8RwxhAzq1a9eApjLglAwTmKY84Wg/Lqpcn9wfvKyIZJyQaJCaLCEteGhB9bopjT9z+nmMZVQ2LrDEtKMEe1oltPoR8EvTel2/2jJ/gwvJK+vTw9sL2GMPJIoA/NZQWjR2CWaCGlEFIjmgqT8BjTwiSS6hEp90CEQVN14U9A71vXquH73X6ZAyIFScf2XJS1Y+iCaEFo6r8qIIiGdrAGUTgfa8r9EwHzb5emCzlQzEDWgzno5IUDxuMBNzJinFudgwPFkA/xhdAHcHnB+quFOGGKVZJw72o5Ix7IeWI1Frs2n8+JZMrpPNW5r4SHHLrMD/iPR5FSfDz/sQqR5f+3/N3i3aq0LX8NfthfYtS9N4oCdPBPbIReP1w05we1Q+PJMO4KVG4w3x8k9O7aT0zoi+5CuPgKR30IgbE0sL8fOeki5OKYfsscNMzV/6T23axh9Ky+axI9fAMarjjL5aeYfa8n6jeevpA4f2SmlkbvW6P72292Ihk3bD1HMghn7ibjZ2q6hLwTb9QWyQvSDjHPsqeoiuKBTNJZgsCqBA4QK8j6/9exufTsOe/SgTclHPfiXpSI7CgbaGd6JQ2P5QSDVwQNQPuaf4qFKsZdPWfdEGcCgxLVZtcU0Cd12AnpaWIpiVUjCz6pWl4YygEXsvntLQfLSQ7XX2Q8lA1DjqBOcDQXY9mMo6PvZi3IsqcdF/DEn931nwBPO09T2AqWJWuAaK/Vh4+olkVYFWuj/Eerp2UkG2ItJduUaRNWzXV9s1hQ/q/36S0RTxN0DgXPII6CowQWIV2d5ZYwSUKVgsiDM43GBPF4SFFJOUec37yzYv6XT3/BmDmNpq32a+VAUB/OP23k4mnTvm/Nay1Iy6E8sUOYSpCY1up6XAcFL1XsacpNKLpMTmH6LsROX9BhmdTNaWgCQaDNVNeAISoJ8HZ5lw/EX1f6Rtz4uWyvBfSOPPAWPkNQawexjVKl0FtR6fRSnAGMkgflURH5QNX5xm+y0sfZsNz9sAFZofoJLQ3rdV7ToFJE+JlEvPKRHFDVbxDCURQ5CynXFnqlLj+2LhBbyX0n6oHQwMgTTTIf/+PNcjOx3zBn6/V3T0PdD6fnjVtTDnbJzN7ct7SOuifW0OfCfyeKSs0IOzPm8BucZ4CODaTwjY1bz2kgGRTjuenCp1N1GIRhMJBIBJhWOs3nee6Y9DgtlpWc3SZRZeYkmOffT5xNwQeTLrIXvTZCByHZcN3+g8OG0HqlodUCbPgf8jK45dMeT8piyFwZem8Dotjz7mXOaJxF7C66SQKvFVfuJjXDmTbmdzqwt33z+w39TV8ueXGyB/5S1kpV/ul+c7LwTwked7bMJtFJpVwdFKFiUxMebDuu3vINlVSZJfo43SSmTD3rM2UXV8ol65KzlmacBhgCwXtLFg7/8uGQrrUVq9gqHsoPyEgt</CipherValue>
         </CipherData>
       </EncryptedData>
     </connectionStrings>
    

     

    Decrypt Web.config

    การถอดรหัส (Decrypt) ไฟล์ Web.config สามารถใช้คำสั่งเช่นเดียวกันกับการ Encrypt แต่เปลี่ยนจาก -pef เป็น -pdf ดังคำสั่งต่อไปนี้ :

    aspnet_regiis.exe -pdf connectionStrings  C:\inetpub\wwwroot

    หมายเหตุ: “connectionString” เป็น case sensitive ตัวพิมพ์เล็ก พิมพ์ใหญ่ ต้องพิมพ์ให้ถูกต้อง

    การ Decrypt จะทำได้เฉพาะที่เครื่องที่ทำการ encrypt เท่านั้น จะไม่สามารถ decrypt ไฟล์ web.config นี้จากเครื่องอื่นได้ หากเรานำไฟล์ไป Decrypt จากเครื่องอื่นก็จะพบ message Failed ดังรูป

    step3

    โดยการ Encrypt/Decrypt ด้วยการใช้คำสั่งผ่าน command line สามารถทำได้กับทุก section (ไม่เฉพาะ connectionString)ในไฟล์ Web.confog เพียงแต่เปลี่ยนคำสั่งในส่วนของ section ตามที่ต้องการ

     

    แหล่งข้อมูลอ้างอิง : https://msdn.microsoft.com/en-us/library/ff647398.aspx

  • การใช้ 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/

  • สร้างกราฟด้วย Chart.js ร่วมกับ ASP.NET

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

        สำหรับ Chart.js นั้นเป็นเฟรมเวิร์คที่สร้างด้วยภาษา JavaScript ดังนั้นคุณสมบัติที่พ่วงมาด้วยคือการทำงานแบบ AJAX อย่างเต็มรูปแบบ ซึ่งในบทความนี้จะเป็นการนำเอามาใช้ร่วมกับเว็บแอพลิเคชัน ที่พัฒนาด้วย ASP.NET โดยวิธีการส่งข้อมูลในรูปแบบ JSON ผ่าน Web Services และทำการแปลงข้อมูล JSON ให้อยู่ในรูปแบบของ Object ที่มีโครงสร้างตรงตามที่ Chart.js ต้องการ เพื่อนำไปใช้แสดงผลในรูปแบบกราฟแท่ง กราฟเส้น กราฟวงกลม  ผ่าน HTML Tag ที่มีชื่อว่า Canvas ซึ่งมีการเพิ่มส่วนแสดงความหมายของสีต่างๆในกราฟ ที่ได้พัฒนาเพิ่มเติมขึ้นมาอีกด้วย

        ในบทความนี้จะยกตัวอย่างการสร้างกราฟใน 3 รูปแบบ และมีการกำหนดค่า Option ในการแสดงผลเท่าที่จำเป็นเท่านั้น สามารถอ่านวิธีการใช้งานเต็มรูปแบบได้ที่ http://www.chartjs.org/docs

    1. ทำการ Include ไฟล์ Javascript ของ chart.js ไว้ใน header (ในตัวอย่างเป็นการเรียกใช้งานจาก CDN หากต้องการใช้งานจากไฟล์ที่เก็บไว้ที่เว็บเซิฟเวอร์ให้ปรับแก้ src path)
    <script src="https://code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js" type="text/javascript"></script>
    1. เพิ่ม canvas ในส่วนของ body
     <canvas id="report" width="600" height="300"></canvas>
    1. เขียน JavaScript เพื่อสร้างข้อมูล ตามโครงสร้างของกราฟแต่ละประเภท ในตัวอย่างจะเป็นโครงสร้างข้อมูลของกราฟแท่ง
     var dataDemo = { labels: ["Apple", "Sumsung", "ASUS", "OPPO"],
     datasets: [{
     label: "2557",
     fillColor: "#5B90BF",
     data: [20, 10, 9, 8]
     }]
     };
    1. ทำการสร้าง Context จาก canvas เพื่อนำไปสร้าง Chart Object โดยใช้คำสั่ง ดังนี้
     var ctx = $("#report").get(0).getContext("2d");
     var chart = new Chart(ctx).Bar(dataDemo, { bezierCurve: false });

     

    จาก 4 ขั้นตอนดังกล่าวเราจะได้โค้ดที่เมื่อทำการเพิ่มโครงสร้างของหน้าเว็บ และบันทึกเป็นไฟล์ html แบบนี้ chart.html  ลองเปิดดูจะพบว่าสามารถแสดงกราฟแท่งได้แล้ว

     

        แต่ในงานจริงนั้น รู้กันดีนะครับ ว่ามันไม่ง่ายอย่างนั้น โจทย์ของเราคือ สามารถนำข้อมูลจาก Database ซึ่งได้เขียน Query จนได้ข้อมูลแบบที่เราเรียกกันติดปากว่า Crosstab นั้นคือมีชื่อฟิลด์ข้อมูลที่มีความสัมพันธ์กันในแกน x และแกน y ซึ่งเป็นรูปแบบข้อมูลที่นำมาสร้างเป็นกราฟนั้นเอง ส่วนวิธีการนั้น ผมไม่ขอลงรายละเอียดในบทความนี้ แต่สำหรับท่านใดที่ใช้งานฐานข้อมูล Oracle ตั้งแต่ 11g ขึ้นไปลองศึกษาคำสั่งชื่อ Pivot ดูครับ น่าจะช่วยลดความยุ่งยากในขั้นตอนนี้ได้มาก ตัวอย่างข้อมูล แบบ Crosstab ที่เราจะส่งจากฝั่ง Server มาสร้างเป็น Object สำหรับสร้างกราฟอีกทีครับ

     

    crosstab-datatable

     

        อีกจุดที่มีความยุ่งยาก คือการแปลงจากรูปแบบข้อมูล Crosstab Datatable เป็น JSON ตัวช่วยของผมในเรื่องนี้คือ Library ที่ชื่อ Newtonsoft.Json สามารถดาวส์โหลดมาใช้งานผ่าน NuGet ได้เลยครับ จากนั้นก็เรียกใช้งาน ดังตัวอย่าง โดยตัวแปล data คือ Datatable ของเรา เมื่อได้ข้อมูล JSON แล้วให้ทำการสร้าง Web Service เพื่อให้สามารถดึงข้อมูลดังกล่าวจาก Javascript ได้

    JsonConvert.SerializeObject(data)

    ถัดจากนั้น ก็คือการนำ JSON นั้นไปสร้างเป็น Object ที่มีโครงสร้างตามที่ Chart.js ต้องการอีกที ในขั้นตอนนี้ผมลองหา Library ดูแล้วแต่ไม่เจอ ก็ได้พัฒนาเป็นชุดคำสั่ง helper เล็กๆ ซึ่งค่อนข้างจะจำเพาะกับลักษณะข้อมูล และรูปแบบการแสดงผลของเว็บไซด์ที่ผมพัฒนาอยู่ แต่สามารถนำไปปรับแก้ให้เหมาะสมได้ครับ ซึ่งในไฟล์นี้ หากใส่ parameter และเขียนโครงสร้าง html ตามตัวอย่าง เราจะเหลือโค้ดที่จะต้องเขียนเพียงไม่กี่บรรทัด ก็จะได้กราฟมาใช้งานใน 3 รูปแบบ คือ กราฟแท่ง กราฟเส้น และกราฟวงกลม ตามที่มี method ให้ครับ

     

    สำหรับการสร้างกราฟจะมีขั้นตอนเปลี่ยนไปดังนี้ครับ

    1. ทำการ include ไฟล์ Javascript โดยเพิ่มเติม chart-helper.js
    <script src="https://code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js" type="text/javascript"></script>
    <script src="chart-helper.js" type="text/javascript"></script>
    1. ทำการ include ไฟล์ Style Sheet ดังนี้ bootstrap-grid.css และไฟล์ chart.css
    <link href="bootstrap-grid.css" rel="stylesheet" type="text/css" />
    <link href="chart.css" rel="stylesheet" type="text/css" />
    1. สร้าง HTML ตามโครงสร้าง โดยมีการใช้งาน class ในส่วน grid system ของ Bootstrap มาช่วยวางตำแหน่งซ้ายขวา ดังนี้
    <div class="row">
     <div class="col-xs-8">
     <canvas id="reportBar" width="600" height="300">
     </canvas>
     </div>
     <div class="col-xs-4">
     <ul id="chartLabelBar" class="chart-label-list">
     </ul>
     </div>
     </div>
     <div class="row">
     <div class="col-xs-8">
     <canvas id="reportLine" width="600" height="300">
     </canvas>
     </div>
     <div class="col-xs-4">
     <ul id="chartLabelLine" class="chart-label-list">
     </ul>
     </div>
     </div>
     <div class="row">
     <div class="col-xs-8">
     <canvas id="reportPie" width="600" height="300">
     </canvas>
     </div>
     <div class="col-xs-4">
     <ul id="chartLabelPie" class="chart-label-list">
     </ul>
     </div>
     </div>
    1. จากนั้นทำการเรียกใช้งาน Method ของ chart-helper.js ซึ่งประกอบไปด้วย CreateBarChart (สร้างกราฟแท่ง), CreateLineChart (สร้างกราฟเส้น), CreatePieChart (สร้างกราฟวงกลม) จะรับค่าเป็นข้อมูล JSON และ ID ของ HTML เพื่อนำไปสร้างกราฟโดยตัวอย่างการใช้งาน Method เหล่านี้ร่วมกับ Webservice (ทั้งนี้รูปแบบการเรียก Webservice ขึ้นอยู่กับวิธีการ Response ด้วย) มีดังนี้
    $.ajax({
     type: "POST",
     url: "DemoService.asmx/MethodName",
     data: { param:data1 }
     }).done(function (json) {
     CreateBarChart(json, "reportBar", "chartLabelBar");
     CreateLineChart(json, "reportLine", "chartLabelLine");
     CreatePieChart(json, "reportPie", "chartLabelPie");
     }).fail(function (jqXHR, textStatus) {
     alert(textStatus);
     });

    สามารถดาวโหลดไฟล์ตัวอย่างแบบเต็มได้ตามนี้ครับ chart-with-helper.html และกราฟที่ได้จะมีหน้าตาแบบนี้ ทั้งนี้ขึ้นอยู่กับข้อมูลของเราด้วยครับ

    bar line pie

     

  • การทดสอบโปรแกรม (Testing)

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

    การ Test คือการทดสอบระบบว่าทำงานได้ถูกต้องได้ผลตามวัตถุประสงค์หรือไม่ ซึ่งเป็นการทดสอบกระบวนการทางพื้นฐานทางคอมพิวเตอร์

    โปรแกรมคอมพิวเตอร์มีหลักการง่าย ๆ คือ Input -> Process -> Output วิธีการกำหนด Test case อย่างง่ายที่สุดคือทำการ Test แต่ละส่วนโดยอยู่บนพื้นฐานของ Business requirement และวัตถุประสงค์ของระบบ ซึ่งจะต้องมีการเขียน Test case โดย Test case เป็นเอกสารที่ระบุชุดข้อมูลป้อนเข้าผลลัพธ์ ที่คาดว่าจะได้รับและกลุ่มของเงื่อนไขในการดำเนินการในชุดทดสอบต่าง ๆ มีจุดมุ่งหมายเพื่อแบ่งฟังก์ชันการทำงานของซอฟต์แวร์ออกเป็นฟังก์ชันย่อย ๆ เพื่อให้สามารถทำการทดสอบโดยชุดข้อมูลป้อนเข้าดังกล่าว และสร้างผลลัพธ์ที่สามารถประเมินผลได้โดยปกติจะขึ้นกับ use case ของระบบ

    “Test case ประกอบด้วย”

    • ชื่อ Test case โดยปกติแล้วคือ Use case ตาม ฺBusiness requirement เช่น การ login เข้าระบบ
    • วัตถุประสงค์ของ Test case นั้น ๆ
    • ผลที่คิดว่าจะได้รับ (Output)
    • กำหนดลักษณะข้อมูลที่จะนำเข้าเพื่อใช้ในการ Test (Input)
    • ขั้นตอนวิธีการทดสอบ เป็น Step 1,2,3,… ว่าแต่ละขั้นตอนต้องทำอะไรบ้าง
    • ผลที่ได้จากการ test

    “ชนิดของการ Test”

    1. ทดสอบความถูกต้อง
      • Unit test เป็นการ test functional ของระบบในแต่ละส่วนย่อยๆเพื่อให้แน่ใจว่าแต่ละส่วนทำงานได้ถูกต้อง
      • Integration test เป็นการนำแต่ละ unit มาประกอบกันและทดสอบการติดต่อระหว่าง unit ว่าสามารถทำงานได้ถูกต้อง
      • End to end test เป็นการทดสอบระบบในภาพรวมโดยนำแต่ละส่วนของระบบมาประกอบกันให้สมบูรณ์ และทดสอบระบบประหนึ่งเป็น ผู้ใช้ของระบบ
    2. ทดสอบคุณภาพ
      • Stress test เป็นการทดสอบประสิทธิภาพของระบบ เพื่อทดสอบว่าระบบสามารถรับจำนวนผู้ใช้, ข้อมูล ได้มากแค่ไหน
      • Usability test เป็นการทดสอบประสิทธิภาพการใช้งานของระบบ เช่น UI เหมาะสมต่อการใช้งานหรือไม่ เข้าใจได้ง่ายหรือไม่

    การทดสอบระบบไม่ว่าที่ไหนก็คงมีวิธีการและขั้นตอนไม่ต่างกันนัก ที่แตกต่างกันคงจะเป็นความเข้มข้นของการ Test เสียมากกว่า คือจะ Test ละเอียดแค่ไหน มีระบบที่ใช้เพื่อการ Test พร้อมหรือไม่ และทีมงานมีความพร้อมแค่ไหน

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

  • วิธีการทดสอบเว็บไซต์ Responsive บน Smart phone ด้วย Chrome

    “ปัจจุบันกระแสการออกแบบเว็บเชิงตอบสนอง (Responsive design) ถูกนำมาใช้ในการออกแบบเว็บสมัยใหม่ เนืองจากสามารถดูได้ทั้งแบบผ่านเครื่องคอม แท็บเล็ต และมือถือ ได้โดยทันที”

    แต่ในระว่างการออกแบบ ถ้าผู้ออกแบบจะต้องมีการทดสอบบนอุปกรณ์แท็บเล็ต หรือมือถือ ต่างๆ ซึ่งมีความละเอียดของหน้าจอแตกต่างกันออกไป

    ซึ่งในส่วนที่ Chrome มีเครื่องมือที่ช่วยในการแสดงผลเว็บไซต์บนอุปกรณ์ Smart phone ได้ โดยไม่ต้องโหลดเพิ่ม แต่ประการใด !!! แถมวิธีการก็ง่ายแสนง่าย 

    ขั้นตอนที่ 1

    ให้ไปที่ More tools > Developer tools ดังภาพ

    01

    ขั้นตอนที่ 2

    เลือกที่รูปโทรศัพท์ ดังภาพ

    02

    ขั้นตอนที่ 3

    สังเกต ด้านซ้ายจะปรากฏหน้าจอมือถือขึ้นมา ให้ระบุ URL ที่เราต้องการดังภาพ

    06

    จากภาพ จะเห็นว่าหากเป็นเว็บที่ออกแบบด้วยหลักการออกแบบเว็บเชิงตอบสนอง (Responsive design) จะมีการจัดหน้าจอให้เหมาะสมกับอุปกรณ์

    ขั้นตอนที่ 4

    สังเกต ด้านบน เราสามารถเลือกรุ่นของ Smart Phone ได้หลายรุ่น แม้จะไม่มาก แต่ก็เป็นรุ่นหลักและหลากหลายความละเอียด หรือจะเลือกปรับขนาดเองก็ทำได้  และสามารถปรับให้แสดงแนวตั้งและแนวนอนได้อีกด้วย ดังภาพ

    07

    จะเห็นว่าเครื่องมือด้งกล่าวใช้งานไม่ยาก ทำให้สามารถดูหน้าจอในหลายๆ ความละเอียดได้อย่างรวดเร็ว 

  • ทดสอบการแสดงผลเว็บแอพพลิเคชันง่ายๆ บน Browser ต่างๆ ด้วยบริการของ Modern IE

    ในปัจจุบันเว็บแอพพลิเคชันที่มีการพัฒนาจะต้องรองรับ Browser และอุปกรณ์ที่แตกต่างกัน ซึ่งบางครั้งเป็นการยากที่เราจะทดสอบให้ครบได้

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

    Microsoft ได้เปิดตัว Modern IE ขึ้น โดยมีบริการที่น่าสนใจที่เรียกว่า Browser screenshots !!

    ขั้นตอนที่ 1

    ไปยัง URL : https://dev.modern.ie/tools/screenshots/

    2

    ขั้นตอนที่ 2

    ใส่ URL ของเว็บแอพพลิเคชันของเราที่ต้องการ

    1

    ขั้นตอนที่ 3

    กดปุ่ม Enter หรือรูปแว่นขยาย เครื่องมือจะแสดงผลดังภาพ

    3 4

    จะเห็นว่าเจ้า Browser screenshots เป็นเครื่องมือที่ช่วยให้เราเห็นหน้าจอเว็บแอพพลิเคชันของเราในเบื้องต้นได้

    “หวังว่าจะมีประโยชน์ต่อนักพัฒนาหรือนักทดสอบระบบทุกท่านนะค่ะ”