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