精進 ASP.NET MVC 開發技術,打造高生產力與易於維護的系統 (Develop ASP.NET MVC Better)
2020-09-15
本次的筆記是從 LinkedIn Learing 課程中,反芻學習內容整理而成,深信只有動手輸出,才能夠將知識真正納為己有 😉
目錄
Customizing routes with attribute routing
在 RouteConfig.cs 加入 routes.MapMvcAttributeRoutes
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
即可在 Controller Action 藉由 Route Attribute 自定義路由,使用 Url.Action 的 Url 會自動配合使用新的 Route ,十分方便。
Controller.cs
[RoutePrefix("Home")]
public class HomeController : Controller
{
[Route("~/About")] // /About/
[Route] // /Home/
[Route("~/")] // /
[Route("Information")] // /Home/Information/
[Route("Info/About")] // /Home/Info/About
public ActionResult About()
{
return View();
}
[Route("Application")] // /Home/Contact -> /Home/Application/
public ActionResult Contact()
{
return View();
}
}
Route Constraint 可以進一步的限制參數條件來決定使用不同的 Action 處理。
Controller.cs
[Route(@"~/Route/{str:regex(^\d{6})}")]
public ActionResult ProcessDigits(string str)
{
return Content($"<h1>It's Digit</h1><p>{str}</p>");
}
[Route(@"~/Route/{str:regex(^[a-zA-Z]\d{0,8})}")]
public ActionResult ProcessAlphaDigits(string str)
{
return Content($"<h1>It's Alpha Digit String</h1><p>{str}</p>");
}
Reuse View with AjaxRequest
共用 Controller Action 及 View,利用 IsAjaxRequest 區別呼叫是否來自於 Ajax,如果是以 Partial View 方式回傳,避免多餘的 head, body 標籤。
Custom Html Helper To reuse code
重複使用 Razor Html Code 的三種方式:
- Razor Helper
- Razor Function
- Html Helper Extension
Razor Helper
/cshtml
@helper ROCCalendarTrans(int commonEra)
{
<text>@(commonEra - 1911)</text>
}
@ROCCalendarTrans(DateTime.Now.Year)
@helper AMPM(DateTime datetime)
{
if (datetime.Hour < 12)
{
<text>AM🌞</text>
}
else
{
<text>PM🌙</text>
}
}
@AMPM(DateTime.Now)
Razor Function
/cshtml
@functions
{
public int func(string str)
{
return 42;
}
}
@func("params")
不論是 Razor Helper 或者 Function 都可以將程式碼存在 App_Code 讓 View 共用,引用的方式配合調整為檔案名稱即可。例如 App_Code/RazorHelper.cshtml 下則調整為 @RazorHelper.HelperName 😎
Html Helper Extension
/App_Code/HtmlHelperExteinsions.cs
namespace System.Web.Mvc
{
public static MvcHtmlString ExtensionExamples(this HtmlHelper helper, object htmlAttributes = null)
{
var ele = new TagBuilder("div")
{
InnerHtml = "<p>Lorem Ipsum</p>"
};
ele.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
return new MvcHtmlString(ele.ToString());
}
}
GitHub - Nancy.ViewEngines.Razor.HtmlHelpers
目前範例寫得還不理想,主要是要用 TagBuilder 客製化可以重用的 Html Code,待實際情境再補充這部分的內容 🤔
Less Responsibility On View, More Responsibility For ViewModel
View 中複雜的邏輯抽取為 ViewModel 的方法。
- 不要懼怕創造新的類別(Viewmodel),為了區別輸入物件與呈現物件,使用不同的類別是可以被接受的
- 類別共有屬性,藉由 Controller 做 Adapter 轉換兩者
- Viewmodel 中可以將原本 View 的 logic 抽取出
Seperation Concerntion of Controller & Model (Abstract Service Level)
將 Controller 中龐雜的邏輯抽取為 Business Folder 下的 Service.cs
AutoFac Dependency Injection
ELMAH - Log & Monitor
The Error Logging Modules And Handlers
Nuget Install :
Install-Package elmah
Install-Package elmah.xml
Install-Package elmah.mvc
預設情況下,ELMAH 會將錯誤存在 Ram 中,安裝完成 elmah.xml packages 後,則會將資料存在 ~\App_Data\Elmah.Errors
下以 XML file 的方式保存。每一個 XML file 代表一個 錯誤。
使用 ELMAH 要特別注意存取的安全性,因為錯誤訊息的資料如果被惡意存取,將會被利用於攻擊所使用。
同時 ELMAH 可以將資料改存在資料庫,另外可以設定電子郵件通報以及區別事件的等級來決定是否通報。