项目改造建议:在将项目改成.net core之前,一定要先学习,不然很容易踩坑,导致项目进度变慢,.net core和asp.net mvc有很大区别
学习地址
https://docs.microsoft.com/zh-cn/aspnet/core/migration/mvc?view=aspnetcore-2.2
https://www.bilibili.com/video/av38392956/?p=8 强烈推荐
https://www.yuque.com/yuejiangliu/dotnet/solenovex-core-mvc-comp
https://www.cnblogs.com/chillsrc/p/10509412.html
https://ken.io/note/asp.net-core-tutorial-mvc-view-layout-section
项目发布到网站:
https://www.cnblogs.com/craigtaylor/p/11143484.html
https://www.cnblogs.com/humin/p/10330983.html
快速开发技巧:
自动生成构造函数,在类下输入ctor+tab键按两下
方法里面参数自动生成属性,写完参数后,按ctrl+.,会弹出提示,然后选择后回车即可
在非div元素处鼠标右键,使用<div>换行,会在元素前后加上div标签
1、后台使用 HtmlEncoder.Default.Encode 防止恶意输入(即 JavaScript)损害应用
防止重复提交常用办法:post-redirect-get,RedirectToAction(nameOf(Detail)),使用nameOf利于重构
2、项目安装mysql的ef支持
MySql.Data.EntityFrameworkCore、Microsoft.EntityFrameworkCore.Tools、Microsoft.EntityFrameworkCore.Proxies(延时加载)
使用Pomelo.EntityFrameworkCore.MySql替代MySql.Data.EntityFrameworkCore,因为efcore操作mysql时,出现错误System.InvalidOperationException:“No coercion operator is defined between types 'System.Int16' and 'System.Boolean'.”
Sql Server 请安装 Microsoft.EntityFrameworkCore.SqlServer
3、netcore项目支持依赖注入,nuget添加Microsoft.Extensions.DependencyInjection https://stackoverflow.com/questions/32459670/resolving-instances-with-asp-net-core-di
4、efcore配置(配置 DbContext、连接字符串等)https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/connection-strings
5、设置级联删除https://www.jianshu.com/p/39da9b023c81
6、目前针对dotnet core项目的nuget包,还不支持执行包里的代码模板和识别Content内容,所以暂时无法实现(不能通过nuget获取js库或者css第三方库,使用vs自带libman最方便)
详情参考 https://docs.microsoft.com/zh-cn/nuget/create-packages/project-json-impact
(6.1)、Bower 的安装,JS包默认安装到webroot的lib文件夹,可以通过.bowerrc文件更改安装路径(不推荐使用,会将很多无用的js和文件下载到项目中)
https://blog.csdn.net/qq_33303204/article/details/81323512
https://www.cnblogs.com/wanghaibin/p/9116816.html
https://www.cnblogs.com/beginfromnow/p/6883747.html
在安装 Bower 前,请安装它的以下依赖组件nodejs、git
安装完成后打开 CMD 执行以下语句在全局中安装 Bower:npm install -g bower
安装完成后可执行以下命令验证是否安装成功:bower -v
在 Visual Studio 中建立 ASP.NET Core Web 应用程序。
首先你可以看到依赖项内没有 Bower 管理,在项目右键也发现无管理 Bower 程序包选项。
此时我们打开 CMD。切换到项目目录内(包含 *.csproj 的文件夹)。输入以下命令初始化 Bower (请不要使用 PowerShell ):
bower init
在vs项目下.bowerrc文件,配置外部工具中一定要去除$(VSInstalledExternalTools)或$(VSINSTALLDIR)\Web\External勾选,不然不能下载或更新文件到wwwroot/lib中
(6.2)、使用LibMan添加依赖js和css库,强烈推荐使用此种方法添加js和css库
https://docs.microsoft.com/zh-cn/aspnet/core/client-side/libman/libman-vs?view=aspnetcore-2.2
https://blog.csdn.net/qq_22949043/article/details/86766808
手动还原文件
若要手动还原库文件:
对于解决方案中的所有项目:
右键单击解决方案的名称解决方案资源管理器。
选择还原客户端库选项。
对于特定的项目:
右键单击libman.json中的文件解决方案资源管理器。
选择还原客户端库选项。
如果添加客户端库时选择提供程序为unpkg,必须输入完下载的框架后,然后@版本号才有提示
添加jquery.validate.js等库,搜索使用jquery-validate、jquery-validation-unobtrusive
(6.3)、配置使用npm文件安装目录node_modules像wwwroot目录一样可以使用静态文件
在Startup.cs中加入如下代码
app.UseStaticFiles(new StaticFileOptions
{
RequestPath = "/node_modules",
FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath,"/node_modules"))
});
//使用<link href="~/node_modules/bootstrap/bootstrap.css">
7、efcore ef code first自动迁移,需要自动在数据库中新建表
CREATE TABLE __EFMigrationsHistory ( MigrationId nvarchar(150) NOT NULL, ProductVersion nvarchar(32) NOT NULL, PRIMARY KEY (`MigrationId`) ); end;
8、ef core操作mysql 数据迁移需要导入Microsoft.EntityFrameworkCore.Design,版本是2.0.0;
https://www.cnblogs.com/whyd/p/9348325.html
https://www.cnblogs.com/Saumterer/p/7605340.html
9、ef code first一对多配置:https://blog.csdn.net/Fanbin168/article/details/81745861
10、执行数据库迁移命令时,提示不支持PowerShell 2.0版本(don't support PowerShell version 2.0. )解决
https://www.bbsmax.com/A/6pdDBl6DJw 非常好
https://www.cnblogs.com/systemnet123/p/10262096.html
http://www.mamicode.com/info-detail-2584332.html
Add-Migration Xxxx,每次增加或修改类后,都要重新执行此命令
Update-Database -v 马上同步本地数据库,不适合正式环境
当执行以上命令时,如果出现错误Build failed,选中项目解决方案-》右键-》重新生成解决方案,看下项目是否有报错的地方,当重新生成成功后,一般就可以执行了,如果还是不行,参考https://www.cnblogs.com/DHclly/p/11332591.html
11、Startup.cs取代Global.asax,Startup类负责处理所有应用程序启动任务
BundleConfig.cs在asp.net core里面不存了,安装Bundler & Minifier工具替代
要引用處理完的指令碼檔,在過去是使用 @Scripts.Render() 或 @Styles.Render() 將指令碼檔加入到網頁之中,現在只要在引用打包完後的指令碼檔時,加一個屬性叫 asp-append-version 的 TagHelper,把它設定為 true 就可以了。
https://dotblogs.com.tw/supershowwei/2017/07/26/164153
https://dotnetthoughts.net/bundling-and-minification-in-aspnet-core/
https://marketplace.visualstudio.com/items?itemName=MadsKristensen.BundlerMinifier
https://www.cnblogs.com/yunspider/p/9746555.html
12、Razor指令可以根据规则从 HTML 转换为 C# 或 Razor 特定标记。 当在 @ 符号后跟 Razor 保留关键字时,它会转换为 Razor 特定标记,如果不是Razor保留关键字,则会转换为 C#。
@page Razor 指令将文件转换为一个 MVC 操作,这意味着它可以处理请求。 @page 必须是页面上的第一个 Razor 指令。 @page 是转换成 Razor 特定标记的一个示例。
13、mvc模板页使用:@RenderSection("header", false)
@RenderBody()
@RenderSection("Scripts", required: false)//required: false表示不是必须的
子页面:@section header
{}
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
https://ken.io/note/asp.net-core-tutorial-mvc-view-layout-section
14、页面文件介绍
_layout.cshtml文件中包含通用的HTML元素(脚本和样式表)和应用程序的总体布局。例如,当你点击RazorMvcBooks,Home,About的链接时,你会看到同样的页眉与页脚布局。
_viewstart.cshtml文件当作_layout.cshtml文件的布局属性来使用。可以放公用html
_viewimports.cshtml包含导入到每个Razor页面的Razor指令。
_validationscriptspartial.cshtml文件提供对jQuery验证脚本的引用。当我们添加创建和编辑网页时,_validationscriptspartial.cshtml文件将被使用。
@Html.PartialAsync("_PartialViewName",data):复用View代码,@Html.Partial()未旧方法或使用
使用<partial name="_StudentRow" for="@s">替换@Html.Partial
@await Commponent.InvokeAsync("XXX"):可复用、独立组件、有独立的逻辑/数据、相当于迷你mvc请求、不依赖于父级View的数据,通常放到ViewComponents文件夹下
taghelper对于写法<vc:welcome></vc:welcome>,必须在_ViewImports.cshtml导入当前项目命名空间才能使用
15、@Html.使用TagHelper替换,asp-开头都是taghelper,asp-action、asp-controller、asp-route-id、asp-route-name、asp-for、asp-items、asp-validation-for
_ViewImports.cshtml
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<select asp-for="Gender" asp-items="Html.GetEnumSelectList<Gender>()"></select>
<span asp-validation-for="birthdate"></span>
<span asp-validation-summary="All"></span> 模型错误汇总显示
<span asp-validation-summary="ModelOnly"></span> ModelState.AddModelError()添加的错误才会显示
16、获取控制器和action名称
this.ControllerContext.ActionDescriptor.ControllerName
this.ControllerContext.ActionDescriptor.ActionName
17、.net core Identity用户登录使用
核心对象UserManager<IdentityUser>、SignInManager<IdentityUser>、RoleManager<IdentityRole>
使用在Startup.cs中配置
string connectionString = Configuration.GetConnectionString("MysqlConnection");
//注册数据库上下文
services.AddDbContext<Data.NBSharpDbContext>(options => options.UseMySql(connectionString));
//注册Identity
services.AddDbContext<IdentityDbContext>(options => options.UseMySql(connectionString));
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 1;
}).AddEntityFrameworkStores<IdentityDbContext>();
app.UseAuthentication();//全局身份认证,必须放在app.UseMvc()之前
执行数据库迁移Add-migration InitIdentity -Context IdentityDbContext
//页面中判断是否登录@if(SignInManager.IsSignedIn(User)){...}
//Controller用户登录才能访问,再Controller或Action上加上[Authorize]即可
18、页面中使用注入对象@inject SignInManager<IdentityUser> SignInManager
SignInManager为变量名
19、mvp提供增删改查参考https://github.com/solenovex/ASP.NET-Core-MVC-Tutorial-Code
RoleController AddUserToRole()中代码应该调整为
// 使用SQL语句的方式实现
// 方法一、推荐,先查所有用户,再查角色的用户,然后在内存中排除
// 所有用户
var users = await _userManager.Users*************);
// 当前角色包含的用户
var users2 = await _userManager.Users.FromSql(
"select u.* from AspNetUsers u, AspNetUserRoles r where u.Id = r.UserId and r.RoleId = @roleId ",
new SqlParameter("@roleId", roleId))*************);
// 添加当前角色不包含的用户
vm.Users.AddRange(users.Where(u => users2.Contains(u) == false));
// 方法二、不推荐,直接使用 not in语句
//vm.Users.AddRange(await _userManager.Users.FromSql(
// "select u.* from AspNetUsers u where u.Id not in (select UserId from AspNetUserRoles where RoleId = {0})",
// roleId)*************));
20、.net-core的api接口不再返回HttpResponseMessage,返回和mvc控制层一样、可以是JsonResult、void、string等待
21、.net-core里面使用HttpContext对象
public class xxxAppService : PlatformAppService { private readonly IHttpContextAccessor httpContextAccessor; public xxxAppService(IHttpContextAccessor _httpContextAccessor) { httpContextAccessor = _httpContextAccessor; } public async Task<string> GetHeaders() { var headers = httpContextAccessor.HttpContext.Request.Headers; return headers["Authorization"]; } }
22、.netcore中使用HttpContext对象 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-2.2
23、.netcore执行sql查询 语句https://docs.microsoft.com/zh-cn/ef/core/querying/raw-sql
默认生成的为Person的Model,如果Select获取的字段中不包含Person中的某字段就会抛异常了,例如:下面的语句只获取name字段,并没有包含Person的其他字段,那么抛异常:The required column 'id' was not present in the results of a 'FromSql' operation.
db.Set<Person>().FromSql($"select name from {nameof(Person)} ").ToList(); 那么改为: db.Set<Person>().Select(l => l.name).FromSql($"select name from {nameof(Person)} ").ToList();
.net core项目重命名后错误解决: