关键文件和目录结构
按照asp.net core WEB应用程序向导,创建一个工程之后
你会发现如下几个目录和文件
- wwwroot:放置网站的静态文件的目录
- Pages:放置razor页面的目录
- appsettings.json:是应用的配置文件
- bower.json:静态资源包管理的配置文件
- Program.cs:这个程序负责承载ASP.NET Core应用
- Startup.cs:初始化service的配置,初始化请求管道
下面我们单独说一下Pages目录
_Layout.cshtml 是整个网站的母板文件,
除了在这里写布局页面的代码外,
你还可以把一些基础的样式和脚本放在这里,
_ViewStart.cshtml 负责设置所有Razor页面都会用到的Layout属性,
_ViewImports.cshtml 负责设置所有页面都会用到的指令,比如引入什么类库等
_ValidationScriptsPartial.cshtml 负责引用验证脚本,比如jquery的validation组件
数据库链接字符串放在哪儿
在appsettings.json文件中,你可以防止数据库链接字符串,比如这样:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"ConnectionStrings": {
"MovieContext": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
ConnectionStrings就是数据库链接字符串;
在Startup中依赖注入数据库链接上下文对象
在Startup.cs文件中,有一个ConfigureServices方法,你可以通过依赖注入的方式,加载数据库连接上下文,比如这样:
public void ConfigureServices(IServiceCollection services)
{
// 需要引用如下两个类库
// using RazorPagesMovie.Models;
// using Microsoft.EntityFrameworkCore;
services.AddDbContext<MovieContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MovieContext")));
services.AddMvc();
}
说明:这里用到了Microsoft.EntityFrameworkCore,要先通过nuget包管理器,引入包,相关内容不作赘述;
接下来你就可以写实体,完成相应数据的增删改查了;
数据库表结构同步工具
往往我们写了实体类型,还需要把实体类型做成数据库结构,非常麻烦
这里你可以用microsoft.visualstudio.web.codegeneration.design,这个包来完成相应的工作,相关的命令如下:
Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Design -Version 2.0.0
Add-Migration Initial
Update-Database
第一行是安装这个工具包;
第二行是根据DbContext所引用的实体类,生成数据库表结构的同步代码;
第三行是更新数据库;
这个工具包是不是只支持EF,还有待考察。
Razor页面的PageModel类
好,我们现在看看怎么通过数据库上下文把数据从数据库中拿出来
在Pages目录下,创建一个Razor页面
在相应的cshtml.cs文件中,撰写如下代码:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
using RazorPagesMovie.Models;
namespace RazorPagesMovie.Pages.Movies
{
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Models.MovieContext _context;
public IndexModel(RazorPagesMovie.Models.MovieContext context)
{
_context = context;
}
public IList<Movie> Movie { get;set; }
public async Task OnGetAsync()
{
Movie = await _context.Movie.ToListAsync();
}
}
}
说明:Movie是与数据库表结构对应的实体类;
Razor页面继承自PageModel类,按照约定,类名遵从[PageName]Model这样的命名方式
构造函数通过依赖注入获得数据库访问上下文实例;
关于Razor Page的页面代码
我们再来看看.cshtml文件的代码:
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-page="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movie[0].Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movie) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Razor引擎可以把上面这些HTML代码转成C#代码或者转成Razor过度代码;
当一个 @ 符号后面跟的是Razor保留关键字的话,他会被转义成Razor过度代码,否则会被转义成C#代码;
这是在编译期完成的工作,所以不会影响运行期的执行效率;
关于page指令
@page指令使得这个页面变成了一个ASP.NET MVC的Action
这个指令必须是在Razor Page的第一个指令
关于违法访问的处理
来看看下面这行代码:
@Html.DisplayNameFor(model => model.Movie[0].Title))
这行代码的特殊之处在于,不会存在违法访问的异常,
也就是说model, model.Movie 和model.Movie[0] 的值是 null 或者empty时,不会报异常;
关于model指令
@model RazorPagesMovie.Pages.Movies.IndexModel
这个指令使得cshtml.cs文件中的IndexModel类,在这个Razor Page中有效
关于ViewData
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
你可以在Razor Page页面中设置ViewData的键值,在_Layout.cshtml模版页面中使用你设置的ViewData
关于注释
在Razor Page中,用下面的方式写注释
@*这里是注释*@
关于全局的模版页设置
在_ViewStart.cshtml文件中,我们为所有的页面设置了母板页,代码如下:
@{
Layout = "_Layout";
}
注意,在这里我们并没有详细讲链接标签: asp-page="./Edit" asp-route-id="@item.ID"
以后的文章里我们会说到!