[K2 Five] – Workflow REST & SMO OData

สวัสดีครับ วันนี้เราจะมาพูดถึง API ที่เราน่าจะได้ใช้กันบ่อยๆ คือ REST service ของ Workflow และ SmartObject

Workflow REST API

โดยสิ่งที่จะต้องทำเป็นอย่างแรกเลยคือ ไป enable service ใน Management site ก่อน

Workflow REST API Setting

หลังจากเปิดแล้วจะได้ตามด้านล่าง

Workflow REST API Setting Enable

เราสามารถทดสอบ API ได้จาก Swagger URL ด้วย

Workflow Swagger URL

Workflow Swagger Result

โดยตัวอย่างการใช้งานโดยเรียกจาก application อื่นๆ สามารถดูได้จาก https://help.k2.com/onlinehelp/k2five/DevRef/5.0/default.htm#Runtime/WF-REST/REST-Samples.htm

SmartObject OData API

เหมือนกับ Workflow REST API ต้องไปเปิดใน management site ก่อน (ถ้าเป็น version ก่อนๆ เราจะต้องไปเปิดใน config ตามวิธีใน  https://help.k2.com/onlinehelp/k2blackpearl/DevRef/4.7/default.htm#Configuration2.html)

SMO Service Setting

หลังจากเปิดแล้วจะเป็นตามด้านล่าง เราสามารถเลือก SmartObject ที่ต้องการ exposed เป็น REST service ได้ด้วย

SMO Server Setting Enable

ทีนี้พอเปิดแล้วเราก็มาลองกันซักหน่อย วิธีง่ายที่สุดคือ ใช้ Excel โดยเลือก Import Data From OData Data Feed

Excel OData

ใส่ link และ credential

Excel Data Connection Wizard

ใน wizard จะมี SmartObject ให้เลือก

List SMO

จากนั้นจะให้เลือก Import Data เป็นแบบไหน

Excel Import Data

จากนั้นก็จะได้ข้อมูลอย่างที่เราต้องการ 🙂

Excel

สำหรับรายละเอียด สามารถดูเพิ่มเติมได้จาก https://help.k2.com/onlinehelp/k2five/DevRef/5.0/default.htm#Runtime/SmO-REST/SmORESTServices.htm%3FTocPath%3DRuntime%2520APIs%2520and%2520Services%7CSmartObjects%7CSmartObject%2520REST%2520Services%7C_____0 ครับ

10 เทคนิคที่ทำให้ List View ของคุณโหลดเร็ว!!

List View เป็นการแสดงข้อมูลแบบหลาย records (ใครเขียน coding จะคล้ายๆ Grid view ใน C#) ในที่นี้จะขอรวมเทคนิคในการทำให้การเปิด List View ของคุณนั้นเร็วขึ้นมาอย่างแน่นอน

1. เรียกใช้ rule ในการ List แบบ Asynchronous

เปลี่ยนการเรียก execution block จาก then เป็น asynchronous ช่วยให้เรียก rule ได้อย่างรวดเร็วไม่ต้องรอจนทำงานเสร็จก่อนเรียก rule ถัดไป

execution block

ตอนแก้เสร็จก็ทดสอบก่อนนะ บางครั้งเราต้องรอข้อมูลก่อนหน้าให้โหลดเสร็จ แบบนี้ก็ต้องใช้ then ไปเนอะ

2. เปิด option ให้แสดงผลแบบ Paging

เปิด paging ใน list view แล้วจำกัดจำนวน item ที่จะเห็นในหน้าจอ จะช่วยลดปริมาณข้อมูลที่ต้องดึงมาแสดงผลที่หน้าจอได้

setting

ไม่ได้มีเลขเป๊ะ ๆ ว่าควรแสดงกี่รายการ แต่ส่วนใหญ่ที่ทำมักจะใช้ในช่วง 10 – 50 รายการต่อหน้าจอครับ

3. ลดการใช้งาน Association

ปกติจะใช้ร่วมกับ List Display ในกรณีที่เราเก็บ ID เป็น reference ไว้ แล้วต้องการไปดึงค่า Value ออกมาแสดงโดยอ้างอิงจาก ID

ถ้าเราอยากให้ performance ในการโหลด List View เร็วขึ้น สามารถทำได้โดยการทำการ join ในข้อมูลตั้งแต่ data source เองเช่น การเขียน Stored procedure หรือเขียน view ใน SQL ก็จะช่วยลดการทำงานในส่วนของ List Display และ association นี้ลงได้ (แต่ถ้าไม่ได้ช้ามาก ใช้ association ก็สะดวกดีครับ)

4. ลดจำนวน Column ที่แสดงใน List View

จำนวน column ที่แสดงน้อยลงจะทำให้ตอน bind เข้า List view สามารถแสดงผลได้รเ็วขึ้นไปอีก อ่อ..ต้องลบออกนะครับ ไม่ใช่แค่ซ่อนด้วย Visible = false

removeColumn

5. ลดจำนวน Properties ที่ส่งกลับมาจาก SmartObjects

โดยปกติถ้าเราสร้าง SmartObjects จากตารางบนฐานข้อมูล ใน SmartObjects จะมีจำนวน Properties เท่ากับจำนวนคอลัมน์ในตารางเลย ซึ่งเราสามารถไปลบ properties นี้ออก หรือเลือกให้ส่งกลับมาเฉพาะ properties ที่เราจะใช้ก็พอ

bind.png

หรือถ้ามีคนอื่นใช้ method นี้อยู่ด้วย ไปสร้าง method แยกไว้สำหรับหน้านี้โดยเฉพาะก็ยังได้ครับ

6. แสดงไฟล์ใน List View ด้วยลิงค์สำหรับดาวน์โหลด แทนที่จะแสดง file content

กรณีถ้าเราต้องโหลดไฟล์ขนาดใหญ่หรือไฟล์เล็ก ๆ จำนวนมากใน 1 หน้าจอก็ตาม การแสดงผลด้วย data type เป็น File จะโหลดไฟล์จริงขึ้นมาด้วย ถ้ายิ่งไฟล์มีขนาดใหญ่ ก็จะใช้ระยะเวลานานในการโหลดข้อมูล

fileListView.png

เราสามารถเปลี่ยนวิธีการเก็บไฟล์ไปอยู่บน shared network path หรือ Content Management System (CMS) เช่น SharePoint แทนได้ และแสดงผลเป็นลิ้งค์แทน เมื่อผู้ใช้งานต้องการเปิดไฟล์ ค่อยกดลิ้งค์ที่เราแสดงเพื่อไปโหลดไฟล์นั้นตรงจากที่ที่เราเก็บไฟล์ไว้ได้

7. ใช้ Input Properties ในการดึงข้อมูลแทนที่จะใช้ Filter

Filter นั้นมีความสามารถในการช่วยกรองข้อมูลที่จะแสดงใน List View ได้ด้วยเงื่อนไขต่าง ๆ แต่คุณรู้หรือไม่ว่าการใช้ Filter นั้นทำให้การแสดงผลใน List View ช้าลง เพราะข้อมูลจะถูกดึงมาทั้งหมดก่อนจึงจะมากรองออกด้วย Filter เพื่อแสดงผลในหน้าจอ

filter.png

การใช้ Input properties นั้นหลังบ้านมันคือการใส่ Where casue ว่า Input properties = ‘Value’ นั่นเอง ทำให้สำหรับหลายกรณี เจอว่า Input Properties นั้นไม่เพียงพอ เพราะต้องการค้นหาด้วยเงื่อนไขอื่นเช่น Contains, Greater than บ้าง

วิธีปรับคือพยายามควรป้อนข้อมูลใน Input properties ได้มากที่สุดก่อนเพื่อลดปริมาณข้อมูลที่ต้องโหลดขึ้นมา แล้วจึงเลือกใช้ Filter ต่ออีกทีเพื่อใส่เงื่อนไขแบบซับซ้อนลงไป หรือถ้าพบยังไม่เพียงพอ ผมก็จะใช้ View หรือ stored procedure มาช่วยรองรับเงื่อนไขแบบซับซ้อนครับ

8. ตรวจสอบว่าไม่โหลดข้อมูลซ้ำ 2 รอบ

ในการสร้าง List View ต่อกับ SmartObjects จะมี option ที่หน้า general ตรงด้านล่างว่าจะให้ Call this method when the form loads เลยหรือไม่

ถ้าไปติ๊กเลือก option นี้ระบบจะไปสร้าง rule Get List ไว้ใน View Initilize และถ้าลากไปใช้ใน Form Method Get List นี้ก็จะถูกเรียกใน Form Initilizing ด้วย (นอกจากนี้ด้วยค่า default ไม่ได้ใส่ input properties เลยทำให้มันจะดึงข้อมูลขึ้นมาทั้งหมด!!)

ListViewsGet.png

เคสที่เคยเจอคือมีไปเลือก option นี้ใน View ทำให้มีการโหลดข้อมูลแบบทั้งหมดขึ้นมา และเพิ่ม rule ใน Form initilzing ต่อ โดยโหลดข้อมูลแบบใส่ input properties ทำให้ตอนทดสอบแสดงผลที่หน้าจอถูกนะ แต่กว่าจะเปิดขึ้นมาทีช้ามาก วิธีแก้คือไปเอา rule นี้ออกซะ หรือเพิ่มเงื่อนไขให้เช็คก่อนใน View Initilize

9. ปิดการใช้ SmartForm ListView Row Count

จากที่เคยเขียน Blog ว่าด้วยเรื่องการแสดง Paging ใน Listview และ แก้ปัญหา SmartObjects สร้างข้อมูลซ้ำ หลังบ้านมีการทำงานโดยไปเรียก List method ขึ้นมา 2 ครั้งเพืื่อหาจำนวน page และเพื่อแสดงรายการ ทำให้เวลาในการโหลดข้อมูลนานขึ้น การไปตั้งค่า SmartObject.RuntimeListViewRowCount = false ก็จะช่วยให้ List method ต่าง ๆ ทำงานได้เร็วขึ้น

10. Tuning data source

ข้อนึงที่มักจะมองข้ามกัน คือการตรวจสอบที่ data soruce ตั้งต้นด้วยครับ ว่าเรียกใช้งานตรงๆ (ด้วยค่า input เดียวกับที่เราเรียกใน List view) ใช้ระยะเวลาเท่าไหร่ ถ้าระยะเวลาในการโหลดนานย่อมส่งผลต่อการเรียกผ่าน List View ไปด้วย

ส่วนวิธีแก้ให้ทำการปรับแต่งตั้งแต่ที่ data source ด้วยครับ เช่นการใส่ index ใน view หรือ table, การแก้ logic ที่ web service หรือ stored procedure ให้ทำงานเร็วตั้งต้นทาง

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

แก้ปัญหา SmartObjects สร้างข้อมูลซ้ำ

มาจากคำถามจากทางบ้านอีกเช่นกันครับ สำหรับปัญหาที่ว่าสร้างข้อมูลจาก SmartObjects แล้วพบว่ามีข้อมูลเข้าไป 2 records

ถ้าใครเจอปัญหานี้เหมือนกันให้ลองตรวจสอบว่าเราได้ตั้งค่าหรือมีอาการตามนี้หรือไม่

  1. SmartObjects ต่อกับ Stored procedure ใน SQL
  2. Method ใน SmartObjects ที่ใช้สร้างข้อมูลเป็น type แบบ List
  3. ทดสอบเรียกผ่าน SmartObjects Services Tester แล้วพบว่าสร้าง 1 record แต่ถ้าเรียกผ่าน SmartForm แล้วเข้าไป 2 records

methodList.png

ถ้าใครเจอว่ามีอาการดังกล่าว แสดงว่าน่าจะมาจากสาเหตุเดียวกันแล้วครับ ให้ลองตรวจสอบเพิ่มอีกครับว่าเราได้ไปเปิดการแสดงผล paging ใน List View ด้วยหรือไม่

วิธีตรวจสอบง่าย ๆ คือไปเปิด List View ขึ้นมานะ ว่ามีแสดง paging หน้าสุดท้ายหรือไม่ (ถ้าไม่ได้เปิดจะไม่มีในวงเล็บ) แต่ถ้ามีก็ชัดเลยครับ ไปอ่านวิธีแก้กันต่อด้านล่างได้เลย (ส่วนวิธีการเปิดเคยเขียนไว้ใน blog นี้ -> ว่าด้วยเรื่องการแสดง Paging ใน Listview)

listview3.png

สาเหตุของอาการนี้มีสองอย่างด้วยกัน คือเพราะ method ใน SmartObject เป็นแบบ List และมีการเปิด SmartObject.RuntimeListViewRowCount ไว้ ทำให้ทุก method ที่เป็น List จะถูกเรียกสองครั้งเสมอ

วิธีแก้มีสองวิธีครับ

  1. แบบง่าย: ก็คือไปปิดการแสดง paging ของ List View ซะ (SmartObject.RuntimeListViewRowCount = false) แต่ถ้าเรายังอยากได้ทั้งการแสดงผลแบบนี้ และยังสร้าง record ให้ไม่ซ้ำด้วย ไปทำตามข้อสองครับ
  2. แบบยาก: ต้นเหตุคือตัว stored procedure ส่งประเภท method มาเป็น List อยู่ เราต้องไปแก้ stored procedure ให้ส่งมาเป็นประเภท Execute แทน โดยการเพิ่มบรรทัด SET FMTONLY ON ใน stored procedure แนะนำให้อ่านวิธีแก้เต็ม ๆ ใน KB นี้ครับ -> Determined SmartObject method ‘List’ or ‘Execute’ when SmartObject was created from SQL Store Procedure

ST136024.jpg

ย้อน version ของ K2 component ยังไงกันนะ?

Blog นี้เริ่มจากคำถามจากทางบ้านนะครับ ว่าในการพัฒนา K2 เห็นมีการเก็บ version ไว้ ทั้ง Workflow , SmartForm และ SmartObject

version.png

แต่ยังหาวิธีการย้อน version ไม่เจอว่าต้องทำยังไง ใน blog นี้เลยจะบอกวิิธีการของแต่ละส่วนครับ

1. Workflow

เริ่มด้วยการย้อน version ของ workflow ก่อนนะครับ เพราะเป็นส่วนที่ทำได้ง่ายที่สุดแล้ว เราสามารถเข้าไปดู version ของ workflow ได้ผ่านทาง K2 Workspace หรือ K2 Management (สำหรับ version 4.7 ขึ้นไป)

สำหรับ K2 Workspace ไปที่เมนู [Server name] -> Workflow Server -> Processes -> [Process Name] -> Versions

processVersion.png

สำหรับ K2 Management ไปที่ Workflow Server -> [Workflow name] แล้วกดที่ tab Versions

processVersion47

โดยในทั้งสองไซต์ เราสามารถเลือกย้อน version ในการทำงานของ workflow ได้โดยเลือกกดที่ Set as default (มีผลเฉพาะกับ workflow ที่ยังไม่ start มานะครับ) และสามารถเลือก Download workflow version นั้น มาแก้ไขได้อีกด้วย

2. SmartForm

การย้อน version ของ smartform สามารถทำได้โดยใช้ stored procedure ที่ชื่อ Form.mRevertToVersion โดยสามารถย้อนได้ทั้ง View และ Form

สามารถตามไปอ่านวิธีการ step by step ได้ที่ -> How to roll back to a deleted or previous version of a View or a Form

3. SmartObjects

SmartObject นั้นเก็บโครงสร้างอยู่ที่ database ของ K2 แยกตาม version ที่ deploy ไป ดังนั้นการย้อน version SmartObject นั้นต้องทำตรงที่ database เลย โดยไม่ได้มี stored procedure ช่วย เหมือนการย้อน SmartForm

วิธีการทำก็คือ ต้องใช้ SQL Command ในการ update โดยนำ XML ใน SmartObjectXML ของ version ที่ต้องการย้อนกลับไป นำมาอัพเดทให้ version ล่าสุดนั่นเอง

smoVersion.png

ย้อน version SmartForm กับ SmartObject เป็นการทำงานตรงกับ database ของ K2 ซึ่งอาจมีโอกาสเกิดความผิดพลาดกับ database แนะนำว่าไม่ควรทำบนเครื่อง Production และให้ backup database K2 ทั้งก้อน ก่อนจะเริ่มทำนะครับ

Consume REST Services with K2

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

การเชื่อมต่อ REST service ใน K2 จะแตกต่างจากการเชื่อมต่อ web service อื่นๆ อยู่ตรงที่ เรารู้แค่ url ของ web service นั้นไม่พอ สิ่งที่ต้องมีถัดไปคือ descriptor file ใน format ของ JSON ถ้าเป็น REST service ที่เราเขียนเองก็อาจจะไม่ยาก เพราะเราสามารถ generate JSON ออกมาจาก swagger ที่เราเขียนได้ แต่ถ้าไม่ได้เขียนเองมี option ตามด้านล่าง

โดยในส่วนที่อยู่ใน blog นี้จะเป็นการเขียนเอง

ถ้าจะเขียน descriptor เอง เราควรรู้อะไรบ้าง?

  • Format ที่ REST Service response ออกมา
  • Swagger syntax ที่จะใช้เขียน เพื่อทำ mapping กับ service ที่เราจะใช้

ผมเลือก service จาก Accuweather (https://developer.accuweather.com) มาลองดู สามารถสมัครมาลองใช้ได้ฟรี แต่ service ก็จะ limit หน่อย (ถ้าใครอยากลอง ก็ไปสมัครแล้ว register app ก็จะได้ API Key ที่ต้องใช้ในมา) ใช้ได้ไม่กี่อัน แต่หลักๆ ของ service ที่มีให้คือ การพยากรณ์ต่างๆ

Weather API

ที่เราจะใช้กันคือ Location API เพื่อหาพื้นที่ที่ต้องการ กับ Forecast API เพื่อดูพยากรณ์ (จริงๆ อยากใช้ Weather Alerts มากกว่า แต่แบบฟรีใช้ไม่ได้ T-T)  อย่างที่บอก เริ่มแรกคือ ต้องไปลองเรียก REST Service เพื่อให้ return response มาซะก่อน

API Response

พอได้ response เราก็เอามาเขียน swagger เพื่อที่จะ generate เป็น descriptor กัน รายละเอียดเกี่ยวกับ swagger ลองอ่านดูตาม link ด้านล่างนะครับ

Tool ที่ผมใช้ในการเขียน swagger ก็มาจาก swagger.io นี่แหละ ใช้เป็นแบบ online เลยง่ายดี สามารถเข้าไปได้ที่ http://editor.swagger.io  ถ้าเขียนเสร็จแล้วก็น่าจะได้ format แบบด้านล่างนี่ล่ะ

Swagger UI

สิ่งที่ควรระวังตอนเขียน swagger คือ ในบางกรณีที่เรามีการเรียกใช้ reference object ซ้อนๆ กัน การประกาศบางแบบอาจจะเรียกใช้ไม่ได้ใน K2 นะครับ แบบที่ใช้ได้จะมีตัวอย่าง file swagger ที่เขียนให้ download ตอนท้ายบทความครับ

เมื่อเขียนเรียบร้อย เราสามารถ generate JSON file ได้โดยเลือกเมนู File -> Download JSON

Download JSON

พอได้ file มา เราก็เอามา register กับ K2 โดยผ่าน SmartObject Service Tester

02-Register REST

03-Register 2

หลังจาก register แล้ว เราก็จะเห็น object ที่สามารถเรียกได้ตามด้านล่าง

04-After Regist

จะเห็นว่า มี method พวก Serialize กับ Deserialize มาด้วย method พวกนี้จะเป็น method สำหรับดึงค่าจาก type ที่ return มาเป็น structure เหมือนกับที่เราใช้ K2 ต่อกับ SAP หรือ web service อื่นๆ จากนั้นลองสร้างเป็น smartobject แล้วทดสอบดู

05-Test City Search

อย่างแรกเลยคือ call City Search เพื่อหาเมือง เพิ่งรู้นะเนี่ยว่า กรุงเทพฯ มีที่อินโดนีเซียด้วย พอได้แล้ว ผมก็เอา Key ไปใช้เพื่อหา forecast ของ 5 วันข้างหน้า

06-5 day forecast

ใน method นี้จะ return Headline หรือคือ พาดหัวข่าวสำคัญ เช่น ฝนจะตกหนักวันไหน กับรายละเอียด forecast มาเป็น object ส่วนที่เราต้องทำถัดไปคือ เอา xml ยาวๆ ที่ได้ ไป call method Deserialize เพื่อให้แสดงผลออกมาเป็น property ออกมา

ส่วนของ Headline ผมได้ xml ตามด้านล่างออกมา

{“$type”:”Accuweather.k2RESTidentifier_Headline, Accuweather, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”,”EffectiveDate”:”2017-08-13T01:00:00+07:00″,”Text”:”A thunderstorm late Saturday night”,”Category”:”thunderstorm”,”Link”:”http://www.accuweather.com/en/th/bangkok/318849/daily-weather-forecast/318849?lang=en-us”}

ผลหลังจากการ call โอ๊ะ!!! ฝนตกหนักคืนวันเสาร์ตอนดึกๆ

07-Headline Call

ส่วนของพยากรณ์จะได้เป็น array ออกมา

{“$type”:”Accuweather.k2RESTidentifier_DailyForecast[], Accuweather, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”,”$values”:[{“$type”:”Accuweather.k2RESTidentifier_DailyForecast, Accuweather, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”,”Date”:”2017-08-10T07:00:00+07:00″,”Link”:”http://www.accuweather.com/en/th/bangkok/318849/daily-weather-forecast/318849?day=1&lang=en-us”},{“$type”:”Accuweather.k2RESTidentifier_DailyForecast, Accuweather, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”,”Date”:”2017-08-11T07:00:00+07:00″,”Link”:”http://www.accuweather.com/en/th/bangkok/318849/daily-weather-forecast/318849?day=2&lang=en-us”},{“$type”:”Accuweather.k2RESTidentifier_DailyForecast, Accuweather, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”,”Date”:”2017-08-12T07:00:00+07:00″,”Link”:”http://www.accuweather.com/en/th/bangkok/318849/daily-weather-forecast/318849?day=3&lang=en-us”},{“$type”:”Accuweather.k2RESTidentifier_DailyForecast, Accuweather, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”,”Date”:”2017-08-13T07:00:00+07:00″,”Link”:”http://www.accuweather.com/en/th/bangkok/318849/daily-weather-forecast/318849?day=4&lang=en-us”},{“$type”:”Accuweather.k2RESTidentifier_DailyForecast, Accuweather, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”,”Date”:”2017-08-14T07:00:00+07:00″,”Link”:”http://www.accuweather.com/en/th/bangkok/318849/daily-weather-forecast/318849?day=5&lang=en-us”}]}

ผลหลังจากการ call ก็เป็นตามด้านล่าง

08-DailyForecast Call

จริงๆ ค่าที่ REST return มามีมากกว่าที่ผมเอามาแสดง แต่ผมเขียน swagger เพื่อเอาค่ามาเฉพาะที่ต้องการเท่านั้น (ขี้เกียจนั่นเอง = =’) ถ้าใครอยากดูตัวอย่างการเขียน swagger กับ file JSON ที่ generate ออกมาได้สามารถ download ได้ตาม link ด้านล่างนะครับ

สำหรับคราวนี้ก็ขอลาแต่เพียงเท่านี้ พบกันใหม่คราวหน้าครับ 🙂

[K2API] SmartObject Error ว่า Exception of type ‘SourceCode.SmartObjects.Client.SmartObjectException’ was thrown.???

วันนี้เรากลับมานำเสนอ KB สำหรับเหล่าชาวขาเดฟผู้เรียกใช้งาน K2 API ในส่วนของการต่อ SmartObjects กันบ้างนะครับ

เริ่มด้วยตัวอย่างจากโค้ดข้างล่าง เป็นการดึงข้อมูลจาก SmartObjects ที่ชื่อว่า Comments ขึ้นมาเก็บใน DataTable

SMOGetList1

ทำงานไปก็ใช้งานได้ปกติครับ แต่วันดีคืนร้าย เกิดมี error ขึ้นมาในส่วนนี้จะทำยังไง …ไม่ต้องตกใจเราเขียน try-catch ให้มี exception ออกมาแล้วนี่นา เดี๋ยวไปเช็คใน log เอาละกัน

SMOGetListError0

SMOGetListError

อ่าว..แย่ล่ะสิ Exception ที่ใช้กันมานมนาน ฟ้องว่า “Exception of type ‘SourceCode.SmartObjects.Client.SmartObjectException’ was thrown.” แต่ดันไม่ได้บอกว่ามัน error ที่ไหน ใน InnerException ก็ไม่มีซะด้วย

พระเอกข้างเราคือโค้ดด้านล่างนี้เลยครับ เอาไปใส่แทน catch (Exception ex) ไปเลย

catch (SmartObjectException soe)
 {
 StringBuilder errorMessage = new StringBuilder();
 foreach (SmartObjectExceptionData smartobjectExceptionData in soe.BrokerData)
 {
 string message = smartobjectExceptionData.Message;
 string service = smartobjectExceptionData.ServiceName;
 string serviceGuid = smartobjectExceptionData.ServiceGuid;
 string severity = smartobjectExceptionData.Severity.ToString();
 string innermessage = smartobjectExceptionData.InnerExceptionMessage;
 errorMessage.AppendLine("Service: " + service);
 errorMessage.AppendLine("Service Guid: " + serviceGuid);
 errorMessage.AppendLine("Severity: " + severity);
 errorMessage.AppendLine("Error Message: " + message);
 errorMessage.AppendLine("InnerException Message: " + innermessage);
 }
 throw soe;
 }

มาทดสอบใหม่อีกครั้งกันครับ

SMOGetListError2

คราวนี้เห็นรายละเอียดครบเลย ว่า error ที่ SmartBoxService และ error ฟ้องว่าชื่อคอลัมน์ของ smartobjects ที่ชื่อ “Comments” มันไม่ถูกนะ ..สงสัยจะมีคนเปลี่ยนชื่อคอลัมน์ใน database

หวังว่าจะช่วยให้ debug กันง่ายขึ้นครับ ผมขอไปหาคนที่มาเปลี่ยนชื่อคอลัมน์ก่อน -“-