前面三章已经把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