• vscode 開發MVC項目記録


    需要:

    dotnet new mvc -o MvcMovie                     新建MVC項目

    code -r MvcMovie             加載csproj項目

    dotnet dev-certs https --trust            信任證書

    为了在开发环境中使用HTTPS,必须要生成加密证书。.net core提供了一个全局工具dotnet-dev-certs,使用该工具可在本地环境中创建自签名的证书。可以通过下面命令行安装该工具:

    dotnet tool install -global dotnet-dev-certs

    安装成功后,就可以用他自签名的证书。

    -ep标志表示将生成证书导出的存储目录;

    -p标志表示生成证书的密码。

    可以使用-trust选项来信任生成的证书。

    • 启动 Kestrel
    • 启动浏览器。
    • 导航到 https://localhost:5001

    Kestrel 是一个跨平台的适用于 Kestrel。 Kestrel 是包含在 ASP.NET Core 项目模板中的 Web 服务器,默认处于启用状态。

    Kestrel 支持以下方案:

    • HTTPS
    • HTTP/2(在 macOS† 上除外)
    • 用于启用 WebSocket 的不透明升级
    • 用于获得 Nginx 高性能的 Unix 套接字

    添加 NuGet 包

    运行以下 .NET CLI 命令:

    .NET CLI
    dotnet tool uninstall --global dotnet-aspnet-codegenerator
    dotnet tool install --global dotnet-aspnet-codegenerator
    dotnet tool uninstall --global dotnet-ef
    dotnet tool install --global dotnet-ef
    dotnet add package Microsoft.EntityFrameworkCore.Design
    dotnet add package Microsoft.EntityFrameworkCore.SQLite
    dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
    dotnet add package Microsoft.EntityFrameworkCore.SqlServer
    

    上述命令添加:

    使用基架工具为电影模型生成 CreateReadUpdate 和 Delete (CRUD) 页面。

    在项目目录中打开命令窗口。 项目目录是包含 Program.cs 和 .csproj 文件的目录。

    在 macOS 和 Linux 上,导出基架工具路径:

    控制台
    export PATH=$HOME/.dotnet/tools:$PATH
    

    运行下面的命令:

    .NET CLI
    dotnet-aspnet-codegenerator controller -name MoviesController -m Movie -dc MvcMovieContext --relativeFolderPath Controllers --useDefaultLayout --referenceScriptLibraries -sqlite
    

    下表详细说明了 ASP.NET Core 代码生成器参数:

    参数说明
    -M 模型的名称。
    -dc 数据上下文。
    --relativeFolderPath 用于创建文件的相对输出文件夹路径。
    --useDefaultLayout|-udl 应为视图使用默认布局。
    --referenceScriptLibraries 向“编辑”和“创建”页面添加 _ValidationScriptsPartial
    -sqlite 标记来指定 DbContext 是否应使用 SQLite,而不是 SQL Server。

    使用 h 开关获取 aspnet-codegenerator controller 命令方面的帮助:

    .NET CLI
    dotnet aspnet-codegenerator controller -h

    将 SQLite 用于开发,将 SQL Server 用于生产

    Program.cs 中突出显示的以下代码展示了如何在开发中使用 SQLite,以及在生产中使用 SQL Server。

    C#
    var builder = WebApplication.CreateBuilder(args);
    
    if (builder.Environment.IsDevelopment())
    {
        builder.Services.AddDbContext<MvcMovieContext>(options =>
            options.UseSqlite(builder.Configuration.GetConnectionString("MvcMovieContext")));
    }
    else
    {
        builder.Services.AddDbContext<MvcMovieContext>(options =>
            options.UseSqlServer(builder.Configuration.GetConnectionString("ProductionMvcMovieContext")));
    }
    
    

    基架更新以下内容:

    • 在 Program.cs 文件中注册数据库上下文
    • 将数据库连接字符串添加到 appsettings.json 文件。

    基架创建以下内容:

    • 电影控制器:Controllers/MoviesController.cs
    • “创建”、“删除”、“详细信息”、“编辑”和“索引”页面的 Razor 视图文件:Views/Movies/*.cshtml
    • 数据库上下文类:Data/MvcMovieContext.cs

    自动创建这些文件和文件更新被称为“基架”。

    尚且不能使用基架页面,因为该数据库不存在。 运行应用并选择“Movie App”链接会导致“无法打开数据库”或“无此类表: Movie”错误消息。

    构建应用程序。 编译器会生成几个有关如何处理 null 值的警告。

    若要消除可为空引用类型的警告,请从 MvcMovie.csproj 文件中删除以下行:

    XML
    <Nullable>enable</Nullable>


    使用 EF Core 迁移功能来创建数据库。 迁移是可用于创建和更新数据库以匹配数据模型的一组工具。
     

    如果尚未安装 dotnet ef,请安装它作为全局工具:

    .NET CLI
      dotnet tool install --global dotnet-ef
    

    有关 EF Core 的 CLI 的详细信息,请参阅 .Net CLI 的 EF Core 工具引用

    运行以下 .NET CLI 命令:

    .NET CLI
    dotnet ef migrations add InitialCreate
    dotnet ef database update
    
    • ef migrations add InitialCreate:生成 Migrations/{timestamp}_InitialCreate.cs 迁移文件。 InitialCreate 参数是迁移名称。 可以使用任何名称,但是按照惯例,会选择可说明迁移的名称。 因为这是首次迁移,所以生成的类包含用于创建数据库架构的代码。 数据库架构基于在 MvcMovieContext 类(位于 Data/MvcMovieContext.cs 文件中)中指定的模型。
    • ef database update:将数据库更新到上一个命令创建的最新迁移。 此命令在用于创建数据库的 Migrations/{time-stamp}_InitialCreate.cs 文件中运行 Up 方法。

    检查生成的数据库上下文类和注册

    对于 EF Core,使用模型执行数据访问。 模型由实体类和表示数据库会话的上下文对象构成。 上下文对象允许查询并保存数据。 数据库上下文派生自 Microsoft.EntityFrameworkCore.DbContext 并指定要包含在数据模型中的实体。

    基架创建 Data/MvcMovieContext.cs 数据库上下文类:

    C#
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.EntityFrameworkCore;
    using MvcMovie.Models;
    
    namespace MvcMovie.Data
    {
        public class MvcMovieContext : DbContext
        {
            public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
                : base(options)
            {
            }
    
            public DbSet<MvcMovie.Models.Movie> Movie { get; set; }
        }
    }
    

    前面的代码创建一个 DbSet<Movie> 属性,该属性表示数据库中的电影。

    依赖项注入

    ASP.NET Core 通过依赖关系注入 (DI) 生成。 服务(如数据库上下文)在 Program.cs 中向 DI 注册。 这些服务通过构造函数参数提供给需要它们的组件。

    在 Controllers/MoviesController.cs 文件中,构造函数使用依赖关系注入将 MvcMovieContext 数据库上下文注入到控制器中。 数据库上下文将在控制器中的每个 CRUD 方法中使用。

    基架在 Program.cs 中生成了以下突出显示的代码:

    C#
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddDbContext<MvcMovieContext>(options =>
        options.UseSqlite(builder.Configuration.GetConnectionString("MvcMovieContext")));
    

    ASP.NET Core 配置系统读取“MvcMovieContext”数据库连接字符串。

    检查生成的数据库连接字符串

    基架向 appsettings.json 文件添加了一个连接字符串:

    JSON
    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*",
      "ConnectionStrings": {
        "MvcMovieContext": "Data Source=MvcMovie.db"
      }
    }}
    

    进行本地开发时,ASP.NET Core 配置系统在 appsettings.json 文件中读取 ConnectionString 键。

    InitialCreate 类

    检查 Migrations/{timestamp}_InitialCreate.cs 迁移文件:

    C#
    using System;
    using Microsoft.EntityFrameworkCore.Migrations;
    
    #nullable disable
    
    namespace MvcMovie.Migrations
    {
        public partial class InitialCreate : Migration
        {
            protected override void Up(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.CreateTable(
                    name: "Movie",
                    columns: table => new
                    {
                        Id = table.Column<int>(type: "int", nullable: false)
                            .Annotation("SqlServer:Identity", "1, 1"),
                        Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
                        ReleaseDate = table.Column<DateTime>(type: "datetime2", nullable: false),
                        Genre = table.Column<string>(type: "nvarchar(max)", nullable: true),
                        Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Movie", x => x.Id);
                    });
            }
    
            protected override void Down(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.DropTable(
                    name: "Movie");
            }
        }
    }
    

    在上述代码中:

    • InitialCreate.Up 创建 Movie 表,并将 Id 配置为主键。
    • InitialCreate.Down 还原 Up 迁移所做的架构更改。

    控制器中的依赖项注入

    打开 Controllers/MoviesController.cs 文件并检查构造函数:

    C#
    public class MoviesController : Controller
    {
        private readonly MvcMovieContext _context;
    
        public MoviesController(MvcMovieContext context)
        {
            _context = context;
        }
    

    构造函数使用依赖关系注入将数据库上下文 (MvcMovieContext) 注入到控制器中。 数据库上下文将在控制器中的每个 CRUD 方法中使用。

    测试“创建”页。 输入并提交数据。

    测试“编辑”、“详细信息”和“删除”页 。

    强类型模型和 @model 指令

    在本教程之前的内容中,已经介绍了控制器如何使用 ViewData 字典将数据或对象传递给视图。 ViewData 字典是一个动态对象,提供了将信息传递给视图的方便的后期绑定方法。

    MVC 提供将强类型模型对象传递给视图的功能。 此强类型方法启用编译时代码检查。 基架机制在 MoviesController 类和视图中传递了一个强类型模型。

    检查 Controllers/MoviesController.cs 文件中生成的 Details 方法:

    C#
    // GET: Movies/Details/5
    public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }
    
        var movie = await _context.Movie
            .FirstOrDefaultAsync(m => m.Id == id);
        if (movie == null)
        {
            return NotFound();
        }
    
        return View(movie);
    }
    

    id 参数通常作为路由数据传递。 例如,https://localhost:5001/movies/details/1 的设置如下:

    • 控制器被设置为 movies 控制器(第一个 URL 段)。
    • 操作被设置为 details(第二个 URL 段)。
    • id 被设置为 1(最后一个 URL 段)。

    id 可以通过查询字符串传入,如以下示例所示:

    https://localhost:5001/movies/details?id=1

    在未提供 id 值的情况下,id 参数可定义为可以为 null 的类型 (int?)。

    Lambda 表达式会被传入 FirstOrDefaultAsync 方法以选择与路由数据或查询字符串值相匹配的电影实体。

    C#
    var movie = await _context.Movie
        .FirstOrDefaultAsync(m => m.Id == id);
    

    如果找到了电影,Movie 模型的实例则会被传递到 Details 视图:

    C#
    return View(movie);
    

    检查 Views/Movies/Details.cshtml 文件的内容:

    CSHTML
    @model MvcMovie.Models.Movie
    
    @{
        ViewData["Title"] = "Details";
    }
    
    <h1>Details</h1>
    
    <div>
        <h4>Movie</h4>
        <hr />
        <dl class="row">
            <dt class = "col-sm-2">
                @Html.DisplayNameFor(model => model.Title)
            </dt>
            <dd class = "col-sm-10">
                @Html.DisplayFor(model => model.Title)
            </dd>
            <dt class = "col-sm-2">
                @Html.DisplayNameFor(model => model.ReleaseDate)
            </dt>
            <dd class = "col-sm-10">
                @Html.DisplayFor(model => model.ReleaseDate)
            </dd>
            <dt class = "col-sm-2">
                @Html.DisplayNameFor(model => model.Genre)
            </dt>
            <dd class = "col-sm-10">
                @Html.DisplayFor(model => model.Genre)
            </dd>
            <dt class = "col-sm-2">
                @Html.DisplayNameFor(model => model.Price)
            </dt>
            <dd class = "col-sm-10">
                @Html.DisplayFor(model => model.Price)
            </dd>
        </dl>
    </div>
    <div>
        <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
        <a asp-action="Index">Back to List</a>
    </div>
    

    视图文件顶部的 @model 语句可指定视图期望的对象类型。 创建影片控制器时,将包含以下 @model 语句:

    CSHTML
    @model MvcMovie.Models.Movie

    此 @model 指令允许访问控制器传递给视图的影片。 Model 对象为强类型对象。 例如,在 Details.cshtml 视图中,代码通过强类型的 Model 对象将每个电影字段传递给 DisplayNameFor 和 DisplayFor HTML 帮助程序。 Create 和 Edit 方法以及视图也传递一个 Movie 模型对象。

    检查电影控制器中的 Index.cshtml 视图和 Index 方法。 请注意代码在调用 View 方法时是如何创建 List 对象的。 代码将此 Movies 列表从 Index 操作方法传递给视图:

    C#
    // GET: Movies
    public async Task<IActionResult> Index()
    {
        return View(await _context.Movie.ToListAsync());
    }
    

    创建电影控制器后,基架将以下 @model 语句包含在 Index.cshtml 文件的顶部:

    CSHTML
    @model IEnumerable<MvcMovie.Models.Movie>

    @model 指令允许使用强类型的 Model 对象访问控制器传递给视图的电影列表。 例如,在 Index.cshtml 视图中,代码使用 foreach 语句通过强类型 Model 对象对电影进行循环遍历:

    CSHTML
    @model IEnumerable<MvcMovie.Models.Movie>
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-action="Create">Create New</a>
    </p>
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Price)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
    @foreach (var item in Model) {
            <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-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
    }
        </tbody>
    </table>
    

    因为 Model 对象为强类型(作为 IEnumerable<Movie> 对象),因此循环中的每个项都被类型化为 Movie。 编译器还有一些其他优势,比如验证代码中使用的类型。

     
  • 相关阅读:
    软件架构自学笔记-- 转载“腾讯数据库专家雷海林分享智能运维架构”
    软件架构自学笔记-- 架构设计与安全控制
    软件架构自学笔记——什么样的架构才是好的架构
    软件架构自学笔记----分享“去哪儿 Hadoop 集群 Federation 数据拷贝优化”
    软件架构自学笔记---架构分析
    软件架构自学笔记——非功能特性
    软件架构自学笔记——常见的软件架构(https://jiajunhuang.com/articles/2018_09_16-common_software_archtecture_pattern.md.html)
    微服务化的基石——持续集成
    微软开源大规模数据处理项目 Data Accelerator
    vs2019 cdkey 秘钥
  • 原文地址:https://www.cnblogs.com/bedfly/p/16382289.html
Copyright © 2020-2023  润新知