Programming

Beware when using Microsoft.Owin.Security.OAuth and Microsoft.AspNet.WebApi.Cors

Submitted by ezybzy on Sun, 2019-01-20 - 13:55

Recently, I helped colleague securing his ASP.NET WebApi. The WebApi was called from SharePoint Online using JavaScript. We thought that an integration with OAuth would be simple for CORS (cross-origin resource sharing) but we took a week to figure out what went wrong with mash up code.

Blog Tags

ทำ HTML Slideshow

Submitted by ezybzy on Sun, 2012-02-26 - 11:05

เนื่องจากรับหน้าที่ไปสอนนักศึกษามหาวิทยาลัยกลุ่มหนึ่ง หัวข้อที่สอนคือ CSS เราก็อยากจะทำเอกสารประกอบการสอนให้เข้ากับเรื่องนี้ ก็เลยมาลงที่การทำสไลด์ด้วย HTML เพื่อให้นักศึกษากลุ่มนี้เกิดความรู้สึกว่า “สิ่งที่เขาเรียนไป มันใช้ทำอะไรได้ขนาดนี้เลยเหรอ”

ตอนแรกก็ลอง ๆ หาก็พบ html5slides ซึ่งก็ถือว่าใช้งานได้ง่ายเลยทีเดียว แต่มีข้อจำกัดว่าขณะใช้งานต้องเชื่อมต่ออินเตอร์เน็ต เนื่องจากการอ้างอิง js, css, ฟอนต์ในนั้น อยู่ภายนอกหมด ก็เลยต้องออกแรงแก้ไขดัดแปลงนิดหน่อยให้สามารถใช้งานแบบ Offline ได้

แต่ Template ชุดนี้ก็ดันมีปัญหากวนใจสำคัญเรื่องหนึ่งคือการแสดงผล iframe ใน Google Chrome ที่จะทำให้หน้าสไลด์เลื่อนจนไม่เหมาะสมแก่การใช้งาน ซึ่งในจุดนี้ก็จนปัญญาจะแก้เหลือเกิน (คงเป็น Internal ใน Google Chrome นี่แหละทำให้เกิดปัญหาการแย่งซีนของ iframe ขึ้นมา)

ในเวลาเดียวกัน ก็ลองค้นหาต้นแบบอื่น ๆ ก็ไปพบกับต้นแบบที่คล้าย ๆ กับของที่ปรากฏใน slides.html5rocks.com อีกตัว เข้าใจว่าเขาคง port ออกมาจากสไลด์ตัวนี้แหละ ชื่อ g5 ซึ่งตอนแรกคิดว่าจะมีรูปแบบการทำงานเดียวกับแบบแรก แต่ที่แท้จริงแล้ว ตัวนี้ต้อง build ผ่านทางคำสั่ง slideshow ซึ่งเป็นแพคเกตตัวหนึ่งใน gem นั่นก็นำมาสู่ขั้นตอนการติดตั้งอันแสนจะวุ่นวายยามค่ำคืน

อันดับแรก ติดตั้ง slideshow ก่อนผ่านทาง gem

sudo gem install slideshow

ขั้นต่อมาติดตั้ง Template ของ g5 ผ่านคำสั่ง

slideshow -f https://github.com/geraldb/slideshow-google-html5-slides/raw/master/g5.txt

ต่อมาก็ทำการสร้าง Directory ว่าง ๆ ซักที่ แล้วเข้าไปเรียกใช้คำสั่งนี้ เพื่อสร้างไฟล์ทั้งหมดออกมา

slideshow -t g5.txt tutorial

ที่นี้ปัญหาคือ เราจำเป็นต้องมีไฟล์ tutorial นี้เสียก่อน ซึ่งจริง ๆ ก็เป็นแค่ text file ธรรมดานี่แหละ แต่ในเว็บเขาไม่ได้บอกเอาไว้ว่าต้องทำ (แหมเราก็ซื่อนะ ไม่เคยใช้นี่) ก็วนเวียนสาระวนกับเรื่องนี้มา 1 คืน ไปเอา rvm มาติดตั้งโหลด ruby 1.9 มาติดตั้ง แล้วก็ไม่ได้อะไรขึ้นมาหนำซ้ำยังไปติดปัญหาอื่นที่งงกว่าเดิม สุดท้ายก็ถอนออก แล้วจึงทำการสร้าง tutorial ขึ้นมา (ผมเลือก Markdown แทนการใช้ Textile นะ) โดย

touch tutorial.text

แล้วจึงทำการเรียกใช้งานคำสั่งที่แล้วอีกครั้ง ก็จะสามารถสร้างสไลด์ตัวอย่างออกมาได้

การกำหนดหัวข้อให้เรากำหนดได้ใน tutorial ของเราตามรูปแบบที่เขียนในเว็บได้เลย แล้วก็ใช้หัวข้อลำดับ 1 ในการแบ่งสไลด์ไปเรื่อย ๆ ขั้นต่อไปคงจะมาดูขั้นตอนการปรับขนาดอักษรภายในให้ใหญ่ขึ้นอีกหน่อย เพราะด้วยปัจจุบันค่อนข้างเล็กมาก

Blog Tags

ทำ Unit Test สำหรับ SharePoint 2010

Submitted by ezybzy on Thu, 2012-02-16 - 20:44

มีโครงการกับทีมงานที่ที่ทำงานว่าเราจะพัฒนาซอฟท์แวร์โดยนำแนวทาง Test Driven Development มาใช้ กล่าวง่าย ๆ คือการเขียน Test ก่อนการพัฒนา ซึ่งนั่นก็แน่นอนว่าเราต้องทำ Class กันเข้มข้นพอสมควร ขั้นตอนก่อนจะเริ่มกระบวนการนี้เราคงต้องมาทบทวนกันว่าใน Visual Studio 2010 นั้นมีกระบวนการใดบ้างที่จะทำ Unit Test กับโปรเจคที่ทำงานกับ SharePoint 2010

มาดูสภาวะแวดล้อมกันก่อน เครื่องที่ผมใช้จัดกระบวนการนี้เป็น Windows 7 (x64) Enterprise Edition SP1 ติดตั้ง SharePoint Foundation 2010 SP1 และ Visual Studio 2010 Ultimate SP1

สิ่งแรกที่ได้ทำคือ เราต้องทำการสร้าง Empty SharePoint Solution ขึ้นมา 1 อัน เพราะเราต้องการจะสร้าง Class Library ที่มีการอ้างอิงเกี่ยวกับไลบารี่ของ SharePoint ให้เรียบร้อย หลังจากนั้นก็ทำการสร้าง Test Project เพิ่มเข้าไปใน Solution เดิมของเรา

ขั้นนี้ปัญหาข้อแรกที่พบคือ SharePoint Project ของเราจะใช้งาน .NET Framework 3.5 แต่ Test Project ใช้งาน .NET Framework 4 ซึ่งไม่ง่ายเลยที่จะปรับให้ Framework ตรงกัน แต่เมื่อตามลิงค์ที่อยู่ตอนท้ายของหน้าต่างแจ้งปัญหานั้น (แหมจะทำให้มันกดลิงค์ง่าย ๆ หน่อยก็ไม่ได้นะ Microsoft) ดังนี้ Possible Additional Steps to Enable Re-targeting of Test Projects to .NET Framework 3.5 ซึ่งบอกให้ทำการแก้ไข devenv.exe.config ซึ่งก็เหมือนจะผ่านไปได้ด้วยดี เราก็สามารถเปลี่ยน Test Project ให้มีเป้าหมายเป็น .NET Framework 3.5 ได้แล้ว

ขั้นตอนเหมือนจะผ่านไปได้ด้วยดี ผมก็เริ่มทำการสร้าง Code ทดสอบมีการเรียกใช้งาน SPSite และ SPWeb แล้วจึงทำการสร้าง TestInitialize เพื่อสร้างออปเจ็คของ SPSite และ SPWeb เพื่อผ่านค่าไปยัง Code ซึ่งก็ไม่ได้ทำอะไรผิดปกติ เมื่อทำการรันเทส ก็พบข้อผิดพลาดยอดนิยมที่คาดว่าจะได้เจอนั่นคือ

System.IO.FileNotFoundException: The Web application at {sharepointurl} could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.

สิ่งแรกที่ผมเดาคือ เพราะ Platform target ของ SharePoint Project ไม่ได้เป็น x64 ก็เลยลองเปลี่ยนจาก Any CPU เป็น x64 แต่แล้วก็พบกับ Error ตัวอื่นคือ

System.BadImageFormatException: Could not load file or assembly '{assemblyinfo}' or one of its dependencies. An attempt was made to load a program with an incorrect format.

ดูจะเลวร้ายไปกันใหญ่ครับ ปัญหานี้เกิดเพราะการพยายามโหลดไลบารี่ x64 จาก x86 ครับ นั่นเพราะตัวโหลดเทสยังคงทำงานเป็น x86 อยู่ ไม่ได้เป็น x64 แบบที่เราต้องการ ก็ลองค้นหาข้อมูลก็ได้พบข้อมูลจากบล็อกหนึ่งในทีมที่ทำตัว Test ใน Visual Studio ให้แนวทางไว้ว่า สามารถทำ Class คั่นกลางหลอกได้ โดย Class นี้จะไปเรียกไลบารี่ x64 อีกต่อหนึ่งไม่ให้ตัวเทสเรียกไลบารี่ x64 โดยตรง ซึ่งก็เหมือนจะใช้ได้นะ แต่หลังจากนั้นก็ไปค้น ๆ ในบล็อกของคนเดิม เจอสิ่งที่เด็ดกว่านั้นนั่นคือ Visual Studio Team Test Load Agent Goes 64 Bit! ซึ่งนั่นก็คือตัวรันเทสมันเป็น x64 อยู่แล้ว แต่เราต้องตั้งค่ามันให้เป็น โดยต้องไปปรับค่าของ Run tests in 32 bit or 64 bit process ซึ่งหลบอยู่ในหัวข้อ Hosts ใน Test Setting ให้เป็น Run tests in 64 bit process on 64 bit machine แล้วก็ไปทำการปรับค่า Platform target ของทั้ง Test Project และ SharePoint Project เป็น Any CPU

หลังจากนั้นทุก Error ที่เจอก็จะหายไป สามารถทำ Test ได้แล้ว แต่วิธีนี้ก็ยังมีข้อจำกัดคือ ไม่สามารถทำการทดสอบ private Method ได้ จะเจออาการ BadImageFormatException ซึ่งก็คาดเดาได้ว่าเกิดจากกระบวนการพิเศษที่ใช้ล้วงลูกนั่นเอง ก็หวังว่าจะมีการปรับปรุงแก้ไขกันต่อไปให้สามารถใช้งานได้

Blog Tags

เมื่อ Stop แล้วมันไม่จบ

Submitted by ezybzy on Thu, 2012-01-05 - 10:39

เคยไหม เปิดหน้าเว็บเพื่อทำธุรกรรมบางอย่างแล้วรอนานมากจนกด Stop แล้ว Refresh เพื่อเริ่มใหม่?

สำหรับคนทั่วไปอาจจะคิดว่าเมื่อ Stop แล้วทุกอย่างจะจบพร้อมเริ่มใหม่เมื่อเรากด Refresh แต่จริง ๆ แล้วมันไม่ได้เป็นเช่นนั้นเลย

ความจริงที่เกิดขึ้นคือการ Stop ของเราเป็นแค่การหยุดรับผลลัพธ์ (HTTP Response ที่ถูกส่งกลับมา) แต่กระบวนการสร้างผลลัพธ์นั้นก็ยังคงดำเนินต่อไป

ตัวอย่างง่าย ๆ ลองเขียน Java Servlet หนึ่งตัวโดย Code ต่อไปนี้

try {
    this.getServletContext().log("Begin: " + Calendar.getInstance().toString());
    Thread.sleep(20 * 1000);
    // ... (Write something out to screen)
    throw new Exception();
} (Exception e) {
    this.getServletContext().log("End: " + Calendar.getInstance().toString());
}

จากตัวอย่าง Code ด้านบน จะเห็นว่ามีการหน่วงเวลาไว้ 20 วินาทีก่อนจะแสดงผลใด ๆ ออกทางหน้าจอ แต่หากเรากด Stop ไปที่ช่วงวินาทีที่ 15 แล้วอ่าน Log ของ Tomcat หลังจากนั้นซักพักใหญ่ เราจะพบทั้ง Begin และ End ใน Log นั่นจึงเป็นการพิสูจน์ได้ว่า เมื่อเกิดการ Request ขึ้นมา กระบวนการในการจัดการ Request จะถูกดำเนินการจนแล้วเสร็จโดยไม่สนว่าผู้รับ (ในกรณีนี้คือ Browser) จะอยู่รอรับผลหรือไม่

Blog Tags