ทส215 การเขียนโปรแกรมบนเว็บ 1 ทส215 การเขียนโปรแกรมบนเว็บ 1 ASP.NET MVC Framework อาจารย์อรรถวิท ชังคมานนท์ สาขาวิชาเทคโนโลยีสารสนเทศ คณะวิทยาศาสตร์ www.itsci.mju.ac.th
MVC สิ่งหนึ่งในรูปแบบเหล่านี้คือ โมเดล วิว คอนโทรลเลอร์ (Model View Controller หรือ MVC) กำเนิดขึ้นในภาษาสมอลทอล์ค (Smalltalk) ในวิธีนี้ระบบจะถูกแบ่งออกเป็น 3 คอมโพเนนต์ ประกอบด้วย โมเดล (Model) วิว (View) คอนโทรลเลอร์ (Controller) MVC แสดงให้เห็นประโยชน์ของมันในการโต้ตอบกับผู้ใช้ด้วยการแสดงผลที่หน้าจอหลากหลายของข้อมูลเดียวกัน สนับสนุนการนำรหัสต้นฉบับ (Source code) มาใช้ใหม่และช่วยให้นักพัฒนามุ่งสนใจกับหน้าตาแอพพลิเคชัน(วิว) เดียว โดยไม่สนหน้าตาแอพพลิเคชันส่วนอื่น เพราะแต่ละส่วนได้นำข้อมูลของส่วนกลางมาแสดงผล ข้อมูลไม่ได้ขึ้นกับหน้าตาแอพพลิเคชันใด การเปลี่ยนแปลงส่วนใดส่วนหนึ่งของคอมโพเนนต์จะไม่ส่งผลกระทบต่อคอมโพเนนต์อื่นตามไปด้วย
Model "Models" คือส่วนของ components ในระบบมีหน้าที่สำหรับจัดการส่วนของ Object State (Data + Value) เป็น Class ที่ออกแบบมาเพื่อ get/set Attribute ซึ่งส่วนใหญ่จะใช้งานประยุกต์ร่วมกับข้อมูลปกติที่จัดเก็บใน database แล้วส่งต่อไปยังส่วนของ View เพื่อกำหนด Format ของการแสดงผลต่อไป สามารถใช้งานร่วมกับส่วนของ View หลายหน้าจอได้โดยไม่ต้องเปลี่ยนแปลง code ใดๆ จึงทำให้สะดวกในการตรวจสอบ reusable หากกรณีที่ข้อมูลที่ได้รับมาไม่ถูกต้องก็ให้ทำการตรวจสอบระบบที่ส่วนของ Controller ซึ่งเป็นส่วนที่มีการคำนวณประมวลผลแล้วส่งผลลัพธ์ไว้ที่ Model
View “Views" คือส่วนของ components ในระบบมีหน้าที่สำหรับจัดการส่วนของการแสดงผลแก่ผู้ใช้งาน(User Interface) MVC model สามารถมีส่วนของการแสดงผลได้หลายประเภทเช่น WEB-FORMS, HTML, XML/XSLT, XTML, and WML or can be Windows forms etc. View สามารถแสดงผลในแบบที่เป็น Graphical data presentation ได้เพื่อความน่าเชื่อถือของข้อมูล look and feel, formatting, sorting etc. การทำงานของ View จะแยกออกจากการประมวลผลข้อมูลที่ซับซ้อน เช่นระบบของการซื้อขายสินค้า Online product catalog การทำงานส่วนของ view จะทำหน้าที่เพียงรับข้อมูลจาก Model มาจัดรูปแบบให้ถูกต้องและสวยงามแล้วแสดงผลทางหน้าจอแก่ผู้ใช้งานระบบต่อไป ซึ่งจะไม่เกี่ยวของกับการ database connection, query, tables etc.
Controller "Controllers" คือส่วนของ components ในระบบมีหน้าที่สำหรับจัดการส่วนของการประมวลผลคำสั่งการทำงานต่างๆ แล้วส่งผลลัพธ์ในรูปแบบของ model จากนั้นจะส่งต่อไปยังview. Handles and Responds to user input and interaction. = Method
ประโยชน์อย่างหนึ่งของการออกแบบระบบแบบ MVC methodology คือช่วยแบ่งแยกการทำงานเป็นส่วนๆ อย่างชัดเจน ซึ่งจะทำให้การปรับปรุงตรวจสอบ แก้ไขระบบเป็นไปได้ง่ายยิ่งขึ้น MVC pattern ยังมีส่วนช่วยในการทดสอบระบบ แบบ Red/Green Test Driven Development (TDD)
MVC Structure
Activity
MVC Sequence Diagram
Benefits Since MVC handles the multiple views using the same enterprise model it is easier to maintain, test and upgrade the multiple system. It will be easier to add new clients just by adding their views and controllers. Since the Model is completely decoupled from view it allows lot of flexibilities to design and implement the model considering reusability and modularity. This model also can be extended for further distributed application. It is possible to have development process in parallel for model, view and controller. This makes the application extensible and scalable.
Drawbacks Requires high skilled experienced professionals who can identify the requirements in depth at the front before actual design. It requires the significant amount of time to analyze and design. This design approach is not suitable for smaller applications. It Overkills the small applications.
Sample Code : XML Business Entity
ASPX protected MVCDesignCSharp.XMLData.Orders ordersDataSet; private void Button1_Click(object sender, System.EventArgs e){ BizOrderManager.GetOrderList(ordersDataSet); if(DataGrid1.Visible==false){ DataList1.Visible =false; DataGrid1.Visible =true; DataGrid1.DataBind(); Button1.Text="Show View 1"; }else { DataList1.Visible =true; DataGrid1.Visible =false; DataList1.DataBind(); Button1.Text="Show View 2"; } private void Button2_Click(object sender, System.EventArgs e){ Button1.Text="Show Only View 2";
Business Objects public static void GetOrderList(DataSet OrderDS){ OrderDS.ReadXml(AppDomain.CurrentDomain.BaseDirectory + "/XMLData/Orders.xml"); }
Sample Code
Site Structure
Database Table: Photos
Photos.aspx <p>The following files were found in your <b>Upload</b> folder. Click on <b>Import</b> to import these pictures to your photo album. This operation may take a few moments.</p> <asp:ImageButton ID="ImageButton1" Runat="server" onclick="Button1_Click" SkinID="import" /> View
Photos.aspx.cs Controller protected void Button1_Click(object sender, ImageClickEventArgs e) { DirectoryInfo d = new DirectoryInfo(Server.MapPath("~/Upload")); foreach (FileInfo f in d.GetFiles("*.jpg")) { byte[] buffer = new byte[f.OpenRead().Length]; f.OpenRead().Read(buffer, 0, (int)f.OpenRead().Length); PhotoManager.AddPhoto(Convert.ToInt32( Request.QueryString["AlbumID"]), f.Name, buffer); } GridView1.DataBind(); Controller
PhotoManager.cs Controller
PhotoManager.cs Controller public static void AddPhoto(int AlbumID, string Caption, byte[] BytesOriginal) { using (SqlConnection connection = new SqlConnection( ConfigurationManager.ConnectionStrings["Personal"].ConnectionString)) { using (SqlCommand command = new SqlCommand("AddPhoto", connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@AlbumID", AlbumID)); command.Parameters.Add(new SqlParameter("@Caption", Caption)); command.Parameters.Add(new SqlParameter("@BytesOriginal", BytesOriginal)); command.Parameters.Add(new SqlParameter("@BytesFull", ResizeImageFile(BytesOriginal, 600))); command.Parameters.Add(new SqlParameter("@BytesPoster", ResizeImageFile(BytesOriginal, 198))); command.Parameters.Add(new SqlParameter("@BytesThumb", ResizeImageFile(BytesOriginal, 100))); connection.Open(); command.ExecuteNonQuery(); } Controller
Photos.aspx View <asp:FormView ID="FormView1" Runat="server" DataSourceID="ObjectDataSource1" DefaultMode="insert“ BorderWidth="0px" CellPadding="0" OnItemInserting="FormView1_ItemInserting"> <InsertItemTemplate> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" Runat="server" ErrorMessage="You must choose a caption." ControlToValidate="PhotoFile" Display="Dynamic" Enabled="false" /> <p>Photo<br /> <asp:FileUpload ID="PhotoFile" Runat="server" FileBytes='<%# Bind("BytesOriginal") %>' /><br /> Caption<br /> <asp:TextBox ID="PhotoCaption" Runat="server" Text='<%# Bind("Caption") %>' /></p> <asp:ImageButton ID="AddNewPhotoButton" Runat="server“ CommandName="Insert" skinid="add"/> </InsertItemTemplate> </asp:FormView> View
Photos.aspx <asp:ObjectDataSource ID="ObjectDataSource1" Runat="server“ TypeName="PhotoManager" SelectMethod="GetPhotos" InsertMethod="AddPhoto" DeleteMethod="RemovePhoto" UpdateMethod="EditPhoto" > <SelectParameters> <asp:QueryStringParameter Name="AlbumID" Type="Int32" QueryStringField="AlbumID" /> </SelectParameters> <InsertParameters> </InsertParameters> </asp:ObjectDataSource> Call Controller “PhotoManager” Mapping Method of “PhotoManager” View
Photo.cs Model public class Photo { private int _id; private int _albumid; private string _caption; public int PhotoID { get { return _id; } } public int AlbumID { get { return _albumid; } } public string Caption { get { return _caption; } } public Photo(int id, int albumid, string caption) { _id = id; _albumid = albumid; _caption = caption; } Model
Controller with Model public static List<Photo> GetPhotos(int AlbumID) { using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Personal"].ConnectionString)) { using (SqlCommand command = new SqlCommand("GetPhotos", connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@AlbumID", AlbumID)); bool filter = !(HttpContext.Current.User.IsInRole("Friends") || HttpContext.Current.User.IsInRole("Administrators")); command.Parameters.Add(new SqlParameter("@IsPublic", filter)); connection.Open(); List<Photo> list = new List<Photo>(); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Photo temp = new Photo( (int)reader["PhotoID"], (int)reader["AlbumID"], (string)reader["Caption"]); list.Add(temp); } return list;
Q&A