More

    Programming

    搜索頁面 – ViewModel的定義 (.NET MVC 5 Ch-21)

    在上一篇介紹完了搜索功能的概念和思路之後,在這一篇開始要看實作的部份。 通常寫Mvc都是從Model開始,因此這一篇將來看一下搜索功能所會使用到的ViewModel 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-21-IndexPage-ViewModel.html ViewModel的內容 首先,搜索的ViewModel必然會有兩個Property: 搜索條件搜索結果 因此,我們會先從這兩個部份的Property來看起。 搜索條件的ViewModel 搜索條件會有一定有的欄位和各個domain所需要的欄位,因此會先定義一個Base,好方便之後domain來繼承並且提供其他相關欄位。 一定會有的欄位像是: 每頁筆數目前頁數排序欄位排序順序 Domain相關的欄位就依照各自的需求,例如假設是一篇文章,可能會有以「標題」做搜索或者以「內文」做搜索。 因此,程式碼會如下: /// <summary> /// 搜索 Form 的 ViewModel base。定義搜索必須要有的相關欄位。 ///...

    搜索頁面 – 思考篇 (.NET MVC 5 Ch-20)

    搜索頁面無疑是任何系統必須要有的功能,同時要做出搜索頁面需要很多不同的地方:需要注意搜索條件,分頁的處理和結果的呈現。 這些處理其實如果沒有統一的做法,會很容易造成每個人用不同的方式做處理,因此這一篇將來介紹,如何透過框架被處理變的更加簡單。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-20-IndexPage-concept.html 一般搜索頁面所會需要處理的內容 搜索頁面基本上就是所謂的Index頁面。這種頁面通常會有3個部份的內容: 搜索條件 - 通常應該會有一個搜索條件,讓使用者可以過濾資料的顯示搜索結果 - 依照搜索條件,去產生對應的結果做呈現和顯示分頁處理 - 通常會針對結果做分頁處理,例如如果有100筆,可能只希望一次呈現20筆,那麼就會有5頁。這些資訊的處理其實並沒有想像中的容易。 針對上面提到的3個部份的內容,其實都有一些底層的內容去處理,而這些如果沒有做好,很多時候都是在runtime的時候才會出錯,而不是...

    框架產生下拉式資料的內容 (.NET MVC 5 Ch-19)

    這一篇,回到Controller常常需要做的一件事情,那就是當如果欄位屬於下拉式選單的時候,需要準備好下拉式清單的資料。 如果用的是預設的方式去產生下拉式選單其實有很多問題,這一篇想透過框架的方式,讓產生下拉式清單的資料能夠自動化。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-19-GenerateSelectListFroDropDownList.html 預設Scaffolding的問題 如果是Mvc Scaffolding內建的話,會在Controller的時候產生下拉式清單資料並且塞到ViewBag裡面。 這個最大的問題是:假設某一個地方有需要下拉式選單的資料,但是忘記產生了(最長發生這個問題是在Edit的時候,驗證失敗需要重新顯示View的時候),畫面就會炸掉。 而且這個只有在runtime的時候才會發生,完全沒有辦法在compile的時候檢測出來。 假設有東西能夠保證需要下拉式清單的資料的時候,一定會產生出來,就不需要擔心到底有沒有忘記呼叫要把資料塞到ViewBag裡面。 這就是我們框架要解決的問題。 解決思路 首先,需要下拉式清單的資料的時候,就需要產生出來。能夠確認每一次需要的時候就會產生,就要透過Filter來做。 如 果透過Filter來處理產生的邏輯,那麼還需要準備資料給Filter,讓它產生對應的資料並且塞到ViewBag裡面。因此,ViewModel是最 適合的,因為在Filter裡面可以取得ViewModel的內容,因此可以做一個特殊的欄位,專門存放這些準備資料。 最後,在顯示的部份,就可以用一般的HtmlHelper產生即可。 實作內容 接下來就看看如何實作。 SelectListViewModel的定義 首先,定義一個SelectListViewModel的Class,這個Class將代表需要產生的下拉式選單: /// <summary> /// 代表一個要被產生的SelectList /// </summary> public...

    資料驗證 – 實作篇 (.NET MVC 5 Ch-18)

    在上一篇介紹了資料驗證的三個時機,在這一篇將會實作上一篇的內容。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-18-DataValidation-implement.html 基本流程 首先,需要定義出一個能夠用來裝錯誤訊息的資料載體。這個Class的用處只是方便我們在3段不同地方做驗證的時候,可以儲存錯誤訊息,並且在3層互相傳遞。 再來,會定一個Wrapper,把錯誤訊息包起來,並且提供一個方法回傳,驗證是否成功。 最後,在Controller那邊的驗證(ModelStateDictionary)和Repository儲存(如果驗證失敗會丟出exception)出現錯誤訊息的時候,把這些放在Wrapper 裡面,方便統一顯示資料驗證。 需要新增的Class和interface 首先先介紹會增加的interface和Class,然後才介紹如何實際做到Freamwork裡面。 定義裝載錯誤訊息的載體 基本上定義一個interface(IBaseError)代表一個錯誤訊息會有的欄位。基本上這個interface有兩個property,一個是儲存錯誤訊息的資訊,另外一個是儲存這個錯誤訊息對應到的Property。 因為,不是所有錯誤訊息都會有對應的欄位,因此,會用兩種實作,一個是PropertyError,代表這個錯誤訊息和Property有關聯(例如某一個欄位是必填欄位,那沒就是屬於這種類型的錯誤哦訊息)。 另外一種實作則是通用型錯誤訊息叫做GeneralError。這種錯誤是不會和某一個欄位有關的,因此只會有錯誤訊息的值,而不會有property欄位。 如果用Class Diagram表示就是: 裝在錯誤訊息的Class 接住Repository層的驗證錯誤邏輯 在Repository層如果驗證錯誤的話,Entity Framework會丟出一個Exception。 因此,為了處理這個部份,將會定義一個自訂的Exception,可以幫忙把Entity Framework的錯誤訊息包住成為IBaseError。 Class Diagram的樣子會是: Entity Framework驗證錯誤Exception包住的客制Exception 驗證的Dictionary 在Mvc裡面,ModelStateDictionary會存放錯誤訊息,並且透過HtmlHelper很方便的能夠把裡面錯誤訊息顯示出來。 但是為了避免和ModelStateDictionary綁死,因此會定義一個interface,提供需要的方法,然後在做一個ModelStateDictionary...

    資料驗證 – 思路篇 (.NET MVC 5 Ch-17)

    在任意的Application裡面,都一定需要儲存資料。而這些資料的正確性是非常重要。舉例來說,以一篇部落格文章來說,這篇文章一定要有“標題”和“作者”,如果沒有這兩個 資訊,這篇部落格文章更本就不算是文章。因此,確認進入資料庫的內容的資料是否正確(或者說符合領域裡面的規則),這就是資料正確性。 在Mvc裡面,有一個非常好的基本資料驗證服務,也就是用DataAnnotation定下欄位基本規則,讓Mvc在Model Binding的時候就會做基本的資料驗證。 但是那個只是單一的資料驗證,邏輯性的資料驗證呢?例如,需要和另外一個資料庫欄位做比對。這個光靠DataAnnotation是不夠的,只能夠在service層級來做這方面的資料 驗證。 在來,當資料要實際儲存的時候Entity Framework這邊也會有實際DB欄位的資訊,有時候會和DataAnnotation設定的不一樣,導致儲存的時候炸掉。 上面提到3個層面,其實並沒有一個統一整合的東西把它們包在一起,導致在開發專案的時候,每一個人處理這三個層面的方式都不一樣。 因此,接下來要看的是,框架如何把這些驗證的地方整合在一起。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-17-DataValidation-concept.html 3個層面的驗證 雖然在開篇提到了關於3個層面的驗證,這裡用一張圖更好的解釋三個層面的驗證和不同之處: Mvc 3 個層面的資料驗證 基本上,3個層面驗證的東西都不同: Controller...

    處理檔案上傳 2 – 放到Service層 (.NET MVC 5 Ch-16)

    在上一篇,介紹了如何處理檔案上傳的部分。但是,裡面處理上傳檔案的邏輯是放在Mvc的Action裡面。 這個有一些壞處,首先,和邏輯相關的不應該寫在Controller裡面,因為Controller的工作很簡單,就只是決定Model的資料,和顯示的View是哪一個。把處理這種邏輯放在Controller裡面破會了所謂的關注點分離(SoC)的概念。 再來屬於SoC的衍生,因為如果邏輯寫在了Controller裡面,未來如果要替換邏輯或者需要做一些測試的時候,更本不好做。加上,如果別的地方也需要同樣邏輯的時候,更本沒有辦法通用。 因此,這一篇將會介紹如何把邏輯抽到Service層裡面。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-16-FileProcess-InService.html 功能概述 基 本的邏輯在上一篇實作了在Controller裡面,現在要抽到Service裡面,尤其是通用型的Service(也就是 GenericService<T>),就要以能夠動態的角度去思考如何處理這部分的邏輯,因此,定下一些規則。如果進來的 ViewModel符合這些規則,就處理,要不然就不處理。 檔案處理的邏輯如果在仔細思考一下,基本上就是: 把HttpPostedFileBase檔案儲存 (在有檔案的情況下)把儲存檔案的路徑放到要儲存到DB的欄位 如果要把上面的邏輯自動化的話,就變成: 找到這個ViewModel裡面是不是有HttpPostedFileBase - 並且裡面有檔案把檔案儲存把路勁給要存到DB的欄位即可...

    處理檔案上傳 (.NET MVC 5 Ch-15)

    在網站裡面,通常都會需要讓使用者上傳檔案,好方便前臺或者別的顯示這個資訊的地方來下載這個對應的檔案。 在Mvc裡面,有所謂的HttpPostedFileBase可以方便我們接到前端input是file的檔案。這個檔案通常會被存到Server的某一個位置之後,路勁才會儲存到DB 裡面,下次顯示的時候顯示的是這個檔案的路徑。 處理HttpPostedFileBase的邏輯其實還滿常見,如果框架能夠把這一部份也處理掉的話,又可以減少我們煩惱這些細節的部份,提升開發效率。 這一篇我們將來看一下如何做到。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-15-FileProcess.html 整體功能概念 我們的Entity欄位通常會是string的形態,用來儲存這個上傳檔案的相對路徑。而檔案上傳方便做model binding是HttpPosedFileBase這個形態,因此我們將會在ViewModel增加一個對應的property用來接使用者所選取的檔案。 我們的邏輯處理規則是需要: HttpPostedFileBase的檔案存到特定的位置。把儲存的檔案相對的路徑存入到正確的欄位裡面。 功能實作 有了上面整體的概念之後,將會開始實作。 欄位說明 假設我們現在的Post需要有一個欄位用來儲存這篇文章的代表圖,因此我們會多一個欄位叫做CoverImg(在ViewModel),同樣對應到DB的Table欄位也是 CoverImg。 我們會在多一個欄位叫做CoverImgFile在ViewModel,這個欄位的主要目的是對應到View裡面的HttpPostedFileBase 因此目前Post的定義會是(標亮是新增的兩個欄位): public partial class Create { ...

    把目前的CRUD功能抽到Service層 (.NET MVC 5 Ch-14)

    在上一篇介紹完了什麼是Service層,和為什麼要使用Service層。在這一篇,將會把CRUD裡面的方法先抽到Service層裡面,因此Controller不在直接和Data Access Layer溝通,而是透過Service層來和Data Access Layer溝通。 在定義Service功能的時候,將會使用泛型的方式讓程式碼能夠通用,然後各自在繼承通用型的方法來提供個別功能的客制。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-14-service-basicCRUD.html IService<T>的定義 在定義實作之前,先來定義好相對應的功能有什麼。 /// <summary> /// Service服務層內容的Interface ///...

    Service層 – 概念篇 (.NET MVC 5 Ch-13)

    在這一篇將會看所謂的Service層。爲什麽需要Service層?並且Service層包含了什麽東西,並且在使用上,會給我們帶來什麽便利。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-13-service-intro.htm 什麽是Service層? 這邊提到的層就是英語所謂的Layer。而Layer就是logical separation of set of functionality (邏輯性的切割一組功能)。舉例來說,和儲存有關的功能就屬於Data...

    BaseController 的重要性 (.NET MVC 5 Ch.12)

    在這一篇將會介紹為什麼對框架來說有一個BaseController讓所有的Controller來繼承很重要,並且介紹一個簡單的強型別的RedirectToAction讓所有繼承這個BaseController的可以來使用。 透過這個強型別的RedirectToAction讓在寫Code的時候,不要犯下寫錯Action的名字,或者Action名字改了但是對應的RedirectToAction沒有改到的低級錯誤。 為什麼要自定自己的BaseController 所有的Controller都會繼承System.Web.Mvc.Controller。繼承的概念在OO裡面很重要,因為可以讓一些所有Controller都通用的功能,透過繼承來傳下去。同時,一些特殊的Attribute如果放在Controller的層級,那麼所有的ActionResult都會有效果,因此針對我們的框架,就會定義一個框架的BaseController來讓所有的Controller繼承,以提供一些通用的方法。 同步發表於我的部落格:http://alantsai2007.blogspot.com/2014/10/BuildYourOwnApplicationFrameworkOnMvc-12-importantofbasecontroller.html 強型別的RedirectToAction 定義一個BaseController非常的簡單,只需要定一個class然後讓他繼承System.Web.Mvc.Controller,之後我們實際要使用的Controller在繼承這個BaseController 就可以了。 /// <summary> /// Application 層級的BaseController /// </summary> public class...

    Recent Articles

    Stay on op - Ge the daily news in your inbox

    spot_img