[ASP.NET] WebForm To MVC Tips - 資料明細內容
在前一篇裡我們以WebForm GridView轉到MVC List為例,說明了在最小幅度的變動情況下,讓WebForm的開發人員可以比較輕鬆的瞭解MVC,所以過程中我們並不把設計架構加進來,我們也不打算改為EF,原因如同上一篇所談的,這樣團隊的學習曲線會拉高,抗拒性會較大不是個好現象,當然如果您的團隊是可以允許打掉重練,那麼就可以考慮用學習新思維新技術。
這一篇我們要來看怎麼呈現單筆資料的明細內容,首先我們先定義這裡採用的是獨立頁面模式,也就是CRUD是各自獨立的頁面,而不是單一頁面模式,在WebForm的GridView,我們可能會採取在每一筆DataRow裡放置加入資料的唯一識別碼( 可能是Guid,可能是身份字號等等.... ),然後在連結Url裡帶入這個唯一識別碼,導向明細頁面,接著再由明細頁面重新Query資料庫取出資料,再把資料一一塞到TextBox,Label這類的控制項裡,所以程式碼可能會像是這個樣子( PS:在GridView做法有很多種,這裡提到的只是其中一種,但原理都是相似的 )。
建立一個 GridView的TemplateField , 加入HiddenField,利用HiddenField bind每筆資料的唯一識別碼,然後配置一個Button用來導向明細頁面。
<asp:GridView ID="PersonData" runat="server" AutoGenerateColumns="False" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="MiddleName" HeaderText="MiddleName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="BusinessEntityID" runat="server" Value='<%# Bind("BusinessEntityID") %>' />
<asp:Button ID="ViewButton" runat="server" Text="ViewDetail" OnClick="ViewButton_Click"></asp:Button>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
接著在Button事件中利用FindControl手法取得HiddenField的值,組合成Url參數一併傳到明細頁面,明細頁面就可以使用Request.QueryString["BusinessEntityID"] 來取得資料唯一識別碼,有了資料唯一識別碼就可以進行資料的Query了。
protected void ViewButton_Click(object sender, EventArgs e)
{
Button bt = (Button)sender;
HiddenField hf = bt.NamingContainer.FindControl("BusinessEntityID") as HiddenField;
Response.Redirect("PersonalView.aspx?BusinessEntityID=" + hf.Value);
}
我想這樣的程式碼應該不用多做解釋,寫WebForm的開發人員應該都會,接著我們直接 run 起來看一下結果。
那麼接著我們把場景轉到 MVC ,在 MVC 裡該怎麼做呢?首先看到在我們前一篇建立起來的List頁面,已經使用Html.ActionLink建立了簡單的超連結,其實它的效果是相等於自已組合html超連結,從Render後的原始碼可以明顯的看出來,在ASP.NET MVC裡提供一些HtmlHelpers來幫助開發人員建立標準HTML標籤,如果您熟HTML的話,當然您也可以選擇直接使用標準HTML的。
由Html.ActionLink的參數可以明顯看到,第一個參數是顯示在頁面的文字,第二個參數是Action名稱,而第三個參數就是我們要丟過去的東西,它是個Object型態,意謂著你可以不只是傳個字串。
所以我們就來修改一下,把資料唯一識別碼給傳過去,id對映到 action 所接收的參數名稱。
接著我們到 controller 新增一個 Details 的 action 方法,帶有一個id的傳入參數。
public ActionResult Details(int id)
{
return View(personRepository.Query(id).First());
}
回傳給 View 的 ActionResult ,我們直接叫用personRepository.Query(id).First(),personRepository用來提供資料服務的類別( 自行參考前一篇 ),Query的方法程式碼如下,採用Dapper這個輕量級的ORM直接使用ADO.NET進行SQL Command的Query。
public List<Person> Query(int id)
{
List<Person> result = new List<Person>();
using (SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["defconn"].ConnectionString))
{
var para = new
{
BusinessEntityID = id
};
result = conn.Query<Person>("select * from Person.Person where BusinessEntityID<=@BusinessEntityID", para).ToList();
}
return result;
}
完成 Controller 之後,接著就是View的部份了,新增View的方式很簡單,直接在Controller 的Action 方法名稱上按右鍵新增檢視即可,範本選擇Details,模型類別則選擇Person。
在View裡一開始宣告與哪一個Model進行綁定以及有沒有要套版面配置的宣告,接著的內容預設是以HTML dd dl dt標籤來排版,可以依照需求自行調整設計,資料內容值則是直接採用物件屬性的方式來進行繫結【@Html.DisplayFor(modelItem => item.LastName)】。
完成之後,我們實際執行看看,由index開始進入,點選Details 連結,此時url會導向Person/Details/1,Person是 Controller 名稱,Details是Action的名稱,而1則是資料唯一識別碼。
透過這樣的過程也可以為編輯頁,刪除頁增加相關頁面,與寫Webform不同的是不再是事件驅動模式,在ASP.NET MVC裡看不到控制項以及控制項事件,在觀念上要回到最原始的HTML、Form表單、URL連結的運作機制,並且以往在Webform只需一隻ASPX就可以完成一個頁面的開發模式,來到ASP.NET MVC會變成需要Controller + View + Model來配合,看似變複雜了,但實際上可以發現這樣的方式,熟悉HTML+CSS的人員可以專注在View的設計,而熟悉商業邏輯的人員則可以專注在Model的部份,甚至如果只是調整View的部份只需直接重新部署View即可,開發團隊可以依人員專長專注於某項事務上,發揮最大的戰力,相較於Webform的開發模式,整體來看ASP.NET MVC並不會比較費工,在下一篇我們要來看看如何撰寫編輯頁,刪除頁的邏輯。
By No.18