当前位置 博文首页 > 基于.NET Core 3.1 网站开发和部署的方法

    基于.NET Core 3.1 网站开发和部署的方法

    作者:njohao 时间:2021-09-08 17:46

    目录
    • 一、准备开发环境
      • 1.主要开发工具的选择
      • 2.vscode安装C#插件
      • 3.安装数据库
      • 4.使用Dbeaver连接数据库创建数据表和测试数据
    • 二、搭建项目框架
      • 1.使用vscode创建一个mvc项目
      • 2.生成Model
    • 三、编写Model部分的代码
      • 四、前端UI实现
        • 五、使用区域项目完成后台管理系统
          • 六、使用依赖注入改进项目
            • 七、项目发布
              • 八、通过Nginx部署到Linux服务器
                • 参考文档

                  一、准备开发环境

                  1.主要开发工具的选择

                  • vscode
                  • .NET Core command-line interface (CLI) tools
                  • Dbeaver

                  这里选择vscode + .net core cli 是因为不管在Windows还是Linux和Mac上都能使用这一套工具,而且命令行工具也非常强大。

                  2.vscode安装C#插件

                  在vscode插件市场中搜索安装即可


                  新手还可以去这里了解vscode的强大之处

                  3.安装数据库

                  这里使用Centos7,因为.NET Core 3.1只支持7及以上版本

                  配置网络

                  nmcli conn
                  nmcli conn add ifname ens34 con-name ens34 type enthernet autoconnect yes ip4 192.168.30.110/24
                  

                  安装mariadb-server

                  使用XShell连接服务器

                  cd /etc/yum.repos.d/
                  mkdir bak
                  mv Cen* ./bak/
                  curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
                  yum install mariadb-server.x86_64 
                  

                  启动服务

                  systemctl enable mariadb.service
                  systemctl start mariadb.service
                  systemctl status mariadb
                  

                  执行安全加强脚本

                  mysql_secure_installation

                  创建数据库并授权访问帐号

                  MariaDB [(none)]> create database HotelWebDb default charset utf8 collate utf8_general_ci;
                  MariaDB [(none)]> grant all on HotelWebDb.* to sa@'192.168.30.%' identified by '110';
                  MariaDB [(none)]> show databases;
                  +--------------------+
                  | Database      |
                  +--------------------+
                  | information_schema |
                  | HotelWebDb     |
                  | mysql       |
                  | performance_schema |
                  +--------------------+
                  4 rows in set (0.00 sec)

                  4.使用Dbeaver连接数据库创建数据表和测试数据



                  编写Sql脚本

                  -- 管理员登录表
                  CREATE TABLE if not EXISTS SysAdmins
                  (
                    LoginId INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
                    LoginName VARCHAR(20) NOT NULL,
                    LoginPwd VARCHAR(20) NOT NULL
                  )engine=innodb DEFAULT charset=utf8;
                  ALTER TABLE SysAdmins AUTO_INCREMENT=10000;
                  
                  -- 新闻分类表
                  CREATE TABLE if not EXISTS NewsCategory
                  (
                    CategoryId INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
                    CategoryName VARCHAR(20) NOT NULL
                  )engine=innodb DEFAULT charset=utf8;
                  
                  -- 新闻表
                  CREATE TABLE if not EXISTS News
                  (
                    Id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
                    NewsTitle VARCHAR(100),
                    NewsContent TEXT,
                    PublishTime TIMESTAMP DEFAULT now(),
                    CategoryId INT UNSIGNED ,
                    FOREIGN KEY(CategoryId) REFERENCES NewsCategory (CategoryId)
                  )engine=innodb DEFAULT charset=utf8;
                  ALTER TABLE News AUTO_INCREMENT=1000;
                  
                  -- 菜品分类表
                  CREATE TABLE if not EXISTS DishCategory
                  (
                    CategoryId INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
                    CategoryName VARCHAR(20)
                  )engine=innodb DEFAULT charset=utf8;
                  
                  
                  -- 菜品表
                  CREATE TABLE if not EXISTS Dishes
                  (
                    Id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
                    DishName VARCHAR(100),
                    UnitPrice NUMERIC(18, 2),
                    CategoryId INT UNSIGNED,
                    FOREIGN KEY(CategoryId) REFERENCES DishCategory (CategoryId)
                  )engine=innodb DEFAULT charset=utf8;
                  ALTER TABLE Dishes AUTO_INCREMENT=10000;
                  
                  -- 菜品预订表
                  CREATE TABLE if not EXISTS DishBook
                  (
                    Id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
                    HotelName VARCHAR(50),
                    ConsumeTime datetime,
                    ConsumePersons INT UNSIGNED,
                    RoomType VARCHAR(20),
                    CustomerPhone VARCHAR(20),
                    CustomerName VARCHAR(20),
                    CustomerEmail VARCHAR(100),
                    Comments VARCHAR(500),
                    BookTime TIMESTAMP DEFAULT now(),
                    BookStatus INT DEFAULT 0 -- ( 0 表示未审核,1 表示审核通过,2 表示消费完成,-1 表示撤销订单)
                  )engine=innodb DEFAULT charset=utf8;
                  ALTER TABLE DishBook AUTO_INCREMENT=1000;
                  
                  -- 招聘信息表
                  CREATE TABLE if not EXISTS Recruitment
                  (
                    PostId INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
                    PostName NVARCHAR(100),
                    PostType CHAR(4), -- (全职或兼职)
                    WorkPlace NVARCHAR(50),
                    PostDesc TEXT,
                    PostRequire TEXT,
                    Experience NVARCHAR(100),
                    EduBackground NVARCHAR(100),
                    RequireCount INT,
                    PublishTime TIMESTAMP DEFAULT now(),
                    Manager VARCHAR(20),
                    PhoneNumber VARCHAR(20),
                    Email VARCHAR(100)
                  )engine=innodb DEFAULT charset=utf8;
                  ALTER TABLE Recruitment AUTO_INCREMENT=100000;
                  
                  -- 投诉建议表
                  CREATE TABLE if not EXISTS Suggestion
                  (
                    Id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
                    CustomerName VARCHAR(20),
                    ConsumeDesc TEXT,
                    SuggestionDesc TEXT,
                    SuggestionTime TIMESTAMP DEFAULT now(),
                    PhoneNumber VARCHAR(20),
                    Email VARCHAR(20),
                    StatusId INT DEFAULT 0 -- (0:未受理;1:已经受理)
                  )engine=innodb DEFAULT charset=utf8;
                  ALTER TABLE Suggestion AUTO_INCREMENT=10000;
                  

                  创建测试数据

                  -- 插入测试数据
                  -- 管理员信息
                  insert into SysAdmins(LoginPwd,LoginName)values('123456','李浩');
                  insert into SysAdmins(LoginPwd,LoginName)values('123456','赵雪伶');
                  -- 新闻分类
                  insert into NewsCategory(CategoryName)values('公司新闻');
                  insert into NewsCategory(CategoryName)values('社会新闻');
                  -- 菜品分类
                  insert into DishCategory(CategoryName)values('川菜');
                  insert into DishCategory(CategoryName)values('湘菜');
                  insert into DishCategory(CategoryName)values('鲁菜');
                  insert into DishCategory(CategoryName)values('海鲜类');
                  insert into DishCategory(CategoryName)values('其他');
                  -- 新闻
                  insert into News(NewsTitle,NewsContent,CategoryId)values('迎接十一海鲜大促销','最新鲜的鱼类全面上市,欢迎新老顾客品尝。',1);
                  insert into News(NewsTitle,NewsContent,CategoryId)values('本店正在热招加盟商','如果您愿意在酒店行业有所突破,请加入我们。',1);
                  insert into News(NewsTitle,NewsContent,CategoryId)values('互联网的消费正在兴起','网上购物已经成为人们生活必不可少的一部分。',2);
                  insert into News(NewsTitle,NewsContent,CategoryId)values('本店正在热招加盟商','如果您愿意在酒店行业有所突破,请加入我们。',1);
                  insert into News(NewsTitle,NewsContent,CategoryId)values('互联网的消费正在兴起','网上购物已经成为人们生活必不可少的一部分。',2);
                  -- 菜品信息
                  insert into Dishes(DishName,UnitPrice,CategoryId)values('水煮鱼',50,1);
                  insert into Dishes(DishName,UnitPrice,CategoryId)values('回锅肉',85,1);
                  insert into Dishes(DishName,UnitPrice,CategoryId)values('剁椒鱼头',75,2);
                  insert into Dishes(DishName,UnitPrice,CategoryId)values('红椒腊牛肉',40,2);
                  insert into Dishes(DishName,UnitPrice,CategoryId)values('糖醋鲤鱼',70,3);
                  insert into Dishes(DishName,UnitPrice,CategoryId)values('玉记扒鸡',60,3);
                  insert into Dishes(DishName,UnitPrice,CategoryId)values('汤爆双脆',90,3);
                  insert into Dishes(DishName,UnitPrice,CategoryId)values('赤贝',80,4);
                  -- 预定信息
                  insert into DishBook(HotelName,ConsumeTime,ConsumePersons,RoomType,CustomerName,CustomerPhone,CustomerEmail,Comments)
                  values('天津南开店','2014-09-11 12:30',5,'包间','李丽','13589011222','lilivip@163.com','希望房间敞亮些');
                  insert into DishBook(HotelName,ConsumeTime,ConsumePersons,RoomType,CustomerName,CustomerPhone,CustomerEmail,Comments)
                  values('天津和平店','2014-10-11 14:30',5,'包间','王鑫新','13889018888','wangxinxin@qq.com','希望房间安静些');
                  insert into DishBook(HotelName,ConsumeTime,ConsumePersons,RoomType,CustomerName,CustomerPhone,CustomerEmail,Comments)
                  values('北京朝阳点','2014-12-10 17:30',5,'散座','刘花雨','13689011999','liuhuayu@126.com','房间靠里面点儿');
                  -- 招聘信息
                  insert into Recruitment(PostName,PostType,WorkPlace,PostDesc,PostRequire,Experience,EduBackground,RequireCount,Manager,PhoneNumber,Email)
                  values('大堂经理','全职','天津','负责一层楼的管理','要求具备该职位3年以上经营管理经验','3年','本科',2,'李超阳','15689011231','lichaoyang@hyl.com');
                  insert into Recruitment(PostName,PostType,WorkPlace,PostDesc,PostRequire,Experience,EduBackground,RequireCount,Manager,PhoneNumber,Email)
                  values('接待员','全职','北京','负责客户的接待礼仪','要求具备该职位1年以上经验','1年','高中',5,'李超阳','15689011231','lichaoyang@hyl.com');
                  insert into Recruitment(PostName,PostType,WorkPlace,PostDesc,PostRequire,Experience,EduBackground,RequireCount,Manager,PhoneNumber,Email)
                  values('总经理助理','全职','天津','负责日常的文秘工作','要求具备该职位3年以上经营管理经验','3年','本科',1,'李超阳','15689011231','lichaoyang@hyl.com');
                  -- 投诉建议
                  insert into Suggestion(CustomerName,ConsumeDesc,SuggestionDesc,PhoneNumber,Email)
                  values('杜小杰','在该店举行一次婚礼','感觉总体服务不到位,菜品味道没有以前的好。','15687423456','duxiaojie@qq.com');
                  insert into Suggestion(CustomerName,ConsumeDesc,SuggestionDesc,PhoneNumber,Email)
                  values('柳钢','在本店聚会一次','感觉上菜有点慢,希望后续改进。','15686623456','liugang@qq.com');

                  二、搭建项目框架

                  1.使用vscode创建一个mvc项目

                  进入vscode,打开终端创建项目的根目录
                  快捷键:Ctrl + `


                  创建项目根目录

                  D:\dotnet_core>mkdir HotelWebMVC
                  D:\dotnet_core>dir
                   驱动器 D 中的卷是 补充
                   卷的序列号是 0004-524D
                  
                   D:\dotnet_core 的目录
                  
                  2019/12/10 09:33  <DIR>     .
                  2019/12/10 09:33  <DIR>     ..
                  2019/08/30 16:31  <DIR>     .vscode
                  2018/05/07 20:25  <DIR>     helloworld
                  2019/12/10 09:33  <DIR>     HotelWebMVC
                  2019/12/09 20:22  <DIR>     netcore_mvc
                  

                  安装 .NET Core SDK

                  下载地址:https://dotnet.microsoft.com/download

                  查看微软的教程:https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/start-mvc?view=aspnetcore-3.1&tabs=visual-studio-code

                  查看命令帮助

                  D:\dotnet_core\HotelWebMVC>dotnet new --help
                  用法: new [选项]
                  
                  选项:
                   -h, --help     Displays help for this command.
                   -l, --list     Lists templates containing the specified name. If no name is specified, lists all templates.
                   -n, --name     The name for the output being created. If no name is specified, the name of the current directory is used.
                   -o, --output    Location to place the generated output.
                   -i, --install    Installs a source or a template pack.
                   -u, --uninstall   Uninstalls a source or a template pack.
                   --nuget-source   Specifies a NuGet source to use during install.
                   --type       Filters templates based on available types. Predefined values are "project", "item" or "other".
                   --dry-run      Displays a summary of what would happen if the given command line were run if it would result in a template creation.
                   --force       Forces content to be generated even if it would change existing files.
                   -lang, --language  Filters templates based on language and specifies the language of the template to create.
                   --update-check   Check the currently installed template packs for updates.
                   --update-apply   Check the currently installed template packs for update, and install the updates.
                  

                  创建项目



                  以上操作都是可以使用命令完成
                  比如添加解决方案

                  D:\dotnet_core\HotelWebMVC>dotnet sln ./HotelWebMVC.sln add DAL\DAL.csproj
                  已将项目“DAL\DAL.csproj”添加到解决方案中。
                  
                  D:\dotnet_core\HotelWebMVC>dotnet sln ./HotelWebMVC.sln add BLL\BLL.csproj
                  已将项目“BLL\BLL.csproj”添加到解决方案中。
                  
                  D:\dotnet_core\HotelWebMVC>dotnet sln list
                  项目
                  --
                  HotelWebMVC\HotelWebMVC.csproj
                  Models\Models.csproj
                  DAL\DAL.csproj
                  BLL\BLL.csproj
                  

                  添加启动项目和类库项目之间的引用

                  Models -->DAL

                  D:\dotnet_core\HotelWebMVC\DAL>dotnet add reference ..\Models\Models.csproj
                  已将引用“..\Models\Models.csproj”添加到项目。

                  DAL —> BLL

                  D:\dotnet_core\HotelWebMVC\DAL>dotnet add ..\bll\BLL.csproj reference .\DAL.csproj
                  已将引用“..\DAL\DAL.csproj”添加到项目。
                  

                  HotelWebMVC --> BLL

                  D:\dotnet_core\HotelWebMVC\DAL>dotnet add ..\HotelWebMVC\HotelWebMVC.csproj reference ..\bll\BLL.csproj
                  已将引用“..\bll\BLL.csproj”添加到项目。
                  

                  2.生成Model

                  ① 使用EF Core 生成模型

                  DB First模式

                  全局安装ef工具

                  dotnet tool install --global dotnet-ef
                  

                  测试工具是否安装成功

                  D:\dotnet_core\HotelWebMVC>dotnet ef
                  
                             _/\__    
                          ---==/  \\   
                       ___ ___  |.  \|\  
                      | __|| __| | )  \\\  
                      | _| | _|  \_/ | //|\\ 
                      |___||_|    /  \\\/\\
                  
                  Entity Framework Core .NET Command-line Tools 3.1.0
                  
                  Usage: dotnet ef [options] [command]
                  
                  Options:
                   --version    Show version information
                   -h|--help    Show help information
                   -v|--verbose   Show verbose output.
                   --no-color    Don't colorize output.
                   --prefix-output Prefix output with level.
                  
                  Commands:
                   database  Commands to manage the database.
                   dbcontext  Commands to manage DbContext types.
                   migrations Commands to manage migrations.
                  
                  Use "dotnet ef [command] --help" for more information about a command.
                  

                  只要看到有这个独角兽就代表安装成功了。

                  添加需要的NuGet包

                  dotnet add package Microsoft.EntityFrameworkCore.Design
                  dotnet add package Pomelo.EntityFrameworkCore.MySql

                  使用EF工具

                  查看帮助

                  D:\dotnet_core\HotelWebMVC\DAL>dotnet ef dbcontext scaffold --help
                  
                  
                  Usage: dotnet ef dbcontext scaffold [arguments] [options]
                  
                  Arguments:
                   <CONNECTION> The connection string to the database.
                   <PROVIDER>  The provider to use. (E.g. Microsoft.EntityFrameworkCore.SqlServer)
                  
                  Options:
                   -d|--data-annotations         Use attributes to configure the model (where possible). If omitted, only the fluent API is used.
                   -c|--context <NAME>          The name of the DbContext.
                   --context-dir <PATH>          The directory to put DbContext file in. Paths are relative to the project directory.
                   -f|--force               Overwrite existing files.
                   -o|--output-dir <PATH>         The directory to put files in. Paths are relative to the project directory.
                   --schema <SCHEMA_NAME>...       The schemas of tables to generate entity types for.
                   -t|--table <TABLE_NAME>...       The tables to generate entity types for.
                   --use-database-names          Use table and column names directly from the database.
                   --json                 Show JSON output.
                   -p|--project <PROJECT>         The project to use.
                   -s|--startup-project <PROJECT>     The startup project to use.
                   --framework <FRAMEWORK>        The target framework.
                   --configuration <CONFIGURATION>    The configuration to use.
                   --runtime <RUNTIME_IDENTIFIER>     The runtime to use.
                   --msbuildprojectextensionspath <PATH> The MSBuild project extensions path. Defaults to "obj".
                   --no-build               Don't build the project. Only use this when the build is up-to-date.
                   -h|--help               Show help information
                   -v|--verbose              Show verbose output.
                   --no-color               Don't colorize output.
                   --prefix-output            Prefix output with level.
                  

                  连接数据库生成模型数据

                  D:\dotnet_core\HotelWebMVC\DAL>dotnet ef dbcontext scaffold "Server=192.168.30.110,3306;DataBase=HotelWebDb;User=sa;Pwd=110;" "Pomelo.EntityFrameworkCore.MySql" -s ..\HotelWebMVC\HotelWebMVC.csproj
                  Build started...
                  Build succeeded.
                  


                  修改连接字符串的位置

                  修改在appsettings.json文件中添加连接字符串

                  {
                   "Logging": {
                    "LogLevel": {
                     "Default": "Information",
                     "Microsoft": "Warning",
                     "Microsoft.Hosting.Lifetime": "Information"
                    }
                   },
                   "AllowedHosts": "*",
                   "ConnectionStrings":{
                    "HotelWeb":"Server=192.168.30.110,3306;DataBase=HotelWebDb;User=sa;Pwd=110;"
                   }
                  }
                  
                  

                  然后在Sartup.cs文件获取连接字符串

                  public void ConfigureServices(IServiceCollection services)
                  {
                  	services.AddControllersWithViews();
                  	string connString=Configuration.GetConnectionString("HotelWeb");
                  	services.AddDbContext<DAL.HotelWebDbContext>(options=>options.UseMySql(connString, x => x.ServerVersion("5.5.64-mariadb")));
                  }
                  

                  最后DbContenxt类中配置就可以删除了

                  移动DAL生成的实体类到Models模块
                  修改实体类中的命名空间

                  ② 另一种使用ADO.NET实现

                  不是这次的重点,所以略过。

                  三、编写Model部分的代码

                  1.编写一个简单的Helper类

                  using Microsoft.EntityFrameworkCore;
                  
                  namespace DAL
                  {
                    class EFCoreHelper
                    {
                      private DbContext dbContext = null;
                      public EFCoreHelper(DbContext context)
                      {
                        this.dbContext = context;
                      }
                  
                      /// <summary>
                      /// 添加实体
                      /// </summary>
                      /// <typeparam name="T"></typeparam>
                      public int Add<T>(T entity) where T : class
                      {
                        dbContext.Entry(entity).State=EntityState.Added;
                        return dbContext.SaveChanges();
                      }
                  
                      /// <summary>
                      /// 修改实体的全部属性
                      /// </summary>
                      /// <typeparam name="T"></typeparam>
                      public int Modify<T>(T entity) where T:class
                      {
                        dbContext.Entry(entity).State=EntityState.Modified;
                        return dbContext.SaveChanges();
                      }
                  
                      /// <summary>
                      /// 删除实体
                      /// </summary>
                      /// <typeparam name="T"></typeparam>
                      public int Delete<T>(T entity) where T:class
                      {
                        dbContext.Entry(entity).State=EntityState.Deleted;
                        return dbContext.SaveChanges();
                      }
                    }
                  }
                  

                  2.完成新闻后台数据访问类

                  数据访问类

                  using System;
                  using System.Linq;
                  using System.Collections.Generic;
                  using Models;
                  
                  namespace DAL
                  {
                    public class NewsService
                    {
                      private EFCoreHelper helper = new EFCoreHelper(new HotelWebDbContext());
                  
                      /// <summary>
                      /// 添加新闻
                      /// </summary>
                      /// <param name="news"></param>
                      /// <returns></returns>
                      public int AddNews(News news) => helper.Add(news);
                  
                      /// <summary>
                      /// 修改新闻
                      /// </summary>
                      /// <param name="news"></param>
                      /// <returns></returns>
                      public int ModifyNews(News news) => helper.Modify(news);
                  
                      /// <summary>
                      /// 删除新闻
                      /// </summary>
                      /// <param name="newssId"></param>
                      /// <returns></returns>
                      public int DeleteNews(string newssId)
                      {
                        News news = new News() { Id = Convert.ToUInt32(newssId) };
                        return helper.Delete(news);
                      }
                  
                      /// <summary>
                      /// 获取指定数量的新闻列表
                      /// </summary>
                      /// <param name="count"></param>
                      /// <returns></returns>
                      public List<News> GetNews(int count)
                      {
                        using (HotelWebDbContext dbContext = new HotelWebDbContext())
                        {
                          return (from n in dbContext.News orderby n.PublishTime descending select n).Take(count).ToList();
                        }
                      }
                  
                      /// <summary>
                      /// 根据ID获取新闻信息
                      /// </summary>
                      /// <param name="newssId"></param>
                      /// <returns></returns>
                      public News GetNewsById(string newssId)
                      {
                        uint id = Convert.ToUInt32(newssId);
                        using (HotelWebDbContext dbContext = new HotelWebDbContext())
                        {
                          return (from n in dbContext.News where n.Id == id select n).FirstOrDefault();
                        }
                      }
                  
                      /// <summary>
                      /// 获取所有的新闻分类
                      /// </summary>
                      /// <returns></returns>
                      public List<NewsCategory> GetCategories()
                      {
                        using (HotelWebDbContext dbContext = new HotelWebDbContext())
                        {
                          return (from c in dbContext.NewsCategory select c).ToList();
                        }
                      }
                    }
                  }

                  业务逻辑部分

                  using System.Collections.Generic;
                  using DAL;
                  using Models;
                  
                  namespace BLL
                  {
                    public class NewsManager
                    {
                      private NewsService objService=new NewsService();
                      /// <summary>
                      /// 添加新闻
                      /// </summary>
                      /// <param name="news"></param>
                      /// <returns></returns>
                      public int AddNews(News news) => objService.AddNews(news);
                  
                      /// <summary>
                      /// 修改新闻
                      /// </summary>
                      /// <param name="news"></param>
                      /// <returns></returns>
                      public int ModifyNews(News news) => objService.ModifyNews(news);
                  
                      /// <summary>
                      /// 删除新闻
                      /// </summary>
                      /// <param name="newssId"></param>
                      /// <returns></returns>
                      public int DeleteNews(string newssId) => objService.DeleteNews(newssId);
                  
                      /// <summary>
                      /// 获取指定数量的新闻列表
                      /// </summary>
                      /// <param name="count"></param>
                      /// <returns></returns>
                      public List<News> GetNews(int count) => objService.GetNews(count);
                  
                      /// <summary>
                      /// 根据ID获取新闻信息
                      /// </summary>
                      /// <param name="newssId"></param>
                      /// <returns></returns>
                      public News GetNewsById(string newssId) => objService.GetNewsById(newssId);
                  
                      /// <summary>
                      /// 获取所有的新闻分类
                      /// </summary>
                      /// <returns></returns>
                      public List<NewsCategory> GetCategories() => objService.GetCategories();
                    }
                  }
                  

                  3.添加一个控制台项目用来测试

                  添加需要的引用

                  dotnet add package Microsoft.EntityFrameworkCore.Design
                  dotnet add package Pomelo.EntityFrameworkCore.MySql

                  DbContext中的数据库连接字符串添加回去

                     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
                      {
                        if(!optionsBuilder.IsConfigured)
                        {
                          optionsBuilder.UseMySql("Server=192.168.30.110;DataBase=HotelWebDb;User=sa;Pwd=110;",x => x.ServerVersion("5.5.64-mariadb"));
                        }
                      }
                  
                  

                  编写测试代码

                   News news=new News()
                        {
                          NewsContent="你好这是一个测试新闻内容",
                          NewsTitle="测试新闻",
                          CategoryId=1
                        };
                  
                        Console.WriteLine(objNews.AddNews(news));

                  启动调试
                  选择启动项目有两种方法

                  ①通过solution explorer 插件选择


                  ②通过配置launch.json 文件启动


                  然后修改启动程序入口就可以了

                   {
                        "name": ".NET Core Launch (console)",
                        "type": "coreclr",
                        "request": "launch",
                        "preLaunchTask": "build",
                        "program": "${workspaceFolder}/UnitTestPro/bin/Debug/netcoreapp3.1/UnitTestPro.dll",
                        "args": [],
                        "cwd": "${workspaceFolder}",
                        "stopAtEntry": false,
                        "console": "internalConsole"
                      },
                  

                  还要修改task文件,否则测试项目中新加的代码不能被执行。

                  结果查验


                  结果符合预期

                  注意事项
                  修改新闻调用的方法不支持部分属性修改,如果对象属性不设置,那么没有设置的字段被设置为空。
                  后面有字段部分修改的方法。

                     News news=new News()
                        {
                          Id=1008,
                          NewsContent="修改新闻的内容",
                          NewsTitle="这是被修改的新闻标题",
                        };
                        Console.WriteLine(objNews.ModifyNews(news));
                  

                  4.编写菜品预订

                  5.编写招聘

                  6.编写投诉和建议

                  7.管理员登录

                  类似不再贴代码

                  四、前端UI实现

                  1.完成前端Html代码的编写

                  不多说

                  2.完成MVC项目中控制器和视图的文件添加

                  这个只能手动添加,不像VS有模板可用

                  3.复制网站的静态资源

                  asp.net core 网站静态资源都是放在wwwroot目录的,并且文件名一般是小写。

                  4.在视图中引用资源

                  MVC框架可以直接识别在wwwroot中的静态资源,不用写显示的写出目录名。

                   <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" />
                    <link rel="stylesheet" href="~/css/site.css" rel="external nofollow" rel="external nofollow" />
                  

                  5.编写动作方法

                    public IActionResult Index()
                      {
                        return View();
                      }
                  
                  

                  6.添加视图

                  7.启动调试

                  首页效果图

                  8.视图与控制器之间传递数据

                  使用ViewData

                  视图的网页标题可以使用这种方式传递

                    public IActionResult Index()
                      {
                        ViewData["title"]="好运来酒店";
                        ViewBag.list=new NewsManager().GetNews(4);
                        return View();
                      }
                  

                  视图中引用数据

                  <!doctype html>
                  <html lang="zh">
                  
                  <head>
                    <!-- Required meta tags -->
                    <meta charset="utf-8">
                    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
                  
                    <!-- Bootstrap CSS -->
                    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" rel="external nofollow" rel="external nofollow" />
                    <link rel="stylesheet" href="~/css/site.css" rel="external nofollow" rel="external nofollow" />
                  
                    <title>@ViewData["title"]-舒适快捷经济</title>
                  </head>
                  

                  使用ViewBag

                  这是所谓的动态类型,直接无中生有造一个属性

                  ViewBag.list=new NewsManager().GetNews(4);

                  视图中引用

                   @foreach (News item in @ViewBag.list) {
                      <div class="d-flex flex-row justify-content-between newslist">
                        <div class="p-2">
                          <a href="/News/NewsDetail?id=@item.Id" rel="external nofollow" rel="external nofollow" >@item.NewsTitle</a>
                        </div>
                        <div class="p-2">
                          @item.PublishTime.ToShortDateString()        
                        </div>
                      </div>
                  

                  使用viewmodel

                  控制器中使用View的重载方法传递viewmodel

                     public IActionResult Index()
                      {
                        ViewData["title"]="好运来酒店";
                        return View(new NewsManager().GetNews(4));
                      }
                  

                  视图中先声明后使用
                  Specify a model using the @model directive. Use the model with @Model:

                  @model list<News>
                  ...
                      @foreach (News item in @Model) {
                      <div class="d-flex flex-row justify-content-between newslist">
                        <div class="p-2">
                          <a href="/News/NewsDetail?id=@item.Id" rel="external nofollow" rel="external nofollow" >@item.NewsTitle</a>
                        </div>
                        <div class="p-2">
                          @item.PublishTime.ToShortDateString()        
                        </div>
                      </div>