More

    C#, ASP.NET, ASP.CORE

    資料驗證 – 實作篇 (.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...

    傳遞資訊到前端的通用型服務 (.NET MVC 5 – Ch.11)

    到目前為止,已經介紹了很多屬於基礎建設的部份。從核心的DI用Autofac開始,再到那裡都使用的到的Log服務。再來介紹了ViewModel和如何透過框架來讓對應變得更加簡單。最後介紹了透過Repository 和 Unit of work,使得實際的DAL層級能夠被abstraction出來。 在這一篇,將會介紹比較偏向Controller層級的內容,也就是每一個application一定會使用到的:如何提供一種一致性的服務用於從Server傳遞訊息到客戶端? 同步發表於我的部落格:http://alantsai2007.blogspot.tw/2014/10/BuildYourOwnApplicationFrameworkOnMvc-11-alertservice.html 如何從後端傳遞訊息到前端 所謂傳遞訊息到前端的意思是,通常來說每當一個功能執行完成之後,一定會提供一些feedback給user。例如,新增一筆資料成功,系統可能會用一個alert訊息來顯示「新增成功」。 因為這個功能非常通用,因此Mvc裡面有一個特殊的儲存空間叫做TempData。有別於ViewData只能保存一次的request值到View裡面,TempData 底層也是用Session來儲存,但是有別於Session在,當TempData的值被讀過,那一筆資料就會被清掉。 因此,TempData非常適合用來存這一種一次性的feedback訊息,顯示完之後就不需要了。 使用TempData的難處 TempData很適合存一次性資訊,但是實際在開發的時候不是那麼方便。在一個多人團隊開發的情況可能有以下幾個情況: 在沒有講好的情況下,每個人使用的TempDataKey不一樣:開發者A可能使用message作為key,但是開發者B可能使用messages。要設定錯誤訊息的時候不方便:Action裡面設定TempData其實不是很好用。 因此這一次我們會建制一個AlertService來提供一個好用的傳遞訊息的方式。 AlertService功能概念 基本上我們會先建立一個用來封轉要顯示在前端的訊息ViewModel。這個ViewModel只有兩個Property,一個是Message:代表要顯示的訊息,還有一個是 AlertClass:也就是這個訊息要顯示的樣式。 為了能夠讓設定要傳遞的訊息更加簡單,將會建立一個AlertDecoratorActionResult,這個特別的ActionResult只是讓設定訊息更加的方便。同時,為了讓使用這個...

    加上 Unit of Work,抽離Entity Framework的依賴就完美了 (.NET MVC 5 Ch.10)

    在上一篇介紹完了Repository Pattern,我們能夠抽離實際在做儲存的動作,讓我們在替換實際儲存動作更加容易。 但是光靠一個Repository Pattern其實還是有些缺陷,因此,通常來說會實作Unit of Work pattern搭配Repository pattern達到一個比較完美的狀態。 同步發表於我的部落格:http://alantsai2007.blogspot.tw/2014/10/BuildYourOwnApplicationFrameworkOnMvc-10-UnitOfWork.html Repository...

    用 Repository Pattern 抽離對 Entity Framework 的依賴 (.NET MVC 5 Ch.9)

    在上一篇介紹完了如何讓ViewModel和Entity之間的轉換透過AutoMapper變的更簡單,然後透過框架讓設定ViewModel和Entity之間的對應關係變的容易。 在這一篇,將會看Data Access Layer (DAL)的部份,也就是儲存資料層的部份。 同步發表於我的部落格:http://alantsai2007.blogspot.tw/2014/10/BuildYourOwnApplicationFrameworkOnMvc-09-RepositoryPattern.html Data Acce Layer (DAL) 不管任何大小的軟體,通常都會需要儲存資料。而這個儲存資料最常見的就是儲存到資料庫裡面。以Asp...

    Recent Articles

    Stay on op - Ge the daily news in your inbox

    spot_img