ASP.NET MVC 提供了 Area
的功能,讓開發人員可以把相關的功能模組包起來,讓模組有自己的命名空間跟目錄結構。每個模組中都會有自己的 MVC 結構、路由跟模型,也可以說每個 Area
其實都可以獨立成一個自己的 MVC 專案。
在 VS 2017 中的專案上點右鍵,選擇「加入 > 區域」,再輸入 Area
名稱。
VS 就會自動產生對應的目錄結構。
MVC 應用程式在渲染 Area
中的 View 的時候,會依照以下預設的順序來尋找對應的 cshtml
檔案:
~/Areas/{AreaName}/Views/{ControllerName}/{ActionName}.cshtml
~/Areas/{AreaName}/Views/Shared/{ActionName}.cshtml
~/Views/Shared/{ActionName}.cshtml
可以透過在 Startup.ConfigureServices
中設定 Microsoft.AspNetCore.Mvc.Razor.RazorViewEngineOptions
來調整尋找 cshtml
檔案的順序跟目錄:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RazorViewEngineOptions>(options =>
{
options.AreaViewLocationFormats.Clear();
options.AreaViewLocationFormats.Add("/Categories/{2}/Views/{1}/{0}.cshtml");
options.AreaViewLocationFormats.Add("/Categories/{2}/Views/Shared/{0}.cshtml");
options.AreaViewLocationFormats.Add("/Views/Shared/{0}.cshtml");
});
}
如果有任性的讀者不想用
Area
中原本的目錄結構其實是可以的XD 除了 Views 以外的目錄都可以隨心情調整,因為:
- 只要類別名稱以 Controller 結尾或者繼承
Controller
的類別,MVC 框架都會自動辨認。.cs
檔都會編譯成dll
,執行期間不會有路徑的問題。但其實
RazorViewEngineOptions
有設定好的話好像亂放也沒關係?!
在 Area
的目錄中建立 Controller 後,需要在 Controller 加上 [Area({AreaName})]
標註,讓這個 Controller 跟 Area
建立關聯。(但之前 ASP.NET MVC 的時候不用加這個)
namespace ironman2018.Areas.Todo.Controllers
{
[Area("Todo")]
public class HomeController : Controller
{
private readonly IronmanContext _context;
public HomeController(IronmanContext context)
{
_context = context;
}
public IActionResult Index()
{
var todos = _context.Todo.ToList();
return View(todos);
}
}
}
最後在 Startup.Configure
中設定 MVC 路由時,要多註冊一組 Area
用的路由就完成啦!:
app.UseMvc(routes =>
{
// Area 用的路由
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
// 一般的預設路由
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
喔對了,如果有用 ~/Views/_ViewImports.cshtml
或 ~/Views/_ViewStart.cshtml
來做 Views 的全域設定,要記得複製一份到所有的 ~/{AreaName}/Views
底下,這樣 Area
中的 View 才能吃到這些設定,不知道以後會不會改善QQ