เนื่องในโอกาสที่ ASP.NET MVC 1.0 ออกตัวเต็มมาเป็นที่เรียบร้อยแล้ว เราก็ได้โอกาสเขียนถึงเจ้า ASP.NET MVC อย่างจริงๆจังซักที แถมหลังๆมาก็ไม่ได้ใช้ ASP.NET MVC เลย คราวนี้ขอเขียนแบบ Back to basic เพื่อจะช่วยให้เห็นอะไรที่ไม่เคยเห็นบ้าง
MVC ย่อมาจาก Model-View-Controller สำหรับคนที่ยังไม่รู้ว่ามันคืออะไร ใน Wikipedia อธิบายว่า
Model–View–Controller (MVC) is an architectural pattern used in software engineering. In MVC, the model represents the information (the data) of the application; the view corresponds to elements of the user interface such as text, checkbox items, and so forth; and the controller manages the communication of data and the business rules used to manipulate the data to and from the model.
ถ้าให้เห็นรูปอย่างง่ายๆ ความสัมพันธ์ระหว่าง Model-View-Controller จะเป็นดังรูป
Controller คืออะไร
Controller เป็นส่วนที่ใช้ควบคุม จัดการและ”คิด”ว่าถ้าผู้ใช้ทำอะไรซักอย่าง แล้วโปรแกรมจะต้องทำงานอย่างไรต่อไป ซึ่งต่างจาก View เพราะในแง่ของ MVC แล้ว View จะทำหน้าที่แสดงข้อมูลที่ได้รับมาจาก Controller (ซึ่งอาจจะได้ข้อมูลมาจาก Model อีกทอด) ลองดูรูปอีกครั้งถ้าไม่เข้าใจ
ใน ASP.NET MVC คลาสที่จะทำหน้าที่เป็น Controller ได้จะต้องสืบทอดมาจากคลาส Controller และต้องมีชื่อคลาสที่ลงท้ายด้วย Controller ด้วย ยกตัวอย่างเช่น ProductController ก็จะหมายถึง Controller ชื่อ Product เป็นต้น
Controller Action
Controller Action คือเมธอดที่จะให้ทำงานซึ่งปกติแล้วจะถูกเรียกเมื่อผู้ใช้เข้ามาใน URL ที่ route เอาไว้ โดยเมธอดที่จะเป็น Controller Action ได้จะ
- ต้องเป็น public
- ไม่ใช่เมธอด static
- ห้าม overload ห้ามชื่อซ้ำ จุดนี้ไม่ใช่ปัญหาเราใช้ Routing เข้ามาช่วยได้
- ต้องมี Return type เป็น ActionResult เสมอ (ถ้าไม่ใช่มันจะถูกบังคับให้เป็น ContentResult เสมอ มันคืออะไรอ่านต่อไปเรื่อยๆ)
ส่วน Parameter ของ Action จะเป็นอะไรก็ได้
Action Result
ActionResult เป็นผลของการทำงาน Action ที่จะส่งคืนให้กับผู้ใช้ ยกตัวอย่างเช่น HTML ที่ได้จากการเรนเดอร์, ข้อความ, ไฟล์ไบนารีต่าง หรือแม้กระทั่งสั่งให้ Redirect ไปหน้าอื่นๆ เป็นต้น ใน ASP.NET MVC นั้นมีคลาสลูกของ ActionResult สำหรับผลลัพธ์แบบทั่วๆไปเตรียมไว้ให้ดังนี้
- ViewResult – ผลลัพธ์เป็น HTML
- EmptyResult – ผลลัพธ์คือไม่มีผลลัพธ์(งงป่าว??)
- RedirectResult – redirect ไปที่หน้าอื่น
- JsonResult – คืนเป็น JSON
- JavaScriptResult – คืนเป็น Javascript
- ContentResult – คืนเป็นข้อความ
- FileContentResult – คืนเป็นไฟล์
- FilePathResult – คืนเป็นไฟล์ (แต่มีชื่อไฟล์ให้ด้วย)
- FileStreamResult – คืนเป็น stream ของไฟล์
สำหรับ action ที่มี return type ที่ไม่ใช่ Action Result ระบบจะทำการแปลงให้เป็น ContentResult เอง
ส่วนใหญ่แล้ว Result แบบต่างๆนั้นก็ต่างกันตรง Content-type Header นั่นแหละ การมี ActionResult แบบต่างๆก็จะทำให้การควบคุม content-type และการส่งข้อมูลง่ายขึ้นด้วย
ตอนนี้ลองสร้าง MVC Web Project ขึ้นมา จะเห็นว่าจะมี Controller ให้สอง Controller คือ Account และ Home ซึ่งเราจะลองมาเล่นกับ HomeController โดยลองแก้โค้ดของ Action About ซึ่งจากเดิมจะเรียก View() ซึ่งจะทำให้เกิด ViewResult เป็น
public DateTime About()
{
return DateTime.Now;
}
แล้วลองเปิด ~/Home/About ดู จะเห็นว่าผลลัพธ์เป็นเวลาปัจจุบัน
แล้วเกิดเราเปลี่ยนเป็นโค้ดด้านล่างล่ะ
public ActionResult About()
{
return RedirectToAction("Index");
}
ถ้าเราลองเปิด ~/Home/About ด้วย wget ดู ได้ผลดังด้านล่าง
D:\Util\usr\local\wbin>wget --verbose http://localhost:45746/Home/About
--18:25:39-- http://localhost:45746/Home/About
=> `About'
Resolving localhost... done.
Connecting to localhost[127.0.0.1]:45746... connected.
HTTP request sent, awaiting response... 302 Found
Location: / [following]
--18:25:39-- http://localhost:45746/
=> `index.html'
Connecting to localhost[127.0.0.1]:45746... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1,204 [text/html]
100%[====================================>] 1,204 83.98K/s ETA 00:00
18:25:39 (83.98 KB/s) - `index.html' saved [1204/1204]
จะเห็นว่าเกิดการ Redirect ไปที่ ~/ และในทำนองเดียวกัน เราสามารถคืนผลลัพธ์เป็น Json ได้ด้วยคำสั่ง Json() เช่นกัน
public ActionResult About()
{
return Json(new {name="wiennat", url="http://onedd.net"});
}
สรุป
Controller ใน ASP.NET MVC มีหน้าที่ควบคุม Flow การทำงานรวมไปถึงเลือก View ที่เหมาะสมเพื่อส่งผลลัพธ์ให้กับผู้ใช้ ซึ่งอาจจะไม่ใช่ HTML แต่เพียงอย่างเดียวก็ได้