基于.NET Core 3.1 網(wǎng)站開(kāi)發(fā)和部署的方法
一、準(zhǔn)備開(kāi)發(fā)環(huán)境
1.主要開(kāi)發(fā)工具的選擇
- vscode
- .NET Core command-line interface (CLI) tools
- Dbeaver
這里選擇vscode + .net core cli 是因?yàn)椴还茉赪indows還是Linux和Mac上都能使用這一套工具,而且命令行工具也非常強(qiáng)大。
2.vscode安裝C#插件
在vscode插件市場(chǎng)中搜索安裝即可


新手還可以去這里了解vscode的強(qiáng)大之處

3.安裝數(shù)據(jù)庫(kù)
這里使用Centos7,因?yàn)?NET Core 3.1只支持7及以上版本

配置網(wǎng)絡(luò)
nmcli conn nmcli conn add ifname ens34 con-name ens34 type enthernet autoconnect yes ip4 192.168.30.110/24
安裝mariadb-server
使用XShell連接服務(wù)器

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
啟動(dòng)服務(wù)
systemctl enable mariadb.service systemctl start mariadb.service systemctl status mariadb
執(zhí)行安全加強(qiáng)腳本
mysql_secure_installation
創(chuàng)建數(shù)據(jù)庫(kù)并授權(quán)訪問(wèn)帳號(hào)

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連接數(shù)據(jù)庫(kù)創(chuàng)建數(shù)據(jù)表和測(cè)試數(shù)據(jù)



編寫(xiě)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; -- 新聞分類(lèi)表 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; -- 菜品分類(lèi)表 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; -- 菜品預(yù)訂表 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 表示審核通過(guò),2 表示消費(fèi)完成,-1 表示撤銷(xiāo)訂單) )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:已經(jīng)受理) )engine=innodb DEFAULT charset=utf8; ALTER TABLE Suggestion AUTO_INCREMENT=10000;
創(chuàng)建測(cè)試數(shù)據(jù)
-- 插入測(cè)試數(shù)據(jù)
-- 管理員信息
insert into SysAdmins(LoginPwd,LoginName)values('123456','李浩');
insert into SysAdmins(LoginPwd,LoginName)values('123456','趙雪伶');
-- 新聞分類(lèi)
insert into NewsCategory(CategoryName)values('公司新聞');
insert into NewsCategory(CategoryName)values('社會(huì)新聞');
-- 菜品分類(lèi)
insert into DishCategory(CategoryName)values('川菜');
insert into DishCategory(CategoryName)values('湘菜');
insert into DishCategory(CategoryName)values('魯菜');
insert into DishCategory(CategoryName)values('海鮮類(lèi)');
insert into DishCategory(CategoryName)values('其他');
-- 新聞
insert into News(NewsTitle,NewsContent,CategoryId)values('迎接十一海鮮大促銷(xiāo)','最新鮮的魚(yú)類(lèi)全面上市,歡迎新老顧客品嘗。',1);
insert into News(NewsTitle,NewsContent,CategoryId)values('本店正在熱招加盟商','如果您愿意在酒店行業(yè)有所突破,請(qǐng)加入我們。',1);
insert into News(NewsTitle,NewsContent,CategoryId)values('互聯(lián)網(wǎng)的消費(fèi)正在興起','網(wǎng)上購(gòu)物已經(jīng)成為人們生活必不可少的一部分。',2);
insert into News(NewsTitle,NewsContent,CategoryId)values('本店正在熱招加盟商','如果您愿意在酒店行業(yè)有所突破,請(qǐng)加入我們。',1);
insert into News(NewsTitle,NewsContent,CategoryId)values('互聯(lián)網(wǎng)的消費(fèi)正在興起','網(wǎng)上購(gòu)物已經(jīng)成為人們生活必不可少的一部分。',2);
-- 菜品信息
insert into Dishes(DishName,UnitPrice,CategoryId)values('水煮魚(yú)',50,1);
insert into Dishes(DishName,UnitPrice,CategoryId)values('回鍋肉',85,1);
insert into Dishes(DishName,UnitPrice,CategoryId)values('剁椒魚(yú)頭',75,2);
insert into Dishes(DishName,UnitPrice,CategoryId)values('紅椒臘牛肉',40,2);
insert into Dishes(DishName,UnitPrice,CategoryId)values('糖醋鯉魚(yú)',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);
-- 預(yù)定信息
insert into DishBook(HotelName,ConsumeTime,ConsumePersons,RoomType,CustomerName,CustomerPhone,CustomerEmail,Comments)
values('天津南開(kāi)店','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('北京朝陽(yáng)點(diǎn)','2014-12-10 17:30',5,'散座','劉花雨','13689011999','liuhuayu@126.com','房間靠里面點(diǎn)兒');
-- 招聘信息
insert into Recruitment(PostName,PostType,WorkPlace,PostDesc,PostRequire,Experience,EduBackground,RequireCount,Manager,PhoneNumber,Email)
values('大堂經(jīng)理','全職','天津','負(fù)責(zé)一層樓的管理','要求具備該職位3年以上經(jīng)營(yíng)管理經(jīng)驗(yàn)','3年','本科',2,'李超陽(yáng)','15689011231','lichaoyang@hyl.com');
insert into Recruitment(PostName,PostType,WorkPlace,PostDesc,PostRequire,Experience,EduBackground,RequireCount,Manager,PhoneNumber,Email)
values('接待員','全職','北京','負(fù)責(zé)客戶(hù)的接待禮儀','要求具備該職位1年以上經(jīng)驗(yàn)','1年','高中',5,'李超陽(yáng)','15689011231','lichaoyang@hyl.com');
insert into Recruitment(PostName,PostType,WorkPlace,PostDesc,PostRequire,Experience,EduBackground,RequireCount,Manager,PhoneNumber,Email)
values('總經(jīng)理助理','全職','天津','負(fù)責(zé)日常的文秘工作','要求具備該職位3年以上經(jīng)營(yíng)管理經(jīng)驗(yàn)','3年','本科',1,'李超陽(yáng)','15689011231','lichaoyang@hyl.com');
-- 投訴建議
insert into Suggestion(CustomerName,ConsumeDesc,SuggestionDesc,PhoneNumber,Email)
values('杜小杰','在該店舉行一次婚禮','感覺(jué)總體服務(wù)不到位,菜品味道沒(méi)有以前的好。','15687423456','duxiaojie@qq.com');
insert into Suggestion(CustomerName,ConsumeDesc,SuggestionDesc,PhoneNumber,Email)
values('柳鋼','在本店聚會(huì)一次','感覺(jué)上菜有點(diǎn)慢,希望后續(xù)改進(jìn)。','15686623456','liugang@qq.com');
二、搭建項(xiàng)目框架
1.使用vscode創(chuàng)建一個(gè)mvc項(xiàng)目
進(jìn)入vscode,打開(kāi)終端創(chuàng)建項(xiàng)目的根目錄
快捷鍵:Ctrl + `

創(chuàng)建項(xiàng)目根目錄
D:\dotnet_core>mkdir HotelWebMVC D:\dotnet_core>dir 驅(qū)動(dòng)器 D 中的卷是 補(bǔ)充 卷的序列號(hào)是 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
查看命令幫助
D:\dotnet_core\HotelWebMVC>dotnet new --help 用法: new [選項(xiàng)] 選項(xiàng): -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.
創(chuàng)建項(xiàng)目





以上操作都是可以使用命令完成
比如添加解決方案
D:\dotnet_core\HotelWebMVC>dotnet sln ./HotelWebMVC.sln add DAL\DAL.csproj 已將項(xiàng)目“DAL\DAL.csproj”添加到解決方案中。 D:\dotnet_core\HotelWebMVC>dotnet sln ./HotelWebMVC.sln add BLL\BLL.csproj 已將項(xiàng)目“BLL\BLL.csproj”添加到解決方案中。 D:\dotnet_core\HotelWebMVC>dotnet sln list 項(xiàng)目 -- HotelWebMVC\HotelWebMVC.csproj Models\Models.csproj DAL\DAL.csproj BLL\BLL.csproj
添加啟動(dòng)項(xiàng)目和類(lèi)庫(kù)項(xiàng)目之間的引用
Models -->DAL
D:\dotnet_core\HotelWebMVC\DAL>dotnet add reference ..\Models\Models.csproj 已將引用“..\Models\Models.csproj”添加到項(xiàng)目。
DAL —> BLL
D:\dotnet_core\HotelWebMVC\DAL>dotnet add ..\bll\BLL.csproj reference .\DAL.csproj 已將引用“..\DAL\DAL.csproj”添加到項(xiàng)目。
HotelWebMVC --> BLL
D:\dotnet_core\HotelWebMVC\DAL>dotnet add ..\HotelWebMVC\HotelWebMVC.csproj reference ..\bll\BLL.csproj 已將引用“..\bll\BLL.csproj”添加到項(xiàng)目。
2.生成Model
① 使用EF Core 生成模型
DB First模式
全局安裝ef工具
dotnet tool install --global dotnet-ef
測(cè)試工具是否安裝成功
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.
只要看到有這個(gè)獨(dú)角獸就代表安裝成功了。
添加需要的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.
連接數(shù)據(jù)庫(kù)生成模型數(shù)據(jù)
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類(lèi)中配置就可以刪除了
移動(dòng)DAL生成的實(shí)體類(lèi)到Models模塊
修改實(shí)體類(lèi)中的命名空間

② 另一種使用ADO.NET實(shí)現(xiàn)
不是這次的重點(diǎn),所以略過(guò)。
三、編寫(xiě)Model部分的代碼
1.編寫(xiě)一個(gè)簡(jiǎn)單的Helper類(lèi)
using Microsoft.EntityFrameworkCore;
namespace DAL
{
class EFCoreHelper
{
private DbContext dbContext = null;
public EFCoreHelper(DbContext context)
{
this.dbContext = context;
}
/// <summary>
/// 添加實(shí)體
/// </summary>
/// <typeparam name="T"></typeparam>
public int Add<T>(T entity) where T : class
{
dbContext.Entry(entity).State=EntityState.Added;
return dbContext.SaveChanges();
}
/// <summary>
/// 修改實(shí)體的全部屬性
/// </summary>
/// <typeparam name="T"></typeparam>
public int Modify<T>(T entity) where T:class
{
dbContext.Entry(entity).State=EntityState.Modified;
return dbContext.SaveChanges();
}
/// <summary>
/// 刪除實(shí)體
/// </summary>
/// <typeparam name="T"></typeparam>
public int Delete<T>(T entity) where T:class
{
dbContext.Entry(entity).State=EntityState.Deleted;
return dbContext.SaveChanges();
}
}
}
2.完成新聞后臺(tái)數(shù)據(jù)訪問(wèn)類(lèi)
數(shù)據(jù)訪問(wèn)類(lèi)
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>
/// 獲取指定數(shù)量的新聞列表
/// </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>
/// 根據(jù)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>
/// 獲取所有的新聞分類(lèi)
/// </summary>
/// <returns></returns>
public List<NewsCategory> GetCategories()
{
using (HotelWebDbContext dbContext = new HotelWebDbContext())
{
return (from c in dbContext.NewsCategory select c).ToList();
}
}
}
}
業(yè)務(wù)邏輯部分
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>
/// 獲取指定數(shù)量的新聞列表
/// </summary>
/// <param name="count"></param>
/// <returns></returns>
public List<News> GetNews(int count) => objService.GetNews(count);
/// <summary>
/// 根據(jù)ID獲取新聞信息
/// </summary>
/// <param name="newssId"></param>
/// <returns></returns>
public News GetNewsById(string newssId) => objService.GetNewsById(newssId);
/// <summary>
/// 獲取所有的新聞分類(lèi)
/// </summary>
/// <returns></returns>
public List<NewsCategory> GetCategories() => objService.GetCategories();
}
}
3.添加一個(gè)控制臺(tái)項(xiàng)目用來(lái)測(cè)試
添加需要的引用
dotnet add package Microsoft.EntityFrameworkCore.Design dotnet add package Pomelo.EntityFrameworkCore.MySql
DbContext中的數(shù)據(jù)庫(kù)連接字符串添加回去
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"));
}
}
編寫(xiě)測(cè)試代碼
News news=new News()
{
NewsContent="你好這是一個(gè)測(cè)試新聞內(nèi)容",
NewsTitle="測(cè)試新聞",
CategoryId=1
};
Console.WriteLine(objNews.AddNews(news));
啟動(dòng)調(diào)試
選擇啟動(dòng)項(xiàng)目有兩種方法
①通過(guò)solution explorer 插件選擇

②通過(guò)配置launch.json 文件啟動(dòng)


然后修改啟動(dòng)程序入口就可以了
{
"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文件,否則測(cè)試項(xiàng)目中新加的代碼不能被執(zhí)行。

結(jié)果查驗(yàn)

結(jié)果符合預(yù)期
注意事項(xiàng)
修改新聞?wù){(diào)用的方法不支持部分屬性修改,如果對(duì)象屬性不設(shè)置,那么沒(méi)有設(shè)置的字段被設(shè)置為空。
后面有字段部分修改的方法。
News news=new News()
{
Id=1008,
NewsContent="修改新聞的內(nèi)容",
NewsTitle="這是被修改的新聞標(biāo)題",
};
Console.WriteLine(objNews.ModifyNews(news));

4.編寫(xiě)菜品預(yù)訂
5.編寫(xiě)招聘
6.編寫(xiě)投訴和建議
7.管理員登錄
類(lèi)似不再貼代碼
四、前端UI實(shí)現(xiàn)
1.完成前端Html代碼的編寫(xiě)
不多說(shuō)
2.完成MVC項(xiàng)目中控制器和視圖的文件添加
這個(gè)只能手動(dòng)添加,不像VS有模板可用

3.復(fù)制網(wǎng)站的靜態(tài)資源
asp.net core 網(wǎng)站靜態(tài)資源都是放在wwwroot目錄的,并且文件名一般是小寫(xiě)。

4.在視圖中引用資源
MVC框架可以直接識(shí)別在wwwroot中的靜態(tài)資源,不用寫(xiě)顯示的寫(xiě)出目錄名。
<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.編寫(xiě)動(dòng)作方法
public IActionResult Index()
{
return View();
}
6.添加視圖

7.啟動(dòng)調(diào)試
首頁(yè)效果圖

8.視圖與控制器之間傳遞數(shù)據(jù)
使用ViewData
視圖的網(wǎng)頁(yè)標(biāo)題可以使用這種方式傳遞
public IActionResult Index()
{
ViewData["title"]="好運(yùn)來(lái)酒店";
ViewBag.list=new NewsManager().GetNews(4);
return View();
}
視圖中引用數(shù)據(jù)
<!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"]-舒適快捷經(jīng)濟(jì)</title> </head>
使用ViewBag
這是所謂的動(dòng)態(tài)類(lèi)型,直接無(wú)中生有造一個(gè)屬性
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"]="好運(yùn)來(lái)酒店";
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>
修改后的首頁(yè)

9.分部視圖
創(chuàng)建分部視圖
分部視圖的創(chuàng)建和其他視圖的創(chuàng)建沒(méi)有任何區(qū)別,只是它作為其他視圖的一部分來(lái)視圖用。
避免視圖代碼的重復(fù)。

在其他視圖中使用分部視圖
引用分部視圖使用特殊的標(biāo)簽 <partial name="..." />
@model List<News>
<div class="row">
<div class="col-md-4">
<partial name="../Shared/_LeftContentPartial.cshtml" />
</div>
<div class="col-md-8">
<div class="lefttitle righttitle">您現(xiàn)在所在的位置:中式餐廳酒店>新聞動(dòng)態(tài)</div>
<div class="bg-light">
@foreach (News item in @Model) {
<div class="d-flex flex-row justify-content-between">
<div class="p-2"><a href="NewsDetail?id=@item.Id" rel="external nofollow" >@item.NewsTitle</a></div>
<div class="p-2">@item.PublishTime.ToShortDateString()</div>
</div>
}
</div>
</div>
</div>
10.使用Section布局定義
@RenderSection("js",required:false)
使用
@section js{
<script type="text/javascript">
function changeFontSize(fontSize) {
//獲取要變化的對(duì)象
var divContent = $(".row .m-4");
divContent.css("font-size",fontSize);
}
</script>
}
11.表單驗(yàn)證
使用模型驗(yàn)證方式實(shí)現(xiàn)
添加驗(yàn)證特性
public partial class DishBook
{
public uint Id { get; set; }
public string HotelName { get; set; }
[Required(ErrorMessage = "{0}不能為空")]
[Display(Name = "消費(fèi)時(shí)間")]
public DateTime? ConsumeTime { get; set; }
[Required(ErrorMessage = "{0}不能為空")]
[RegularExpression(@"^\d+$", ErrorMessage = "請(qǐng)輸入正確的{0}")]
[Display(Name = "消費(fèi)人數(shù)")]
public uint? ConsumePersons { get; set; }
public string RoomType { get; set; }
[Required(ErrorMessage = "{0}不能為空")]
[RegularExpression(@"^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$", ErrorMessage = "請(qǐng)輸入正確的{0}")]
[Display(Name = "手機(jī)號(hào)碼")]
public string CustomerPhone { get; set; }
[Required(ErrorMessage = "{0}不能為空")]
[Display(Name = "姓名")]
public string CustomerName { get; set; }
[EmailAddress(ErrorMessage = "請(qǐng)輸入正確的{0}")]
[Display(Name = "電子郵件")]
public string CustomerEmail { get; set; }
public string Comments { get; set; }
public DateTime BookTime { get; set; }
public int? BookStatus { get; set; }
// 擴(kuò)展屬性
[Required(ErrorMessage = "{0}不能為空")]
[Remote(action:"CheckVcode",controller:"Dish")]
[Display(Name = "驗(yàn)證碼")]
public string ValidationCode { get; set; }
}
使用 Tag Helper 完成前端代碼編寫(xiě)
@model DishBook
@section js{
<partial name="../Shared/_ValidationScriptsPartial.cshtml" />
<script src="~/lib/My97DatePicker/WdatePicker.js"></script>
}
<div class="row">
<div class="col-md-4">
<partial name="../Shared/_DishPartial.cshtml" />
</div>
<div class="col-md-8">
<div class="lefttitle righttitle">您現(xiàn)在所在的位置:中式餐廳酒店>在線預(yù)訂</div>
<form class="bg-light p-3" asp-controller="Dish" asp-action="Booking" method="post">
<div class="form-group">
<label for="HotelName">酒店名稱(chēng):</label>
<select class="form-control w-25" name="HotelName">
<option value="天津南開(kāi)店">天津南開(kāi)店</option>
<option value="天津和平店">天津和平店</option>
<option value="北京朝陽(yáng)店">北京朝陽(yáng)店</option>
</select>
</div>
<div class="form-group">
<span><label asp-for="ConsumeTime"></label> :</span>
<div class="d-flex flex-row align-items-center">
<input class="form-control w-50" asp-for="ConsumeTime" onclick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss'})">
<span class="p-2 text-danger">*</span>
<span asp-validation-for="ConsumeTime"></span>
</div>
</div>
<div class="form-group">
<span><label asp-for="ConsumePersons"></label>:</span>
<div class="d-flex flex-row align-items-center">
<input class="form-control w-50" type="text" asp-for="ConsumePersons">
<span class="p-2 text-danger text-center">*</span>
<span asp-validation-for="ConsumePersons"></span>
</div>
</div>
<div class="form-group">
<label for="RoomType"> 選擇包間類(lèi)型: </label>
<select class="form-control w-25" name="RoomType">
<option value="包間">包間</option>
<option value="散座">散座</option>
</select>
</div>
<div class="form-group">
<span>您的<label asp-for="CustomerName"></label>:</span>
<div class="d-flex flex-row align-items-center">
<input class="form-control w-50" asp-for="CustomerName">
<span class="p-2 text-danger text-center">*</span>
<span asp-validation-for="CustomerName"></span>
</div>
</div>
<div class="form-group">
<span><label asp-for="CustomerPhone"></label>:</span>
<div class="d-flex flex-row align-items-center">
<input class="form-control w-50" asp-for="CustomerPhone">
<span class="p-2 text-danger text-center">*</span>
<span asp-validation-for="CustomerPhone"></span>
</div>
</div>
<div class="form-group">
<span><label asp-for="CustomerEmail"></label>:</span>
<div class="d-flex flex-row align-items-center">
<input class="form-control w-50" asp-for="CustomerEmail">
<span asp-validation-for="CustomerEmail"></span>
</div>
</div>
<div class="form-group">
<label for="Comments"> 備注事項(xiàng): </label>
<textarea class="form-control" cols="20" name="Comments" rows="4" placeholder="備注"></textarea>
</div>
<div class="form-group">
<span><label asp-for="ValidationCode"></label>:</span>
<div class="d-flex flex-row align-items-center">
<input class="form-control w-50" asp-for="ValidationCode">
<span class="p-2 text-danger text-center">*</span>
<span asp-validation-for="ValidationCode"></span>
</div>
</div>
<div class="form-group">
<img alt="驗(yàn)證碼圖片" title="看不清?點(diǎn)擊換一個(gè)" src='@Url.Action("ValidationCode","Dish")' onclick="this.src=this.src+'?'" />
</div>
<div class="form-group">
<input class="btn btn-success" type="submit" value="馬上預(yù)定" />
</div>
</form>
</div>
</div>
引入jQuery驗(yàn)證插件
這個(gè)是插件MVC項(xiàng)目時(shí),模板自動(dòng)生成的
@section js{
<partial name="../Shared/_ValidationScriptsPartial.cshtml" />
<script src="~/lib/My97DatePicker/WdatePicker.js"></script>
}

Tag Helper自動(dòng)根據(jù)數(shù)據(jù)類(lèi)型生成對(duì)應(yīng)的輸入框類(lèi)型
可以手動(dòng)設(shè)置 type 來(lái)覆蓋

驗(yàn)證碼提交到服務(wù)器驗(yàn)證
使用 [Remote] 特性
詳細(xì)文檔參考:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-3.1
The jQuery Validate remote method expects a JSON response:
- true means the input data is valid.
- false, undefined, or null means the input is invalid. Display the default error message.
- Any other string means the input is invalid. Display the string as a custom error message.
注意:The [Remote] attribute is in the Microsoft.AspNetCore.Mvc namespace.
五、使用區(qū)域項(xiàng)目完成后臺(tái)管理系統(tǒng)
1.創(chuàng)建區(qū)域項(xiàng)目
建立區(qū)域項(xiàng)目目錄結(jié)構(gòu)
- Project name
Areas
Admin //分區(qū)項(xiàng)目1
Controllers
Views
Services //分區(qū)項(xiàng)目2
Controllers
Views
添加路由規(guī)則
在Startup.cs文件中添加區(qū)域項(xiàng)目路由規(guī)則
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "Admin",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"
);
});
測(cè)試頁(yè)面
如果有和主項(xiàng)目同名的控制器使用區(qū)域特性區(qū)分
using Microsoft.AspNetCore.Mvc;
namespace HotelWebMVC.Areas.Admin.Controllers
{
[Area("Admin")]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Welcome()
{
ViewData["Message"] = "Your welcome message";
return View();
}
}
}
如果不打區(qū)域標(biāo)記區(qū)分,啟動(dòng)項(xiàng)目會(huì)包錯(cuò)。
2.使用Cookie保存登錄憑證
添加依賴(lài)包
dotnet add package Microsoft.AspNetCore.Authentication.Cookies
配置服務(wù)
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromSeconds(300);
options.Cookie.HttpOnly = true;
// Make the session cookie essential
options.Cookie.IsEssential = true;
});
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options=>{
options.Cookie.HttpOnly=true;
options.ExpireTimeSpan=TimeSpan.FromMinutes(5);
options.LoginPath="/admin";
// options.AccessDeniedPath="/403.html";
}
);
string connString = Configuration.GetConnectionString("HotelWeb");
services.AddDbContext<DAL.HotelWebDbContext>(options => options.UseMySql(connString, x => x.ServerVersion("5.5.64-mariadb")));
}
啟用認(rèn)證服務(wù)添加的位置有要求:必須在app.UseRouting 和 app.UseEndpoints 之間。
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "admin",
pattern: "{area:exists}/{controller=SysAdmin}/{action=Index}/{id?}"
);
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
登錄成功后簽發(fā)憑證
using System.Security.Claims; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies;
List<Claim> claims = new List<Claim>() { new Claim("username", admin.LoginName) };
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
AuthenticationProperties properties = new AuthenticationProperties()
{
IsPersistent = true
};
await HttpContext.SignInAsync
(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
properties
);
其他需登錄后才能訪問(wèn)的資源,在控制器上添加 [Authorize]標(biāo)記
[Authorize]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Welcome()
{
ViewData["Message"] = "Your welcome message";
return View();
}
}
3.使用ajax提交表單
在dotnet core 中不再支持@Ajax.Form方式,而是使用jquery插件的方式支持了。
通過(guò)定義data-* 屬性來(lái)支持類(lèi)似的功能
和Ajax助手的對(duì)照
====================================================== AjaxOptions HTML attribute ====================================================== Confirm data-ajax-confirm HttpMethod data-ajax-method InsertionMode data-ajax-mode LoadingElementDuration data-ajax-loading-duration LoadingElementId data-ajax-loading OnBegin data-ajax-begin OnComplete data-ajax-complete OnFailure data-ajax-failure OnSuccess data-ajax-success UpdateTargetId data-ajax-update Url data-ajax-url ======================================================
這個(gè)特性只能在form和a標(biāo)簽上起作用
使用方法:
①下載插件并引用到項(xiàng)目中
地址:https://github.com/aspnet/jquery-ajax-unobtrusive/releases
將src文件夾中的js文件拷貝到項(xiàng)目對(duì)應(yīng)的存放位置
②編寫(xiě)需要的js函數(shù)
編寫(xiě)回調(diào)函數(shù)
<script>
var onSuccess=function(data){
alert(data);
$("#mainForm")[0].reset();
dishImg.src = "/images/default.png";
};
var onFailed=function(data){
alert(data);
};
</script>
③使用data屬性改寫(xiě)標(biāo)簽
這里注意:要使用ajax提交表單,data-ajax="true"必須要設(shè)置為true。
data-ajax-confirm=“確認(rèn)要提交嗎?” 這里是彈出框的內(nèi)容,不是具體的函數(shù)名
data-ajax-begin
data-ajax-complete
data-ajax-failure
data-ajax-success
這些屬性值就是回調(diào)函數(shù)的名稱(chēng)。
4.CKeditor使用
推薦使用ckeditor4,因?yàn)?版本中文輸入有問(wèn)題。
使用步驟:
下載編輯器的軟件包
在頁(yè)面中引入它的js腳本
<script src="../../third_files/ckeditor4/ckeditor.js"></script>
使用texterea作為目標(biāo)
編輯器的高度可以config.js文件中設(shè)置
<textarea id="editor" name="editor" rows="20"></textarea>
在js中創(chuàng)建
<script> CKEDITOR.replace( 'editor' ); </script>
自定義配置
修改配置文件config.js,推薦直接在默認(rèn)的文件中添加需要的配置。
CKEDITOR.editorConfig = function( config ) {
config.language = 'es';
config.uiColor = '#F7B42C';
config.height = 300;
config.toolbarCanCollapse = true;
};
獲取編輯器的內(nèi)容
用于提交前驗(yàn)證是否有內(nèi)容,NewsContent是編輯器textarea的id
var content=CKEDITOR.instances.NewsContent.getData();
注意此時(shí)數(shù)據(jù)驗(yàn)證通過(guò),使用js提交表單的話(huà),編輯器并沒(méi)有替換原來(lái)的內(nèi)容,需要手動(dòng)替換
$("#NewsContent").html(content);
不然提交到控制器中是沒(méi)有值的。
var onSubmit=function(){
var content=CKEDITOR.instances.NewsContent.getData();
if(content==""){
alert("新聞內(nèi)容不能為空");
}
else{
$("#NewsContent").html(content);
$("#mainForm").submit();
}
}
清空編輯器的內(nèi)容
CKEDITOR.instances.NewsContent.setData("");
In rare cases it may happen that the server or application configuration
will reject submitted HTML content if it is not encoded first (e.g. ASP.NET ValidateRequest).
In such case check the config.htmlEncodeOutput option.
config.htmlEncodeOutput = true;
上傳圖片設(shè)置
需要外部插件:file browser,popup,filetools
配置config.js文件
config.filebrowserBrowseUrl = ‘/browser/browse.php'; config.filebrowserUploadUrl = ‘/uploader/upload.php';
控制器中的參數(shù)使用 (IFormFile upload) 使用的是upload的參數(shù)名。
如何給一個(gè)響應(yīng),放棄不用這個(gè),使用filebrowserBrowseUrl這個(gè)功能,里面也有上傳
具體方法是:
- 構(gòu)建一個(gè)圖片上傳和瀏覽的頁(yè)面
- 完成圖片上傳功能
- 圖片選裝功能
響應(yīng)的js代碼如下:
<script>
// Helper function to get parameters from the query string.
function getUrlParam( paramName ) {
var reParam = new RegExp( '(?:[\?&]|&)' + paramName + '=([^&]+)', 'i' );
var match = window.location.search.match( reParam );
return ( match && match.length > 1 ) ? match[1] : null;
}
var upload=function(){
var file=$(".btnUpload>input")[0].files[0];
if(file==null){
alert("請(qǐng)選擇上傳圖片");
}
else{
var formData=new FormData();
formData.append("upload",file);
// 實(shí)例化一個(gè)AJAX對(duì)象
var xhr = new XMLHttpRequest();
xhr.onload = function() {
$(".border3").first().before('<div class="w-25 p-3 border3"><span class="d-inline-block"><h3><span class="badge badge-info rotated">new</span></h3><img class="img-thumbnail" src="/images/news/'+xhr.responseText+'" onclick="select(this)"></span><div class="text-center p-2">'+xhr.responseText+'</div></div>');
}
xhr.open("post",'@Url.Action("UploadImage","News")',true);
// 發(fā)送表單數(shù)據(jù)
xhr.send(formData);
}
}
var selectedImg=null;
var select=function(img){
if(selectedImg!=null){
selectedImg.parents(".border3").removeClass("selected");
}
selectedImg=$(img);
selectedImg.parents(".border3").addClass("selected");
}
var choose=function(){
if(selectedImg!=null){
var funcNum = getUrlParam( 'CKEditorFuncNum' );
var fileUrl = selectedImg.attr("src");
window.opener.CKEDITOR.tools.callFunction( funcNum, fileUrl );
window.close();
}
else{
alert("請(qǐng)選裝圖片");
}
}
</script>

5.其他功能省略代碼
六、使用依賴(lài)注入改進(jìn)項(xiàng)目
1.抽取接口
通過(guò)vs來(lái)抽取接口,效率高。
2.重新組織項(xiàng)目結(jié)構(gòu)
新增IDAL、IBLL、DBUtility
UI–>IBLL–>IDAL–>Models
BLL–>IBLL、IDAL
IDAL–>Models
DAL–>IDAL、DBUtility

3.注冊(cè)依賴(lài)服務(wù)
public void ConfigureServices(IServiceCollection services)
{
//其他代碼省略了
...
services.AddDbContext<DBUtility.HotelWebDbContext>(
options => options.UseMySql(
Configuration.GetConnectionString("HotelWeb"),
x => x.ServerVersion("5.5.64-mariadb")
)
);
services.AddTransient<INewsManager, NewsManager>();
services.AddTransient<IDishManager, DishManager>();
services.AddTransient<IDishBookManager, DishBookManager>();
services.AddTransient<ISuggestionManager, SuggestionManager>();
services.AddTransient<IRecruitmentManager, RecruitmentManager>();
services.AddTransient<ISysAdminManager, SysAdminManager>();
services.AddTransient<INewsService,NewsService>();
services.AddTransient<IDishService,DishService>();
services.AddTransient<IDishBookService,DishBookService>();
services.AddTransient<ISuggestionService,SuggestionService>();
services.AddTransient<IRecruitmentService,RecruitmentService>();
services.AddTransient<ISysAdminService,SysAdminService>();
}
4.修改代碼使用依賴(lài)注入
public class HomeController : Controller
{
private readonly INewsManager newsManager;
private readonly ISuggestionManager suggestionManager;
private readonly IRecruitmentManager recruitmentManager;
public HomeController(
INewsManager newsManager,
ISuggestionManager suggestionManager,
IRecruitmentManager recruitmentManager)
{
this.newsManager = newsManager;
this.suggestionManager = suggestionManager;
this.recruitmentManager = recruitmentManager;
}
// ...
}
5.測(cè)試
啟動(dòng)項(xiàng)目也沒(méi)有什么問(wèn)題
七、項(xiàng)目發(fā)布
1.項(xiàng)目配置
dotnet core 中沒(méi)有Web.conf文件了。
查看文檔,都是通過(guò)Startup.cs中配置項(xiàng)目的。
暫時(shí)放棄配置。
2.命令行發(fā)布項(xiàng)目
CLI 提供了發(fā)布項(xiàng)目的相關(guān)命令
dotnet publish -c Release --no-self-contained -o /path/to/save/project/
3.另一種方式使用vs發(fā)布
很簡(jiǎn)單,下一步下一步做就好了。
八、通過(guò)Nginx部署到Linux服務(wù)器
1.在Centos7 上安裝運(yùn)行時(shí)
Register Microsoft key and feed
sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
Install the ASP.NET Core runtime
sudo yum install dotnet-sdk-3.1
2.安裝libgdiplus
因?yàn)轫?xiàng)目中使用驗(yàn)證碼,需要用到這個(gè)命名空間:System.Drawing.Common
速度太慢,放棄。
3.將項(xiàng)目目錄上傳到linux
使用xshell 的ftp 輕松完成。

4.測(cè)試項(xiàng)目是否運(yùn)行
cd /var/www/HotelWeb/ dotnet HotelWeb.dll [root@centos7 HotelWeb]# dotnet HotelWebMVC.dll info: Microsoft.Hosting.Lifetime[0] Now listening on: http://localhost:5000 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Production info: Microsoft.Hosting.Lifetime[0] Content root path: /var/www/HotelWeb
5.安裝Nginx并配置
yum install nginx
vim /etc/nginx/nginx.conf
---------------
# 刪除nginx默認(rèn)的server,添加下面兩個(gè)
server {
listen 80 default_server;
return 444;
}
server {
listen 80;
server_name *.hotel.com;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
----------------
6.啟動(dòng)nginx
systemctl start nginx nginx -t # 配置確認(rèn)沒(méi)有問(wèn)題后,重新載入配置 nginx -s reload
7.瀏覽器測(cè)試
修改win7的host
www.hotel.com 192.168.30.110

8.最后的問(wèn)題
因?yàn)閘ibgdiplus這個(gè)庫(kù)沒(méi)有安裝,所以進(jìn)入驗(yàn)證碼的頁(yè)面會(huì)有報(bào)錯(cuò)。
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.TypeInitializationException: The type initializer for 'Gdip' threw an exception.
---> System.DllNotFoundException: Unable to load shared library 'libgdiplus' or one of its dependencies.
9.修改dotnet監(jiān)聽(tīng)端口
在Program.cs 文件中修改
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 5000);
})
.UseStartup<Startup>();
});
}
修改后
[root@centos7 HotelWeb]# dotnet HotelWebMVC.dll info: Microsoft.Hosting.Lifetime[0] Now listening on: http://0.0.0.0:5000 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Production info: Microsoft.Hosting.Lifetime[0] Content root path: /var/www/HotelWeb [root@centos7 ~]# ss -tna State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:5000 *:* LISTEN 0 50 *:3306 *:* LISTEN 0 128 *:111 *:* LISTEN 0 128 *:80 *:* LISTEN 0 128 *:22 *:* LISTEN 0 100 127.0.0.1:25 *:* ESTAB 0 0 192.168.30.110:22 192.168.30.88:1581 ESTAB 0 52 192.168.30.110:22 192.168.30.88:1516 LISTEN 0 128 :::111 :::* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::*
參考文檔
Entity Framework Core tools reference - .NET CLI
Using a Separate Migrations Project
Model validation in ASP.NET Core MVC
Use cookie authentication without ASP.NET Core Identity
Dependency injection in ASP.NET Core
CentOS 7 Package Manager - Install .NET Core
Add the Mono repository to your system
到此這篇關(guān)于基于.NET Core 3.1 網(wǎng)站開(kāi)發(fā)和部署的方法的文章就介紹到這了,更多相關(guān).NET Core 3.1 網(wǎng)站開(kāi)發(fā)部署內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
.net通過(guò)Action進(jìn)行Options參數(shù)的傳遞的方法
在.NET Core中,使用Action和Options參數(shù)方式配置服務(wù)并將配置信息對(duì)象注冊(cè)到IServiceCollection的好處在于,它提供了更高級(jí)別的可配置性和可擴(kuò)展性,這篇文章主要介紹了.net通過(guò)Action進(jìn)行Options參數(shù)的傳遞,你知道是怎么實(shí)現(xiàn)的嗎,需要的朋友可以參考下2023-12-12
ASP.NET Core讀取Request.Body的正確方法
相信大家在使用ASP.NET Core進(jìn)行開(kāi)發(fā)的時(shí)候,肯定會(huì)涉及到讀取Request.Body的場(chǎng)景,畢竟我們大部分的POST請(qǐng)求都是將數(shù)據(jù)存放到Http的Body當(dāng)中,本文就介紹一下ASP.NET Core讀取Request.Body,感興趣的可以了解一下2021-05-05
ASP.NET Core SignalR中的流式傳輸深入講解
這篇文章主要給大家介紹了關(guān)于ASP.NET Core SignalR中流式傳輸?shù)南嚓P(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
ASP.NET使用xslt將xml轉(zhuǎn)換成Excel
本文介紹利用Excel軟件生成格式,提取和精簡(jiǎn)之后制作成xslt文件,將xml導(dǎo)入,以xslt為模板,生成新的Excel文件的過(guò)程。2016-05-05
asp.net 將一個(gè)圖片以二進(jìn)制值的形式存入Xml文件中的實(shí)例代碼
這篇文章介紹了將一個(gè)圖片以二進(jìn)制值的形式存入Xml文件中的實(shí)例代碼,有需要的朋友可以參考一下2013-07-07
asp.net+Ligerui實(shí)現(xiàn)grid導(dǎo)出Excel和Word的方法
這篇文章主要介紹了asp.net+Ligerui實(shí)現(xiàn)grid導(dǎo)出Excel和Word的方法,實(shí)例分析了asp.net結(jié)合jQuery的Ligerui插件操作excel和word文件的技巧,需要的朋友可以參考下2016-04-04
ASP.NET Core中的依賴(lài)問(wèn)題解決方法示例
這篇文章主要為大家介紹了ASP.NET Core中的依賴(lài)問(wèn)題解決方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
asp.net轉(zhuǎn)出json格式客戶(hù)端顯示時(shí)間
最近在學(xué)習(xí)ext過(guò)程中,很多地方的數(shù)據(jù)從服務(wù)器傳到客戶(hù)端都是以json格式傳回來(lái)2008-10-10

