วันอังคาร, มิถุนายน 29, 2553

เมื่อใด(ไม่)ควรใช้ Web Services

เกณฑ์ในการพิจารณาใช้ Web Services

1. การส่งข้อมูลและสื่อสาร ผ่าน FireWall
2. Application Integration
3. Business to Business Integration
4. การนำ Software มา Reuse

เกณฑ์ในการพิจารณาไม่ควรใช้ Web Services

1. การใช้หลายๆ Applications บนเครื่องเดี่ยว
2. การใช้ Application ที่ต่างกัน บน LAN ในขณะที่มีทางเลือกอื่นดีกว่า ไม่ว่าจะเป็น .NET Remoting/DCOM

วันจันทร์, มิถุนายน 28, 2553

คอนโทรล ยืนยันตัวตน (Authentication)

การเปลี่ยนแปลงที่แสดงในคลาส Membership และคลาส Roles เริ่มมีให้เห็น ตั้งแต่ ASP.NET เวอร์ชั่น 2 ขึ้นไป ที่มา
พร้อมกับ คอนโทรลสำหรับ การยืนยันตัวตนต่างๆ ซึ่งช่วยให้เรา ทำงานกับข้อมูลผู้ใช้ และ เพจอีลีเม้นต์ ในแต่ละโพรไวเดอร์
ได้สะดวกง่ายดายขึ้น

คอนโทรล ด้านการตรวจสอบ อันดับแรกที่จะกล่าวถึง และมีประโยชน์มาก สำหรับใช้เพื่อการยืนยันตัวตน คือ คอนโทรล Login เป็นคอนโทรลที่ มีรูปแบบการผสมผสาน (composite) เพื่อนำชื่อผู้ใช้และรหัสผ่าน เข้าสู่ขั้นตอนการตรวจสอบสิทธิ และล็อกผู้ใช้เข้าระบบ หลักการทำงาน มันจะเรียกใช้ Membership.ValidateUser() และกรณี
ที่การป้อนข้อมูลของผู้ใช้ ตรงกับข้อมูลที่เก็บอยู่ในดาต้าสโตร์ ที่กำหนดโดย MembershipProvider แล้ว FormsAuthentication.SetAuthCookie() จะ ถูกเรียกขึ้นมาทำงาน จากนั้น ผู้ใช้ก็จะผ่านการล็อกอิน เข้ามาใช้งาน

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

สำหรับคอนโทรล LoginStatus มีลักษณะการทำงานเช่นเดียวกับคอนโทรล Login โดยมันจะแทรกแทก ไว้ในเพจ ในกรณีที่ผู้ใช้ไม่ได้ล็อกออนเข้ามา มันจะเตรียมลิงค์ให้กับเพจล็อกออน ที่ระบุแอททริบิ้ว loginUrl ไว้ในอีเลเม้นฟอร์ม จาก web.config เมื่อผู้ใช้ล็อกออนเข้ามา จะมองเห็น LinkButton แสดงแคปชั่น “Logout” ซึงจะเรียกใช้
FormsAuthentication.SignOut()และลบคุกกี้การยืนยันสิทธิของผู้ใช้ออกไป คอนโทรลนี้ยังประกอบด้วยพร๊อพเพอร์ตี้อีกมากมาย ซึ่งจะช่วยให้เราแก้ไขเปลี่ยนแปลงข้อความ และรูปแบบในแต่ละอีเลเม้นท์
คอนโทรล LoginView ใช้เท็มเพลตในการแสดงเนื้อหาที่สัมพันธ์กับสถานะหรือบทบาทของผู้ใช้ที่ล็อกออนเข้ามา วิธีนี้มีประโยชน์สำหรับการแสดงเฉพาะในส่วนเนื้อหา

วันศุกร์, มิถุนายน 25, 2553

Form Authentication


โหมด Forms ใช้เทคนิคการตรวจสอบสิทธิผ่านทางคุ๊กกี้ (cookie-based authentication) โดยที่เราไม่จำเป็นต้องสร้างรูปแบบ การตรวจสอบสิทธิผ่านคุ๊กกี๊ ด้วยตัวเอง เหมือนในอดีต เนื่องจาก ASP .net ดูแลและจัดการรายละเอียด ด้วยการ กระตุ้นให้เกิด กระบวนการ ให้ได้รับอนุญาติใช้งาน (authorization) ผ่านการยืนยันตัวตน การตรวจสอบสิทธิผ่านทางคุ๊กกี้ ดูขั้นตอนการทำงานประกอบ จากรูปภาพด้านบน

วันศุกร์, มิถุนายน 18, 2553

N-Tire Architecture


Layer หรือ Tier เป็นการวางการทำงานของระบบ แยกออกเป็นส่วน ๆ
โมเดลที่นักพัฒนานิยมนำมาใช้ ประกอบด้วย

1. Microsoft DNA Model แบ่งเป็น 3 Tier หลักๆ คือ Presentation, Business, Data access
2. Core J2EE Model แบ่งหลักๆได้ Client, Presentation, Business, Integration, Resource
3. Brown Model แบ่งได้ Presentation , Controller/Mediator ,Domain ,Data Mapping ,Data Source


การประยุกต์ใช้ ขึ้นอยู่กับขนาดของซอฟต์แวร์ ความเข้าใจของผู้พัฒนา ความเหมาะสมกับงาน “ไม่มีกฎตายตัว” แต่ ถ้าจะนำ Tier/Layer ใดมาใช้ ให้คำนึงถึง การเชื่อมต่อระหว่าง Layer และ วางกลไกลภายในให้ตรงกับลักษณะจุดประสงค์ของ Layer นั้นๆ โดยที่ อาจมีการยุบรวมเข้าด้วยกัน เช่น Façade(Controller) Layer + Application(Business) Logic Layer หรือ แตกย่อย Data Access Layer เป็น Layer อื่นๆ ได้อีก เพื่ออธิบายกระบวนการภายใน เช่น การรับข้อมูล การประมวลผล การจัดเก็บ/แสดงผล

วันพุธ, มิถุนายน 16, 2553

Role-Based Authentication

วิธีนี้ให้ประโยชน์ ในการสร้างเว็พแอพพลิเคชั่น ก็คือการกำหนด สิทธิ แบบ Role-Based Authentication ASP.NET สนับสนุน การยืนยันตัวตน แบบ Role-based โดยเรียกการทำงานของ เมทธอด IsInRole() ของ อินเตอร์เฟซ IPrincipal โดยอินทิเกรทการใช้เข้ากับ การยืนยันตัวตนผ่าน Windows ตัวเมทธอด IsInRole() จะทำหน้าที่ตรวจสอบ กลุ่มผู้ใช้สมาชิกบน Windows ในขณะที่ การยืนยันตัวตนผ่านคุกกี้ จะต้องใช้ role เพื่อการตรวจสอบความปลอดภัย เราจะต้องกำหนด role เหล่านั้น และสร้าง การจับกลุ่มเชื่อมโยง (Mapping) ระหว่างผู้ใช้ กับ roles นั้นๆ ด้วย วิธีที่สะดวก คือการเรียก คลาส GenericPrincipal ให้เรียกใช้เมทธอด IsInRole() ทำงาน โดยการตรวจเช็คชื่อดูว่าชื่อผู้ใช้ที่แอคทีฟอยู่นั้น สัมพันธ์หรืออยู่ใน roles ต่างๆ ที่กำหนดขึ้นหรือไม่



<%! File: global.asax %>
<%@ Import Namespace="System.Security" %>
<%@ Import Namespace="System.Security.Principal" %>

<%! File: global.asax %><%@ Import Namespace="System.Security" %><%@ Import Namespace="System.Security.Principal" %>

วันศุกร์, มิถุนายน 11, 2553

เทคนิคการ บันทึกเฉพาะส่วน (Save Points) ใน Transaction

เมื่อไหร่ ก็ตามที่เรา Rollback Transaction จะทำให้การปรับปรุงแก้ไข ทุกคำสั่งถูกยกเลิก และคืนสถานะเดิมของข้อมูลทั้งหมด โดยในบางครั้ง เราอาจไม่ต้องการ Rollback คำสั่งใด คำสั่งหนึ่ง จากทุกๆ คำสั่ง ก็เป็นได้ ฉะนั้นเราจำเป็นต้องหากลไก ที่จะ Rollback เพียงส่วนใดส่วนหนึ่งใน Transaction เราสามารถทำเช่นนั้นได้ ด้วยการใช้ SavePoints
SavePoints เป็นตัวทำเครื่องหมายที่ทำงานคล้ายกับ Bookmark เราอาจจะทำเครื่องหมาย ณ. จุดใด จดหนึ่งภายในการทำงานของ Transaction จากนั้นให้ Rollback กลับไปที่จุดที่ทำเครื่องหมายไว้ แทนที่จะ Rollback Transaction ทั้งหมด วิธีการคือ เราจะใช้ เมทธอด Save ในออบเจ็กต์ Transaction (ใช้ได้เฉพาะ คลาส SqlTransaction เท่านั้น)

ลิสติ่งที่ 1 พร้อมคำอธิบาย
Imports system
Imports System.Data
Imports System.Data.SqlClient

Module Module3

Sub Main()
Dim tConnection As SqlConnection
Dim tCommand As SqlCommand
Dim tTransaction As SqlTransaction
Dim tReader As SqlDataReader

‘ กำหนด ตัวแปรออบเจ็กต์ ต่างๆ เช่น Connection,Command และ Transaction เพื่อเชื่อมต่อไปยังฐานข้อมูล

Dim ConnectionString As String
ConnectionString = "Data Source=totsawat;Initial Catalog=Northwind;Integrated Security=True"
tConnection = New SqlConnection(ConnectionString)
tConnection.Open()

‘ เริ่มการทำงานของ Transaction โดยเรียกเมทธอด BeginTransaction ของออบเจ็กต์ Connection
tTransaction = tConnection.BeginTransaction()

tCommand = New SqlCommand()
tCommand.Connection = tConnection
tCommand.Transaction = tTransaction

Try
‘ เอ็กซิคิ้ว คำสั่ง SQL สเตทเม้นต์เพื่อการเพิ่มข้อมูล ทั้งหมด 5 ชุดคำสั่ง จาก ออบเจ็กต์ SqlCommand

tCommand.CommandText = "insert into orders default values"
tCommand.ExecuteNonQuery() ‘เรียกการทำงาน SavePoint ด้วยเมทธอด “Save” หลังจากเพิ่มเรคคอร์ดแรกแล้ว
tTransaction.Save("FirstOrder")
tCommand.CommandText = "insert into orders default values"
tCommand.ExecuteNonQuery()
tCommand.CommandText = "insert into orders default values"
tCommand.ExecuteNonQuery()
‘จากนั้น ให้ทำการเพิ่มเรคคอร์ดเข้าไปอีก 2 ชุดคำสั่ง แล้วเรียกเมทธอด rollback ย้อนกลับไปจนถึง จุด SavePoint ที่ชื่อ FirstOrder จะสังเกตเห็นว่า เราใช้ เมทธอด rollback พร้อมกับระบุชื่อของ SavePoint เป็นพารามิเตอร์ กรณีที่ต้องการ เรียกคืนสถานะเดิม (rollback) ทั้งหมดของ Transaction ไม่จำเป็นต้องระบุพารามิเตอร์
tTransaction.Rollback("FirstOrder")
‘ ต่อจากนั้น ให้ทำการเพิ่มเรคคอร์ดเข้าไปอีก 2 ชุดคำสั่ง และ สั่ง คอมมิท ตามปกติ
tCommand.CommandText = "insert into orders default values"
tCommand.ExecuteNonQuery()
tCommand.CommandText = "insert into orders default values"
tCommand.ExecuteNonQuery()
tTransaction.Commit()
‘ สุดท้ายให้เรียก หมายเลขออร์เดอร์ 3 รายการล่าสุด ขึ้นมาดู ทางหน้าจอ
tCommand.CommandText = "select top 3 orderid from " & _
"orders order by orderid desc "
tReader = tCommand.ExecuteReader()
Console.WriteLine("Last 3 Orders")

While tReader.Read()
Console.WriteLine(tReader.GetInt32(0))
End While

Catch e As Exception
Console.WriteLine(e.Message)
Console.ReadLine()
Finally
tConnection.Close()
End Try

End Sub

End Module

วันอาทิตย์, มิถุนายน 06, 2553

ทิป : ใช้หลักทางตรรกะที่ดีในการพัฒนาโปรแกรม

สภาพแวดล้อมตัวจัดการรันไทม์ของ .NET ได้เตรียม Garbage collection ขั้นสูงที่ออกแบบมาเพื่อปรับปรุงทรัพยากรที่ถูกใช้ไป และลบการอ้างอิงที่ไม่จำเป็นออกไป อย่างไรก็ตาม เราควรประยุกต์โครงสร้างตามกฏการทำความสะอาด เพื่อทำให้โค้ดอ่านง่ายและมีประสิทธิภาพ โดยเฉพาะอย่างยิ่ง ให้ยกเลิกการอ้างอิงออปเจ็กต์ที่ไม่ต้องการใช้งานแล้วทุกครั้ง กรณีที่เราใช้การเชื่อมต่อข้อมูล ต้องแน่ใจว่า เราได้เปิดการเชื่อมต่อในช่วงเวลาสั้นที่สุดเท่าที่เป็นไปได้ โดยจะเปิดการเชื่อมต่อ เฉพาะตอนที่จำเป็นจริงๆ และปิดการเชื่อมต่อ เมื่อไม่ต้องการ ใช้งานอีกต่อไป และไม่ควรปล่อยให้การเชื่อมต่อยังคงเปิดอยู่ภายในโค้ดโปรแกรมของเรา และโดยเฉพาะ ถ้าเรากำลังทำงานกับการสตรีมออปเจ็กต์ข้อมูล เช่น ออปเจ็กต์ DataReader

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

วันเสาร์, มิถุนายน 05, 2553

ทิป : การใช้ ตัวจัดการข้อผิดพลาด (Exception Handling) อย่างเหมาะสม

การใช้การจัดการ ความผิดพลาด (Exception Handler) มีข้อควรระวัง โดยเฉพาะอย่างยิ่ง การส่งข้อผิดพลาดต่างๆ ออกมาข้อแนะนำคือ ให้สร้างโครงสร้างเพื่อจัดการข้อผิดพลาด ขึ้นภายในแอพพลิเคชั่นของเรา แต่จะต้องออกแบบ ให้หลีกเลี่ยง การทำงาน ที่วิ่งเข้าไปภายในตัวจัดการข้อผิดพลาด เรื่องนี้สามารถเข้าใจได้ไม่ยาก ยกเว้นแต่เฉพาะนักพัฒนาผู้ใช้การ เขียนโค้ดขึ้นเอง อย่างเช่น การใช้ ASP รุ่นก่อน ใช้การเขียนโค้ดขึ้นเอง บ่อยครั้งมักใช้ การวางบล็อก คำสั่ง On Error Resume Next ที่ยินยอมให้โค้ด ประมวลผลคำสั่งอย่างต่อเนื่องผ่าน ค่าความผิดพลาด ไปแล้วค่อยมาตรวจสอบค่าผิดพลาดของผลลัพธ์ที่กำหนดไว้ในภายหลัง ซึ่งวิธีการนี้ ไม่ได้นำมาใช้ใน สภาพแวดล้อมการทำงานของ .NET ฉะนั้นควรออกแบบโค้ด ให้ใช้ตัวจัดการ ข้อผิดพลาด เป็นทางเลือกสุดท้าย โดยพิจารณา ค่าความผิดพลาดต่างๆ และตรวจสอบประเภทของฟังก์ชั่น เพื่อดักจับ ข้อผิดพลาดเหล่านั้น ก่อนที่จะทำการแปลคำสั่ง เท่ากับบังคับให้เรา แสดงข้อผิดพลาดในช่วงเวลาประมวลผล (runtime) ออกมา

การส่งข้อผิดพลาด เฉพาะกรณีที่จำเป็นจริงๆ เท่านั้น เนื่องจาก มันจะเป็นการทำงานที่สร้างภาระให้เรามาก (ในมุมมองการ ใช้ทรัพยากร การตรวจสอบโค้ดเพื่อแก้ไข ประสิทธิผลการทำงาน ฯลฯ) คลาส exception ได้จัดหา รายละเอียดต่างๆ มากมาย ที่ใช้ได้ โดยไม่ต้องใช้อาศัย การเรียกทำงานจากโค้ด ที่จะรับค่าที่ส่งข้อผิดพลาดออกมา ในกรณีนี้ จะเป็นการดีกว่า ที่จะแสดง ข้อผิดพลาดที่กำหนดขึ้นเอง โดยการใช้ Err.Raise แทนที่จะโยนไปให้ ตัดจัดการข้อผิดพลาด จัดการให้ การทำงานนี้ จะแปลงรายละเอียดข้อผิดพลาดพื้นฐาน อย่างเช่น หมายเลขข้อผิดพลาด แหล่งกำเนิด และข้อความ แต่มันจะหลีกเหลี่ยงรายละเอียดที่ซับซ้อน อย่างเช่น รายละเอียดของ Call stackท้ายนี้ ให้เราเตรียม ชุดคำสั่ง Catch หลายๆ ตัวพร้อมกับ รายการกรองเงื่อนไขต่างๆ จากนั้นจัดเรียงให้ ข้อกำหนดที่เกิดขึ้นบ่อยๆ เป็นค่าแรกที่โปแกรมจะตรวจพบ ดังแสดงตามตัวอย่าง

Try

Catch SqlErr as SqlException

Catch err As Exception

Finally

End Try

วันพฤหัสบดี, มิถุนายน 03, 2553

ทิป : ใช้การรวมกลุ่มการเชื่อมต่อ (Connection Pooling) ในการติดต่อฐานข้อมูล

ข้อพึ่งปฏิบัติในการเชื่อมต่อกับฐานข้อมูล คือ ควรเรียกใช้การรวมกลุ่มการเชื่อมต่อเป็นศูนย์กลางเสมอ เนื่องจากตัวจัดการเซิร์ฟเวอร์ SQL สนับสนุนการ รวมกลุ่มการเชื่อมต่อเป็นค่าเริ่มต้นอยู่แล้ว ทั้งยังสามารถลดภาระงานจากนักพัฒนาลงไปได้มาก งานส่วนมากที่เราจะต้องทำ ก็เพียงแต่แก้ไขรายละเอียดการเชื่อมต่อ เพื่อนำมาใช้แทนที่ค่าเริ่มต้นที่ตั้งไว้ ผ่านทางพารามิเตอร์การรวมกลุ่มการเชื่อมต่อ (Connection Pooling)

วันอังคาร, มิถุนายน 01, 2553

ทิป : การใช้ฟังก์ชั่นจากศูนย์กลางในการเรียกใช้ข้อมูล

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

การประมวลคำสั่ง สโตร์โพรซีเยอร์และการคืนค่าผ่าน ออปเจ็กต์ DataReader
การประมวลคำสั่ง สโตร์โพรซีเยอร์และการคืนค่าผ่าน ออปเจ็กต์ DataSet
การประมวลคำสั่ง สโตร์โพรซีเยอร์และการคืนค่าผ่าน ออปเจ็กต์ XmlReader
การประมวลคำสั่ง สโตร์โพรซีเยอร์โดยไม่ส่งค่าคืน

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