前面三章已經把MVC啓動過程以及源代碼作了講解,本章開始正式MVC,mvc全稱叫model view controller,也就是把表現層又細分三層,官網的圖片描述:html
默認建立了一個.net core web 項目,把Startup類中的代碼改爲下面這樣前端
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment environment) { if (environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvcWithDefaultRoute(); } }
咱們.net core mvc是基於約定的一種模式,例如:控制器是放在Controllers文件夾中的(固然這不是必須),視圖放在pages或者views文件夾中等,首先咱們講講Controller的約定,先無論例外的狀況,咱們要定義一個Controller首先要繼承至Microsoft.AspNetCore.Mvc.Controller類而且符合下面其中之一的條件:web
一、這個類名稱後綴是以Controller結尾編程
例如:新建一個Home類,那麼它的簽名應該像這樣:public class HomeController : Controllermvc
二、繼承至帶有Controller後綴名的基類,app
例如:你已經建立好了一個BaseController基類,如今須要建立Home類,那麼他的簽名能夠是這樣:public class Home : BaseControllervisual-studio
三、這個類帶有[Controller]標籤ui
例如:新建一個Home類,那麼它的簽名應該像這樣:url
[Controller]spa
public class Home : Controller
在Controller類裏面寫的方法,咱們稱爲Action,例以下面,這就建立了一個名爲Index的方法, 返回值類型是一個實現了IActionResult接口的實例,這裏返回的是View
public class HomeController: Controller { public IActionResult Index() { return View(); } }
在這裏先說說View()這個方法到底幹了什麼事兒吧,咱們轉到源代碼能夠看到最終View是建立了一個ViewResult這個類,這個類又繼承至ActionResult而且實現了IActionResult接口,其中最主要 ExecuteResultAsync方法就是返回給咱們前端的數據,ViewResult這個類中有兩個咱們經常使用的屬性,分別是ViewName和ViewData,分別表明"視圖的名稱"和"視圖須要的數據",若是視圖名稱不傳那麼就約定以控制器Action名稱爲準,不然已傳入名稱爲準,若是傳入ViewData那麼就能夠在視圖中的Model屬性裏面訪問到傳入的數據,而且轉換爲強類型,就以上面的例子,咱們在Views文件夾中建立一個Home文件夾和Index.cshtml視圖文件,而且在Models文件夾中建立兩個實體,一個爲通用的ViewModel,代碼以下:
public class ViewModel<T> where T : class { public string Title { get; set; } public IEnumerable<T> Data { get; set; } }
另外一個是具體的Action視圖所需的數據實體,因此名稱爲IndexModel,具體代碼以下:
public class IndexModel { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } }
另外咱們再寫一個獲取Index數據的服務,名稱爲HomeService,而且在Startup類的ConfigureServices方法中最前面加上services.AddScoped<HomeService>();
先無論是否符合設計規範,這樣作完後咱們就能夠在其餘實體中注入HomeService的實例了,咱們HomeService中代碼能夠是這樣的:
public class HomeService { private IEnumerable<IndexModel> _sourceData = new List<IndexModel> { new IndexModel { Id = 1, Description = "my is code1", Name = "test1" }, new IndexModel { Id = 2, Description = "my is code2", Name = "test2" }, new IndexModel { Id = 3, Description = "my is code3", Name = "test3" }, new IndexModel { Id = 4, Description = "my is code4", Name = "test4" }, new IndexModel { Id = 5, Description = "my is code5", Name = "test5" }, }; public ViewModel<IndexModel> GetData(int id) { return new ViewModel<IndexModel> { Title = "Index", Data = id > 0 ? _sourceData.Where(x => x.Id == id) : _sourceData }; } }
這個時候將HomeController中的代碼改爲這樣
public class HomeController: Controller { private readonly HomeService _service; public HomeController(HomeService service) { _service = service; } public IActionResult Index() { var data = _service.GetData(); return View(data); } }
而後轉到視圖文件,視圖中代碼以下:
@model ViewModel<IndexModel>; @{ ViewData["Title"] = Model.Title; } <ul> @foreach (var item in Model.Data) { <li> <span>名稱:@item.Name</span> <span>說明:@item.Description</span> <a asp-action="details" asp-route-id="@item.Id">詳細</a> </li> } </ul>
在視圖裏面有一句代碼值得注意
<a asp-action="details" asp-route-id="@item.Id">詳細</a>
這個是.net core改進部分,它叫作 TagHelpers,它是由.net core解析,最終變成正常的src屬性或者其餘html屬性,這樣作的好處是更加接近於html自己的編程方式,
這裏有注意到咱們定義的asp-action="details"表示的是轉到當前視圖的控制器details方法中,最終會生成的url path是這樣 /home/details?id={id},
爲了可以正常的運行,咱們須要建立一個details方法,代碼以下:
public IActionResult Details(int id) { var data = _service.GetData(id);
data.Title = "Details"; return View(data); }
在建立details的視圖文件,代碼以下:
@model ViewModel<IndexModel> @{ ViewData["Title"] = Model.Title; var data = Model.Data.FirstOrDefault(); } <p>@data.Name,@data.Description,@data.Id</p>
而後咱們運行程序,會看到以下界面:
點擊"詳細" 會出現如下界面:
好啦,mvc大體狀況就介紹到這裏,後面會詳細說說Views這個文件夾中的一些規則以及,有興趣的也能夠去官網看看https://docs.microsoft.com/zh-cn/aspnet/core/razor-pages/?view=aspnetcore-2.2&tabs=visual-studio