asp.net core 系列 3 项目实战之:NetCore 的 Web 应用程序(参考自:Microsoft教程)

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

概述:此教程介绍了生成 Razor Pages Web 应用的基础知识。具体分为如下部分

  1. 创建 Razor 页面 Web 应用
  2. 向 Razor 页面应用添加模型
  3. 基架(生成)Razor 页面
  4. 使用数据库
  5. 更新 Razor 页面
  6. 添加搜索
  7. 添加新字段
  8. 添加验证

首先,我们启用VS新建一个项目:

本篇主要是学习使用NetCore的Razor视图,因此先从最基本的添加项目开始。添加项目完成后,我们发现系统自动生成了以下各项,如下图:

 

 

 首先我们对项目各文件的执行顺序作个说明:

 

 

 与早期版本的 ASP.NET 对比,最显著的变化之一就是配置应用程序的方式, Global.asax、FilterConfig.cs 和 RouteConfig.cs 统统消失了,取而代之的是 Program.cs 和 Startup.cs。Program.cs 作为 Web 应用程序的默认入口,不做任何修改的情况下,会调用同目录下 Startup.cs 中的 ConfigureServices 方法 和 Configure 方法,最后执行Request Handle Start(个人认为就是路由指向的文件) ,譬如:https://localhost:44392/Movies/Details?id=4  执行的是上图Pages文件夹中的Movies文件夹中的Details.cshtml文件,其路由机制和MVC类似。

其次,一起探讨下各个文件夹/文件的作用:

Pages文件夹

1、模板文件,

例如:__Layout.cshtml,一般都放在Pages/Shared文件夹中,_Layout.cshtml 文件可配置所有页面通用的 UI 元素 。 此文件设置页面顶部的导航菜单和页面底部的版权声明。

2、自定义的Razor页面

注意:自定义的Razor页面比模板页面会多出一个CS文件,这一点和.Net MVC中的CsHtml页面不一样,这个CS文件我们可以理解为页面的ViewModel,用于初始化页面及页面业务逻辑的相关操作,譬如:增删改查。

wwwroot 文件夹

包含静态文件,如 HTML 文件、JavaScript 文件和 CSS 文件。 有关详细信息,请参阅 ASP.NET Core 中的静态文件

appSettings.json

包含配置数据,如连接字符串。 有关详细信息,请参阅 ASP.NET Core 中的配置

Program.cs

包含程序的入口点。 有关详细信息,请参阅 .NET 通用主机

Startup.cs

包含配置应用行为的代码。 有关详细信息,请参阅 ASP.NET Core 中的应用启动

文件的简单介绍到此为止,下面我们来添加项目相关准备

1、新建一个数据库,命名为:MovieDB

2、创建一张表,命名为:Movie

脚本如下:

create table Movie
(
ID int identity(1,1) primary key,
Title nvarchar(200),
ReleaseDate datetime,
Genre varchar(200),
Price decimal(18,2)
)
View Code

数据库创建完毕,我们插入一条数据:

  insert into [MovieDB].[dbo].[Movie]
  values('战狼2',getdate(),'影视媒体',18)
View Code

至此,数据准备完毕,下面我们创建数据库链接字符串,打开appsettings.json文件,编辑如下:

新增链接字符串:

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "RazorPagesMovieContext": "Data Source=DESKTOP-VD79APR\\SQLEXPRESS;Initial Catalog=MovieDB;Integrated Security=True"
  }
}
View Code

 注意上述链接字符串中的 RazorPagesMovieContext ,这是一个数据访问上下文,用于数据库对象(数据表)构建及数据访问,我们可以通过VS创建,下面会逐步介绍,现在我们需要准备和数据表对应的实体类Movie,如下:

在项目中添加DataModel文件夹,并添加类:Movie.cs 【类的属性和数据表字段对应,并添加了相关数据验证】,如下:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace RazorPagesMovie2.DataModel
{
    public class Movie
    {
        public int ID { get; set; }

        [StringLength(60, MinimumLength = 3)]
        [Required]
        public string Title { get; set; }

        /// <summary>
        /// 发布日期,Display:展示类型 DataType:数据类型 日期类型
        /// </summary>
        [Display(Name = "Release Date")]
        [DataType(DataType.Date)]
        public DateTime ReleaseDate { get; set; }

       /// <summary>
       /// 价格 范围1~100 货币类型 数字类型
       /// </summary>
        [Range(1, 100)]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18, 2)")]
        public decimal Price { get; set; }

        /// <summary>
        /// 正则表达式 最大长度30  必填信息
        /// </summary>
        [RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$")]
        [Required]
        [StringLength(30)]
        public string Genre { get; set; }
    }
}
View Code

上述准备完毕后,我们利用VS强大的数据模型绑定来构建增删改查页面,如下:

在Pages文件夹中新建文件夹MoviePages,如下:

 

 右键MoviePages文件夹,选择:添加->新搭建基架的项目(F)...,用于创建增删改查页面及生成RazorPagesMovieContext数据库上下文访问类,如下:

 

需要将默认的:RazorPagesMovie2.Models.RazorPagesMovie2Context 修改为:RazorPagesMovie2.Data.RazorPagesMovie2Context ,以便生产一个名为Data的文件夹,用于区分Models文件夹。

 

 

 这是会生产一个Data的文件夹,有一个类,名称为:RazorPagesMovie2Context ,也就是上述提到的数据库访问上下文类,用于数据库访问及数据库对象构建。

如下:

 

 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie2.DataModel;

namespace RazorPagesMovie2.Data
{
    public class RazorPagesMovie2Context : DbContext
    {
        public RazorPagesMovie2Context (DbContextOptions<RazorPagesMovie2Context> options)
            : base(options)
        {
        }

        public DbSet<RazorPagesMovie2.DataModel.Movie> Movie { get; set; }
    }
}
View Code

同时在StartUp.cs中也会指定数据库访问链接字符串,如下:

 

注意:StartUp.cs 中的上下文名称应和appsettings.json 中的名称一致,如果不一致,会导致找不到链接字符串。

 此时,项目基本构建完成,运行如下:

 

 由上图可以,我们根据VS基架模板来生成的增删改查页面对应的.CS文件中有生成相应的增删改查代码,如下:

前端:

@page
@model RazorPagesMovie2.Pages.MoviePages.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].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movie[0].Genre)
            </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.Price)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </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>
View Code

查询代码:

    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie2.Data.RazorPagesMovie2Context _context;

        public IndexModel(RazorPagesMovie2.Data.RazorPagesMovie2Context context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; }

        public async Task OnGetAsync()
        {
            Movie = await _context.Movie.ToListAsync();
        }
    }
View Code

查询表中所有数据,当然,在EF NETCore中也支持Linq查询,如下:

public async Task OnGetAsync()
{
    var movies = from m in _context.Movie
                 select m;
    if (!string.IsNullOrEmpty(SearchString))
    {
        movies = movies.Where(s => s.Title.Contains(SearchString));
    }

    Movie = await movies.ToListAsync();
}
View Code

增加页面代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using RazorPagesMovie2.Data;
using RazorPagesMovie2.DataModel;

namespace RazorPagesMovie2.Pages.MoviePages
{
    public class CreateModel : PageModel
    {
        private readonly RazorPagesMovie2.Data.RazorPagesMovie2Context _context;

        public CreateModel(RazorPagesMovie2.Data.RazorPagesMovie2Context context)
        {
            _context = context;
        }

        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        public Movie Movie { get; set; }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Movie.Add(Movie);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
    }
}
View Code

看到:await _context.SaveChangesAsync();是不是很熟悉,.SaveChanges其实就是EF增加删除更新的最常用方法,呵呵。

前端:

@page
@model RazorPagesMovie2.Pages.MoviePages.CreateModel

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<h4>Movie</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Movie.Title" class="control-label"></label>
                <input asp-for="Movie.Title" class="form-control" />
                <span asp-validation-for="Movie.Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.ReleaseDate" class="control-label"></label>
                <input asp-for="Movie.ReleaseDate" class="form-control" />
                <span asp-validation-for="Movie.ReleaseDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Price" class="control-label"></label>
                <input asp-for="Movie.Price" class="form-control" />
                <span asp-validation-for="Movie.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Movie.Genre" class="control-label"></label>
                <input asp-for="Movie.Genre" class="form-control" />
                <span asp-validation-for="Movie.Genre" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
View Code

 就不一一展示了,大家可参考自己的项目进行学习

参考来自:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/?view=aspnetcore-3.1

@天才卧龙的博客

posted @ 2020-03-24 16:25  天才卧龙  阅读(1046)  评论(0编辑  收藏  举报