概述 
ASP.NET Core 
ASP.NET 4.x 
 
 
针对 Windows、macOS 或 Linux 进行生成 
针对 Windows 进行生成 
 
Razor 页面 是在 ASP.NET Core 2.x 及更高版本中创建 Web UI 时建议使用的方法。 
使用 Web 窗体、SignalR、MVC、Web API、WebHooks 或网页 
 
每个计算机多个版本 
每个计算机一个版本 
 
使用 C# 或 F# 通过 Visual Studio、Visual Studio for Mac 或 Visual Studio Code 进行开发 
使用 C#、VB 或 F# 通过 Visual Studio 进行开发 
 
比 ASP.NET 4.x 性能更高 
良好的性能 
 
选择 .NET Framework 或 .NET Core 运行时 
使用 .NET Framework 运行时 
 
基础知识 依赖注入 概述 
使用接口抽象化依赖关系实现。 
注册服务容器中的依赖关系,ASP.NET Core 提供了一个内置的服务容器 IServiceProvider,服务已在应用的 Startup.ConfigureServices 方法中注册。 
将服务注入到使用它的类的构造函数中,框架负责创建依赖关系的实例,并在不再需要时对其进行处理。 
 
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public  interface  IMyDependency {     Task WriteMessage (string  message ) ; } public  class  MyDependency  : IMyDependency {     private  readonly  ILogger<MyDependency> _logger;     public  MyDependency (ILogger<MyDependency> logger )      {        _logger = logger;     }     public  Task WriteMessage (string  message )      {        _logger.LogInformation(             "MyDependency.WriteMessage called. Message: {MESSAGE}" ,              message);         return  Task.FromResult(0 );     } } public  void  ConfigureServices (IServiceCollection services ) {    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);     services.AddScoped<IMyDependency, MyDependency>();     services.AddTransient<IOperationTransient, Operation>();     services.AddScoped<IOperationScoped, Operation>();     services.AddSingleton<IOperationSingleton, Operation>();     services.AddSingleton<IOperationSingletonInstance>(new  Operation(Guid.Empty));          services.AddTransient<OperationService, OperationService>(); } 
 
MyDependency 在其构造函数中请求 ILogger,以链式方式使用依赖关系注入并不罕见,每个请求的依赖关系相应地请求其自己的依赖关系,容器解析图中的依赖关系并返回完全解析的服务。 
服务生存期 暂时 暂时生存期服务是每次从服务容器进行请求时创建的,这种生存期适合轻量级、无状态的服务。
作用域(Scoped) 作用域生存期服务以每个客户端请求(连接)一次的方式创建。
警告:在中间件内使用有作用域的服务时,请将该服务注入至 Invoke 或 InvokeAsync 方法,请不要通过构造函数注入进行注入,因为它会强制服务的行为与单一实例类似。
单例 单一实例生存期服务是在第一次请求时(或者在运行 ConfigureServices 并且使用服务注册指定实例时)创建的,每个后续请求都使用相同的实例,如果应用需要单一实例行为,建议允许服务容器管理服务的生存期,不要实现单一实例设计模式并提供用户代码来管理对象在类中的生存期。
警告:从单一实例解析有作用域的服务很危险,当处理后续请求时,它可能会导致服务处于不正确的状态。
Razor页面 入门 1 2 3 4 5 6 7 8 9 10 11 #  新建Razor页面项目 $  dotnet new webapp -o RazorPagesMovie #  本地部署 $  dotnet run #  输出 : Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]       User profile is available. Using '/home/hearing/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest. Hosting environment: Development Content root path: /home/hearing/WorkSpace/asp/hello Now listening on: https://localhost:5001 Now listening on: http://localhost:5000 
 
项目文件:
Pages 文件夹:包含 Razor 页面和支持文件。 每个 Razor 页面都是一对文件:
一个 .cshtml 文件,其中包含使用 Razor 语法的 C# 代码的 HTML 标记。 
一个 .cshtml.cs 文件,其中包含处理页面事件的 C# 代码。 
支持文件的名称以下划线开头。例如,_Layout.cshtml 文件可配置所有页面通用的 UI 元素。 此文件设置页面顶部的导航菜单和页面底部的版权声明。 
 
 
wwwroot文件夹:包含静态文件,如 HTML 文件、JavaScript 文件和 CSS 文件。 
appsettings.json:包含配置数据,如连接字符串。 
Program.cs:包含程序的入口点。 
Startup.cs:包含配置应用行为的代码,例如,是否需要同意 cookie。 有关更多信息,请参见ASP.NET Core 中的应用启动。 
 
MVC 入门 1 2 3 4 5 6 7 8 9 10 11 #  新建Razor页面项目 $  dotnet new mvc -o MvcHello #  本地部署 $  dotnet run #  输出 : Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]       User profile is available. Using '/home/hearing/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest. Hosting environment: Development Content root path: /home/hearing/WorkSpace/asp/MvcHello Now listening on: https://localhost:5001 Now listening on: http://localhost:5000 
 
目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 MvcHello ├── appsettings.Development.json ├── appsettings.json ├── bin │   └── Debug │       └── netcoreapp2.2 ├── Controllers │   ├── HelloWorldController.cs │   └── HomeController.cs ├── Models │   └── ErrorViewModel.cs ├── MvcHello.csproj ├── obj │   ├── Debug │   │   └── netcoreapp2.2 │   ├── MvcHello.csproj.nuget.cache │   ├── MvcHello.csproj.nuget.dgspec.json │   ├── MvcHello.csproj.nuget.g.props │   ├── MvcHello.csproj.nuget.g.targets │   └── project.assets.json ├── Program.cs ├── Properties │   └── launchSettings.json ├── Startup.cs ├── Views │   ├── Home │   │   ├── Index.cshtml │   │   └── Privacy.cshtml │   ├── Shared │   │   ├── _CookieConsentPartial.cshtml │   │   ├── Error.cshtml │   │   ├── _Layout.cshtml │   │   └── _ValidationScriptsPartial.cshtml │   ├── _ViewImports.cshtml │   └── _ViewStart.cshtml └── wwwroot     ├── css     │   └── site.css     ├── favicon.ico     ├── js     │   └── site.js     └── lib         ├── bootstrap         ├── jquery         ├── jquery-validation         └── jquery-validation-unobtrusive 
 
Route 在 Startup类 的Configure 方法中,可能会看到与下面类似的代码:
1 2 3 app.UseMvc(routes => {    routes.MapRoute("default" , "{controller=Home}/{action=Index}/{id?}" ); }); 
 
在对 UseMvc 的调用中,MapRoute 用于创建单个路由,亦称 default 路由。大多数 MVC 应用使用带有模板的路由,与 default 路由类似。路由模板:
{controller=Home} 将 Home 定义为默认 controller 
{action=Index} 将 Index 定义为默认 action 
{id?} 将 id 定义为可选参数 
 
路由模板 “{controller=Home}/{action=Index}/{id?}” 可以匹配诸如 /Products/Details/5 之类的 URL 路径,并通过对路径进行标记来提取路由值 { controller = Products, action = Details, id = 5 }。 MVC 将尝试查找名为 ProductsController 的控制器并运行 Details 操作:
1 2 3 public  class  ProductsController  : Controller  {   public  IActionResult Details (int  id )  { ... } } 
 
依赖关系注入 控制器 构造函数注入 服务作为构造函数参数添加,并且运行时从服务容器中解析服务,通常使用接口来定义服务。例如,考虑需要当前时间的应用,以下接口公开 IDateTime 服务:
1 2 3 4 5 6 7 8 9 10 11 12 public  interface  IDateTime {     DateTime Now { get ; } } public  class  SystemDateTime  : IDateTime {     public  DateTime Now     {         get  { return  DateTime.Now; }     } } 
 
注册:
1 2 3 4 5 6 public  void  ConfigureServices (IServiceCollection services ) {    services.AddSingleton<IDateTime, SystemDateTime>();     services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } 
 
使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public  class  HomeController  : Controller {     private  readonly  IDateTime _dateTime;     public  HomeController (IDateTime dateTime )      {        _dateTime = dateTime;     }     public  IActionResult Index ( )      {        var  serverTime = _dateTime.Now;         if  (serverTime.Hour < 12 )         {             ViewData["Message" ] = "It's morning here - Good Morning!" ;         }         else  if  (serverTime.Hour < 17 )         {             ViewData["Message" ] = "It's afternoon here - Good Afternoon!" ;         }         else          {             ViewData["Message" ] = "It's evening here - Good Evening!" ;         }         return  View();     } } 
 
FromServices注入 FromServicesAttribute 允许将服务直接注入到操作方法,而无需使用构造函数注入:
1 2 3 4 5 6 public  IActionResult About ([FromServices] IDateTime dateTime ) {    ViewData["Message" ] = $"Current server time: {dateTime.Now} " ;     return  View(); } 
 
视图 ASP.NET Core 支持将依赖关系注入到视图。 这对于视图特定服务很有用,例如仅为填充视图元素所需的本地化或数据。 应尽量在控制器和视图之间保持问题分离。 视图显示的大部分数据应该从控制器传入。
简单示例 可使用 @inject 指令将服务注入到视图中,可将 @inject 看作向视图添加属性,并用 DI 填充该属性。@inject 的语法:@inject <type> <name>,示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 @using System.Threading.Tasks @using ViewInjectSample.Model @using ViewInjectSample.Model.Services @model IEnumerable<ToDoItem >  @inject StatisticsService StatsService <!DOCTYPE html > <html > <head >     <title > To Do Items</title >  </head > <body >     <div >          <h1 > To Do Items</h1 >          <ul >              <li > Total Items: @StatsService.GetCount()</li >              <li > Completed: @StatsService.GetCompletedCount()</li >              <li > Avg. Priority: @StatsService.GetAveragePriority()</li >          </ul >          <table >              <tr >                  <th > Name</th >                  <th > Priority</th >                  <th > Is Done?</th >              </tr >              @foreach (var item in Model)             {                 <tr >                      <td > @item.Name</td >                      <td > @item.Priority</td >                      <td > @item.IsDone</td >                  </tr >              }         </table >      </div >  </body > </html > 
 
在 Startup.cs 的 ConfigureServices 中为依赖关系注入注册此服务:
1 2 3 4 5 6 7 public  void  ConfigureServices (IServiceCollection services ) {    services.AddMvc();     services.AddTransient<IToDoItemRepository, ToDoItemRepository>();     services.AddTransient<StatisticsService>();     services.AddTransient<ProfileOptionsService>(); 
 
填充查找数据 视图注入可用于填充 UI 元素(如下拉列表)中的选项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 using  Microsoft.AspNetCore.Mvc;using  ViewInjectSample.Model;namespace  ViewInjectSample.Controllers {     public  class  ProfileController  : Controller      {         [Route("Profile" ) ]         public  IActionResult Index ( )          {                         var  profile = new  Profile()             {                 Name = "Steve" ,                 FavColor = "Blue" ,                 Gender = "Male" ,                 State = new  State("Ohio" ,"OH" )             };             return  View(profile);         }     } } using  System.Collections.Generic;namespace  ViewInjectSample.Model.Services {     public  class  ProfileOptionsService      {         public  List<string > ListGenders ( )          {                         return  new  List<string >() {"Female" , "Male" };         }         public  List<State> ListStates ( )          {                         return  new  List<State>()             {                 new  State("Alabama" , "AL" ),                 new  State("Alaska" , "AK" ),                 new  State("Ohio" , "OH" )             };         }         public  List<string > ListColors ( )          {            return  new  List<string >() { "Blue" ,"Green" ,"Red" ,"Yellow"  };         }     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @using System.Threading.Tasks @using ViewInjectSample.Model.Services @model ViewInjectSample.Model.Profile @inject ProfileOptionsService Options <!DOCTYPE html > <html > <head >     <title > Update Profile</title >  </head > <body > <div >     <h1 > Update Profile</h1 >      Name: @Html.TextBoxFor(m => m.Name)     <br />      Gender: @Html.DropDownList("Gender",            Options.ListGenders().Select(g =>                  new SelectListItem() { Text = g, Value = g }))     <br />      State: @Html.DropDownListFor(m => m.State.Code,            Options.ListStates().Select(s =>                  new SelectListItem() { Text = s.Name, Value = s.Code}))     <br  />      Fav. Color: @Html.DropDownList("FavColor",            Options.ListColors().Select(c =>                  new SelectListItem() { Text = c, Value = c }))     </div >  </body > </html > 
 
Controller 
驻留在项目的根级别“Controllers”文件夹中 
继承自 Microsoft.AspNetCore.Mvc.Controller 
 
控制器是一个可实例化的类,其中下列条件至少某一个为 true:
类名称带有“Controller”后缀 
该类继承自带有“Controller”后缀的类 
使用 [Controller] 属性修饰该类 
 
控制器上的公共方法(除了那些使用 [NonAction] 属性装饰的方法)均为操作。操作上的参数会绑定到请求数据,并使用模型绑定进行验证。所有模型绑定的内容都会执行模型验证。 ModelState.IsValid 属性值指示模型绑定和验证是否成功。
操作方法应包含用于将请求映射到某个业务关注点的逻辑,业务关注点通常应当表示为控制器通过依赖关系注入来访问的服务,然后,操作将业务操作的结果映射到应用程序状态。
操作可以返回任何内容,但是经常返回生成响应的 IActionResult(或异步方法的 Task)的实例,操作方法负责选择响应的类型,操作结果会做出响应。 
添加控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using  Microsoft.AspNetCore.Mvc;using  System.Text.Encodings.Web;namespace  MvcHello.Controllers  {    public  class  HelloWorldController  : Controller  {                  public  string  Index ( )  {             return  "This is my default action..." ;         }                  public  string  Welcome ( )  {             return  "This is the Welcome action method..." ;         }     } } 
 
View 创建视图 在 Views / [ControllerName] 文件夹中创建特定于控制器的视图。 控制器之间共享的视图都将置于 Views/Shared 文件夹。 要创建一个视图,请添加新文件,并将其命名为与 .cshtml 文件扩展名相关联的控制器操作的相同名称。
Razor 标记以 @ 符号开头。 通过将 C# 代码放置在用大括号 ({ … }) 括住的 Razor 代码块内,运行 C# 语句。如下所示:
1 2 3 4 5 6 7 @{     ViewData["Title" ] = "About" ; } <h2>@ViewData["Title" ].</h2> <h3>@ViewData["Message" ]</h3> <p>Use this  area to provide additional information.</p> 
 
添加视图 在 HelloWorldController 类中,将 Index 方法替换为以下代码:
1 2 3 public  IActionResult Index ( )  {    return  View(); } 
 
为 HelloWorldController 添加 Index 视图。
添加一个名为“Views/HelloWorld”的新文件夹。 
向 Views/HelloWorld 文件夹添加名为“Index.cshtml”的新文件,并添加内容。 
 
更改标题和页脚等 修改Views/Shared/_Layout.cshtml 文件中的相关内容,并确认 Views/_ViewStart.cshtml 文件:
1 2 3 @{     Layout = "_Layout" ; } 
 
Views/_ViewStart.cshtml 文件将 Views/Shared/_Layout.cshtml 文件引入到每个视图中。 可以使用 Layout 属性设置不同的布局视图,或将它设置为 null,这样将不会使用任何布局文件。
控制器传递数据 强类型数据 (ViewModel) 使用 viewmodel 将数据传递给视图可让视图充分利用强类型检查。 强类型化(或强类型)意味着每个变量和常量都有明确定义的类型(例如 string、int 或 DateTime)。 在编译时检查视图中使用的类型是否有效。
使用 @model 指令指定模型。 使用带有 @Model 的模型:
1 2 3 4 5 6 7 8 @model WebApplication1.ViewModels.Address <h2>Contact</h2> <address>     @Model.Street<br>     @Model.City, @Model.State @Model.PostalCode<br>     <abbr title="Phone" >P:</abbr> 425.555 .0100  </address> 
 
为了将模型提供给视图,控制器将其作为参数进行传递:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public  IActionResult Contact ( ) {    ViewData["Message" ] = "Your contact page." ;     var  viewModel = new  Address()     {         Name = "Microsoft" ,         Street = "One Microsoft Way" ,         City = "Redmond" ,         State = "WA" ,         PostalCode = "98052-6399"      };     return  View(viewModel); } 
 
弱类型数据(ViewData、ViewData 属性和 ViewBag) 与强类型不同,弱类型(或松散类型)意味着不显式声明要使用的数据类型,可以使用弱类型数据集合将少量数据传入及传出控制器和视图。ViewBag 在 Razor 页中不可用。
ViewData 是通过 string 键访问的 ViewDataDictionary 对象。 字符串数据可以直接存储和使用,而不需要强制转换,但是在提取其他 ViewData 对象值时必须将其强制转换为特定类型。可以让控制器将视图模板所需的动态数据(参数)放置在视图模板稍后可以访问的 ViewData 字典中,将Welcome方法改为如下内容:
1 2 3 4 5 6 7 public  IActionResult Welcome (string  name, int  numTimes = 1  )  {    ViewData["Message" ] = "Hello "  + name;     ViewData["NumTimes" ] = numTimes;          return  View(); } 
 
创建一个名为 Views/HelloWorld/Welcome.cshtml 的 Welcome 视图模板,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 @{     ViewData["Title"] = "Welcome"; } <h2 > Welcome</h2 > <ul >     @for (int i = 0; i < (int )ViewData ["NumTimes "]; i ++)      {         <li>@ViewData["Message"]</li>     } </ul > 
 
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public  IActionResult SomeAction ( ) {    ViewData["Greeting" ] = "Hello" ;     ViewData["Address" ]  = new  Address()     {         Name = "Steve" ,         Street = "123 Main St" ,         City = "Hudson" ,         State = "OH" ,         PostalCode = "44236"      };     return  View(); } 
 
在视图中处理数据:
1 2 3 4 5 6 7 8 9 10 11 12 @{     // Since Address isn't a string, it requires a cast.     var address = ViewData["Address"] as Address; } @ViewData["Greeting"] World! <address >     @address.Name<br >      @address.Street<br >      @address.City, @address.State @address.PostalCode </address > 
 
Model 可以结合 Entity Framework Core (EF Core) 使用来处理数据库,EF Core 是对象关系映射 (ORM) 框架,可以简化需要编写的数据访问代码。要创建的模型类称为 POCO 类(源自“简单传统 CLR 对象”),因为它们与 EF Core 没有任何依赖关系,它们只定义将存储在数据库中的数据的属性。
建表 在数据库中建立表,需要与实体类对应。
安装相关包 通过Nuget包管理器安装MySql.Data.EntityFrameworkCore包:
1 $  dotnet add package  MySql.Data.EntityFrameworkCore 
 
添加实体类 在“Models”文件夹下添加“User.cs”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 using  System;using  System.ComponentModel.DataAnnotations;namespace  MvcHello.Models {     public  class  User      {                  [Key ]         public  int  Id { get ; set ; }                     public  string  Name { get ; set ; }                  public  string  Password { get ; set ; }     } } 
 
User 类可包含:
数据库需要 Id 字段以获取主键。 
[DataType(DataType.Date)]:DataType 属性指定数据的类型 (Date)。 通过此特性:
用户无需在数据字段中输入时间信息。 
仅显示日期,而非时间信息。 
 
 
 
添加数据库上下文类 在根目录下加上 DataAccess 目录做为数据库操作目录,在该目录下加上 Base 目录做数据库上下文目录,在Base目录下添加上下文类,继承 DbContext 类,通过构造函数注入数据库连接,添加 DbSet 实体属性,代码如下: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using  System;using  System.Collections.Generic;using  System.Linq;using  System.Threading.Tasks;using  Microsoft.EntityFrameworkCore;namespace  MvcHello.DataAccess.Base {     public  class  UserDbContext  : DbContext      {         public  UserDbContext  (DbContextOptions<UserDbContext> options ): base (options )          {        }         public  DbSet<MvcHello.Models.User> User { get ; set ; }     } } 
 
添加数据库连接配置(MySQL) 将连接字符串添加到 appsettings.json 文件:
1 2 3 4 5 6 7 8 9 10 11 {   "Logging" : {     "LogLevel" : {       "Default" : "Warning"      }   },   "AllowedHosts" : "*" ,   "ConnectionStrings" : {     "UserDbContext" : "server=localhost;user id=root;password=123456;database=asp;charset=utf8;sslMode=None"    } } 
 
添加数据库操作服务类 在 DataAccess 目录下新建 Interface 目录,用于保存数据库操作的接口,在该目录下新建 IUserDao 接口,在接口里增加相关数据库添、删、改、查接口,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 namespace  MvcHello.DataAccess.Interface {     public  interface  IUserDao      {                  bool  CreateUser (User user ) ;                  IEnumerable<User> GetUsers ( ) ;                  User GetUserByID (int  id ) ;                  bool  UpdateUser (User user ) ;                  bool  UpdateNameByID (int  id, string  name ) ;                  bool  DeleteUserByID (int  id ) ;     } } 
 
在 DataAccess 目录下新建 Implement 目录,用于保存数据库操作接口的实现,在该目录下新建 UserDao 类,继承 IUserDao 接口,实现接口里的数据库操作方法,在构造函数注入 UserDbContext 数据库上下文,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 namespace  MvcHello.DataAccess.Implement {     public  class  UserDao : IUserDao      {         public  UserDbContext Context;         public  UserDao (UserDbContext context )          {            Context = context;         }                  public  bool  CreateUser (User user )          {            Context.User.Add(user);             return  Context.SaveChanges() > 0 ;         }                  public  IEnumerable<User> GetUsers ( )          {            return  Context.User.ToList();         }                  public  User GetUserByID (int  id )          {            return  Context.User.SingleOrDefault(s => s.Id == id);         }                  public  bool  UpdateUser (User user )          {            Context.User.Update(user);             return  Context.SaveChanges() > 0 ;         }                  public  bool  UpdateNameByID (int  id, string  name )          {            var  state = false ;             var  user = Context.User.SingleOrDefault(s => s.Id == id);             if  (user != null )             {                 user.Name = name;                 state = Context.SaveChanges() > 0 ;             }             return  state;         }                  public  bool  DeleteUserByID (int  id )          {            var  user = Context.User.SingleOrDefault(s => s.Id == id);             Context.User.Remove(user);             return  Context.SaveChanges() > 0 ;         }     } } 
 
控制器中注入使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47   public  ActionResult<string > Create (string  name, string  password ) {    if  (string .IsNullOrEmpty(name.Trim()))     {         return  "姓名不能为空" ;     }     if  (string .IsNullOrEmpty(password.Trim()))     {         return  "密码不能为空" ;     }     var  user = new  User() {         Name = name,         Password = password     };     var  result = iHelloDao.CreateUser(user);     if  (result)     {         return  "学生插入成功" ;     }     else      {         return  "学生插入失败" ;     } } public  ActionResult<string > Gets ( ) {    var  names = "没有数据" ;     var  users = iHelloDao.GetUsers();     if  (users != null )     {         names = "" ;         foreach  (var  s in  users)         {             names += $"{s.Name}  \r\n" ;         }                  }     return  names; } 
 
在Starup.cs中注册数据库服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public  void  ConfigureServices (IServiceCollection services ) {    services.Configure<CookiePolicyOptions>(options =>     {                  options.CheckConsentNeeded = context => true ;         options.MinimumSameSitePolicy = SameSiteMode.None;     });     services.AddDbContext<UserDbContext>(d => d.UseMySQL(Configuration.GetConnectionString("UserDbContext" )));     services.AddScoped<IUserDao, UserDao>();     services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }