iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 27
1

ASP.NET MVC 提供了 Area 的功能,讓開發人員可以把相關的功能模組包起來,讓模組有自己的命名空間跟目錄結構。每個模組中都會有自己的 MVC 結構、路由跟模型,也可以說每個 Area 其實都可以獨立成一個自己的 MVC 專案。

建立 Area

在 VS 2017 中的專案上點右鍵,選擇「加入 > 區域」,再輸入 Area 名稱。

https://ithelp.ithome.com.tw/upload/images/20181110/20107875achJoDltM3.png

VS 就會自動產生對應的目錄結構。

https://ithelp.ithome.com.tw/upload/images/20181110/20107875iiXmmrYKxI.png

MVC 應用程式在渲染 Area 中的 View 的時候,會依照以下預設的順序來尋找對應的 cshtml 檔案:

  1. ~/Areas/{AreaName}/Views/{ControllerName}/{ActionName}.cshtml
  2. ~/Areas/{AreaName}/Views/Shared/{ActionName}.cshtml
  3. ~/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 以外的目錄都可以隨心情調整,因為:

  1. 只要類別名稱以 Controller 結尾或者繼承 Controller 的類別,MVC 框架都會自動辨認。
  2. .cs 檔都會編譯成 dll,執行期間不會有路徑的問題。

但其實 RazorViewEngineOptions 有設定好的話好像亂放也沒關係?!

Area 的目錄中建立 Controller 後,需要在 Controller 加上 [Area({AreaName})] 標註,讓這個 ControllerArea 建立關聯。(但之前 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

參考資料


上一篇
Filters 過濾器
下一篇
Unit Test 單元測試
系列文
.Net Core 網站開發 10131

尚未有邦友留言

立即登入留言