基于微软的ASP.NET Core教程(参考文献1),学习并以MVC方式实现电影数据的增删改查、搜索、验证等功能。本文主要实现其中的浏览及查看明细功能。
首先创建MVC项目。在VSCode的终端中输入以下命令创建项目:
//创建项目
dotnet new mvc -o TestMVCMySql
//加载项目
code -r TestMVCMySql
之前的项目中已经创建了电影数据库,同时在数据库中录入了测试数据,本项目直接连接并处理该数据库即可。在项目中添加如下程序集的引用。
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools
MySql.EntityFrameworkCore
MVC项目自动创建了Models、Views和Controllers文件夹,MVC模式对应的模型、视图和控制器文件即放在这三个文件夹中,其中模型文件夹主要存放系统中使用的数据类,控制器文件夹中主要存放与页面交互的处理类,而视图文件夹主要存放与控制器类中的公开函数对应的视图模板文件。一般来讲,Controllers文件夹下每个继承了Controller的控制器类都对应着Views文件夹下的一个子文件夹(子文件夹名称为控制类名中在Controller 之前的部分,例如控制器名为HomeController,则在Views文件夹下会有一个名为Home的子文件夹);Views文件夹中控制器类对应的子文件夹下的一个页面都对应着控制器类中的公开函数(页面名称为控制器类中的公开函数名称,如Home文件夹下的Index.chtml页面对应着HomeController类中的Index函数)。
路由是ASP.NET Core MVC项目的重要概念之一,根据目前学习的内容来看,其作用主要是将对页面的请求定位到某个控制器类的特定公开函数中,并传递函数需要的参数。普通的ASP.NET Core 项目,每个Razor页面都对应有相应的处理类,如下图所示,处理类中会响应页面中的OnGet等事件。而在MVC项目中则需要通过路由定位处理页面交互请求的操作函数。微软帮助文档中对MVC模式的介绍:“此模式有助于实现关注点分离:UI 逻辑位于视图中。 输入逻辑位于控制器中。 业务逻辑位于模型中。 这种隔离有助于控制构建应用时的复杂程度,因为它可用于一次处理一个实现特性,而不影响其他特性的代码‘’。
MVC项目的Startup文件中,在Configure函数中设置路由格式,代码如下所示:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
上述代码将网址格式分为了4段:第一段是服务器地址和端口,这段内容在代码中没有体现,不过访问同一网站时该段内容都相同;第二段是控制器,也即代码中的controller值,通过这段内容可以定位到项目中具体的控制器类(第二段内容加上Controller后缀即可);第三段是操作,也即代码中的action,通过这段内容可以定位到控制器中的具体函数(一般来说与函数名称相同,不过也有例外);第四段是路由数据,也即代码中的{id?},个人理解是传递给函数的参数值。代码中同时设置了controller和action的默认值,也即如果用户只输入服务器地址和端口时访问的地址,默认controller为Home,action为Index,如下图所示,在浏览器地址栏中输入https://localhost:5001/和https://localhost:5001/home/index,得到的页面是相同的。
接下来实现浏览及查看明细功能。首先定义模型及数据库连接类,这里偷一下懒,直接将之前项目中的电影类及数据库连接类复制到Models文件夹下,修改文件中的命名空间即可。然后在StartUp的ConfigureServices中注册数据类连接类即可。
项目创建后,会在controller文件夹下默认创建HomeController控制类,将其更名为MovieController(同时要更改StartUp文件中Configure函数内的默认路由),然后将MovieController类中的构造函数参数由日志服务改为数据类连接类,同时创建Index和Details公开函数,其中Index函数返回数据库中的所有数据,Details函数返回指定id的电影数据。程序主要代码如下:
public class MovieController : Controller
{
private readonly RazorPagesMovieContext _context;
public MovieController(RazorPagesMovieContext context)
{
_context = context;
}
public IActionResult Index()
{
var result=_context.Movies;
return View(result.ToArray());
}
public IActionResult Details(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = _context.Movies.Find(id);
if (movie == null)
{
return NotFound();
}
return View(movie);
}
}
在项目的Views/Movie文件夹下创建Index和Details页面,本文直接从之前的项目中复制了这两个页面。复制过来之后,需要把页面开头的@page去掉,同时将页面中的跳转页面都修改为符合MVC项目要求的形式。Razor页面中的跳转,直接用asp-page和asp-route-id指定了要跳转的页面及参数,而在MVC项目中,需要使用asp-controller、asp-action和asp-route-id等定位点标记进行定位。
同时,从控制类向页面传递参数的方式也有变化,在Razor页面中,通常是在页面对应的cs文件中定义公开属性,然后在页面开头处用@model定义要使用的属性。而在MVC项目中,由上面的示意代码可以看出,如果函数返回的是View(XXX)的形式,则项目基于视图文件中与函数名对应的页面文件模板生成响应内容,页面需要的数据以参数的形式传入。
程序运行后的截图如下所示:
本文主要实现了基于MVC的电影数据的浏览及查看明细功能,这两类功能主要是控制类响应页面的Get请求,后续还会继续学习ASP.NET Core MVC帮助文档,实现对数据的增、删、改的功能。
通过学习微软的ASP.NET Core文档及示例代码,同时对比之前学的Razor页面项目,形成了本文档。初学乍到,可能对ASP.NET Core 的内容理解有偏僻,不妥之处可以相互交流。
参考文献:
[1]https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-mvc-app/start-mvc?view=aspnetcore-5.0&tabs=visual-studio-code