文章目录
- 介绍
- 具体案例
- 自定义环境变量的命名前缀
- 自定义命令行参数映射
- 使用JSON文件来配置选项类
- 在应用程序运行期间创建SQLite数据库
- 总结
介绍
随着.net core
越来越流行,对.net core
基础知识的了解,实际应用等相关的知识也应该有所了解。所以就有了这篇文章,案例都是来自阅读的书籍,或者实际工作中感觉比较有用的应用。分享亦总结。
本文主要介绍 .net core
相关的应用配置和数据库访问案例。
具体案例
自定义环境变量的命名前缀
【导语】
用于对应用程序进行配置的环境变量的默认前缀为“ASPNETCORE_”,例如,配置应用启动 URL
的环境变量名为“ASPNETCORE_URLS”,配置运行环境的环境变量名为“ASPNETCORE_ENVIRONMENT”。
但有时不希望使用默认的环境变量前缀,本实例将演示自定义环境变量命名前缀的方法。
【操作流程】
步骤1:新建一个空白的 ASP.NET Core Web
应用程序项目。
步骤2:在 Main
方法中使用 ConfigurationBuilder
类添加环境变量配置源。
var configBuilder = new ConfigurationBuilder()
.AddEnvironmentVariables("APP_");
调用带 prefix
参数的 AddEnvironmentVariables
重载方法,prefix
参数为字符串类型,用来指定环境变量的命名前缀。本实例指定的前缀为“APP_”,即所有有效的环境变量名都必须以此前缀开头,例如“APP_URLS”。
步骤3:使用上面的配置数据来配置 WebHostBuilder
。
var hostBuilder = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseConfiguration(configBuilder.Build())
.UseStartup<Startup>();
hostBuilder.Build().Run();
UseConfiguration
实例需要调用 Build
方法生成配置信息,再通过 WebHostBuilder
实例的 UseConfiguration
扩展方法应用配置。
步骤4:在“解决方案资源管理器”窗口中右击项目名称,从快捷菜单中选择“属性”命令,打开“项目属性”窗口。
步骤5:切换到“调式”选项卡,在环境变量节点处添加两个环境变量。
注意:此处环境变量的前缀已经变为“APP_”。
APP_URLS
配置应用程序的启动URL
,APP_ENVIRONMENT
配置应用程序的运行环境。
步骤6:保存设置并关闭“项目属性”窗口。
步骤7:创建一个简单 Demo
控制器,稍后用来测试应用程序。
[Route("/demo/[action]")]
public class DemoController : Controller
{
public IActionResult Index()
{
return View();
}
}
步骤8:在项目中创建 Views
目录,在 Views
目录下创建 Demo
子目录。
步骤9:添加 Index
视图,HTML
代码如下。
<h1>测试网站</h1>
<h4>欢迎来到主页。</h4>
步骤10:运行应用程序,在浏览器地址栏中输入 http://localhost:12130/demo/index ,如果视图显示正常,表明环境变量配置无误。
自定义命令行参数映射
【导语】
ASP.NET Core
应用程序支持通过传递命令行参数来配置应用程序,这些命令行参数追加到 dotnet run
或 dotnet <应用程序.dll>
之后。例如,编译应用程序后生成的文件为 LeetAPI.dll
,下面三种方式都可以使用命令行参数来配置应用程序的监听 URL
。
dotnet LeetAPI.dll urls=http://localhost:6570
dotnet LeetAPI.dll - urls http://localhost:6570
dotnet LeetAPI.dll /urls http://localhost:6570
默认情况下,命令行参数的命名与配置项的名称相同,但是也可以在命令行参数和配置项之间创建一个映射关系,使命令行参数的名称与配置项的名称不同。例如,将应用程序运行环境的配置项命名为 environment
,整个名称太长,可以使用命令行参数 e
或者 env
来指向 environment
配置项。命令行参数的映射列表是一个字典对象,其中,Key
表示命令行参数的名称,Value
表示配置项的名称。
【操作流程】
步骤1:新建一个空白的 ASP.NET Core Web
应用程序项目。
步骤2:在 Main
方法中,声明一个字典类型的变量,对命令行参数进行映射。
IDictionary<string, string> mapping = new Dictionary<string, string>
{
["--u"] = "urls",
["--env"] = "environment"
};
经过映射后,设置应用程序监听URL的命令行参数为 -u
,设置运行环境的命令行参数为 -env
。
步骤3:创建 ConfigurationBuilder
实例,并添加命令行参数作为配置来源。
IConfigurationBuilder configbd = new ConfigurationBuilder()
.AddCommandLine(args, mapping);
步骤4:将配置信息应用到 Host
上。
var hostbd = new WebHostBuilder()
.UseConfiguration(configbd.Build())
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>();
hostbd.Build().Run();
步骤5:打开项目属性窗口,切换到“调试”选项卡。
步骤6:填写“应用程序参数”(即命令行参数)。
--u http://localhost:7000 --env Test
步骤7:运行应用程序,从控制台的输出信息中可以查看以上命令行参数是否已经成功应用。
使用JSON文件来配置选项类
【导语】
初始化选项类最佳的方法,是在调用 Configure<TOptions>
方法时通过传入的委托对象来设置各个属性的值,该方法的缺点是如果需要经常修改选项类的数据的话,在每次更新属性后都要重新编译应用程序。而使用 JSON
文件来配置选项类的初始数据是一种比较实用的方案,当要进行更新时,只需要修改 JSON
文件中的内容,可以免去重新编译和发布应用程序的麻烦。
使用 JSON
文件配置时,首先使用 ConfigurationBuilder
类添加JSON文件配置源。然后到用 Build
方法生成配置信息,可以在配置 WebHostBuilder
时通过UseConfiguration
方法引用配置信息,在经过依赖注入提供给 Startup
类。最后在 ConfigureServices
方法中调用 Configure<TOptions>
方法,并且传递配置信息来初始选项类。
从 JSON
文件中提取选项类的属性值,实质上是一个反序列化的过程,这就要求 JSON
文件中的字段名称必须和选项类的属性 名称匹配(字段名称的首字母允许使用小写)。
【操作流程】
步骤1:新建一个空白的 ASP.NET Core Web
应用程序项目。
步骤2:定义选项类 TestOptions
,公开两个 string
类型的属性 Item1
和 Item2
。
public class TestOptions
{
public string Item1 { get; set; }
public string Item2 { get; set; }
}
步骤3:在项目目录下添加一个 JSON
文件,命名为 configs.json
。
{
"urls": "http://localhost:16420",
"environment": "Development",
"myOptions": {
"item1": "选项-A",
"item2": "选项-B"
}
}
urls
和 environment
两个字段配置的是 WebHost
,myOptions
字段中所包含的内容才是配置 TestOptions
选项类的。
步骤4:在 Main
方法中,创建并启动 WebHost
实例,并加载 configs.json
文件中的配置内容。
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("configs.json", optional:true)
.Build();
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseConfiguration(config)
.UseStartup<Startup>()
.Build();
host.Run();
AddJsonFile
扩展方法的 optional
参数用于指定当前需要添加的配置源是否为可选。本实例中将该参数设置为 true
,如果应用程序找不到 configs.json
文件,就忽略它,不会发生异常。
步骤5:修改项目模板默认生成的 Startup
类,从构造函数中接收 IConfiguration
类型的参数,以便获得配置信息的引用。
private readonly IHostingEnvironment _env;
private readonly IConfiguration _config;
public Startup(IHostingEnvironment env, IConfiguration config)
{
_env = env;
_config = config;
}
步骤6:在 ConfigureServices
方法中调用 Configure<TOptions>
方法来初始化 TestOptions
选项类,之后它会注册到服务容器中。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.Configure<TestOptions>(_config.GetSection("myOptions"));
}
由于在 configs.json
文件中,myOptions
字段所包含的内容才是反序列化 TestOptions
类需要的,所以这里调用 GetSection
方法获取 myOptions
字段下的内容。
步骤7:创建 Demo
控制器,返回一个视图,用于显示选项类的信息。
[Route("opts/[action]")]
public class DemoController : Controller
{
public ActionResult Default() => View();
}
步骤8:Default
视图的内容如下。
@using Microsoft.Extensions.Options
@using Demo
@inject IOptions<TestOptions> opt
<html>
<body>
@{
TestOptions o = opt?.Value;
}
@if(o == null)
{
<div>无选项信息。</div>
}
else
{
<div>
<p>Item 1 : @o.Item1</p>
<p>Item 2 : @o.Item2</p>
</div>
}
</body>
</html>
步骤9:运行应用程序,在浏览器中访问 http://localhost:16420/opts/default ,可以看到选项类初始化后的属性值。
在应用程序运行期间创建SQLite数据库
【导语】
为实体类型创建数据库有两种方案:(1)在 Nuget
控制台中执行 Update-Database
命令(或者在命令行中执行 dotnet ef database update
命令),此方案是在应用程序未运行的情况下执行的;(2)通过编写代码,在应用程序运行期间创建数据库。
DbContext
类公开了 Database
属性,其类型为 DatabaseFacade
,该类型公开了用于在运行阶段创建和删除数据库的方法。
(1)EnsureCreated
方法或 EnsureCreatedAsync
方法。如果目标数据库(根据连接字符串获取)不存在,就创建新数据库并返回 true
;如果数据库已经存在,则返回 false
。
(2)EnsureDeleted
方法或 EnsureDeletedAsync
方法。如果目标数据库已经存在,则删除该数据库并返回 true
,否则返回 false
。
本实例演示了在应用程序运行过程中通过调用代码来创建 SQLite
数据库。
【操作流程】
步骤1:新建一个空白的 ASP.NET Core Web
应用程序项目。
步骤2:打开 Nuget
控制台窗口,输入以下命令列来安装 SQLite
数据库提供的与程序相关的程序包。
Install - Package Microsoft.EntityFrameworkCore.Sqlite
从 .NET Core SDK 2.1
开始,此程序包并不在 AspNetCore.APP
默认包含的程序包列表中,需要手动安装。
步骤3:定义两个实体类。
public class Album
{
public int ID { get; set; }
public string AlbumName { get; set; }
public int Year { get; set; }
public string Summary { get; set; }
public List<Track> Tracks { get; set; }
}
public class Track
{
public int ID { get; set; }
public string Title { get; set; }
public string Artist { get; set; }
public double Duration { get; set; }
}
步骤4:定义 DbContext
派生类。
public class DemoDbContext : DbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Track> Tracks { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 配置主键
modelBuilder.Entity<Album>().HasKey(s => s.ID);
modelBuilder.Entity<Track>().HasKey(t => t.ID);
// 配置为一对多的关系
modelBuilder.Entity<Album>().HasMany(a => a.Tracks).WithOne();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("data source=TestData.db");
}
}
在 OnModelCreating
方法中,首先分别设置两个实体的逐渐,然后配置两个实体之间的关系:Album
类和 Track
类是“一对多”的关系。
步骤5:在 Main
方法中,配置并创建 WebHost
实例。
var host = new WebHostBuilder()
.UseKestrel()
.UseEnvironment(EnvironmentName.Development)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("http://localhost:9133")
.UseStartup<Startup>()
.Build();
步骤6:为了生成测试用的数据,在运行 WebHost
实例前,可以先创建数据库,然后再向数据库写入记录。
using(IServiceScope scope = host.Services.CreateScope())
{
DemoDbContext context = scope.ServiceProvider.GetRequiredService<DemoDbContext>();
context.Database.EnsureDeleted();
if (context.Database.EnsureCreated())
{
// 如果是新创建的数据库,写入一些测试数据
Album ab1 = new Album();
ab1.AlbumName = "专辑 01";
ab1.Year = 2010;
ab1.Summary = "冬日里的唱响";
ab1.Tracks = new List<Track>
{
new Track
{
Title = "曲目 1",
Artist = "老高",
Duration = 212.3d
},
new Track
{
Title = "曲目 2",
Artist = "大鹏",
Duration = 179.62d
}
};
context.Albums.Add(ab1);
Album ab2 = new Album();
ab2.AlbumName = "专辑 02";
ab2.Year = 2016;
ab2.Summary = "最具风雅的弦乐";
ab2.Tracks = new List<Track>
{
new Track
{
Title = "曲目 1",
Artist = "张K",
Duration = 230.301d
},
new Track
{
Title = "曲目 2",
Artist = "Coh",
Duration = 197d
},
new Track
{
Title = "曲目 3",
Artist = "L.Joke",
Duration = 265.99d
}
};
context.Albums.Add(ab2);
context.SaveChanges();
}
}
先调用 EnsureDeleted
方法以确保删除已经存在的数据库,再调用 EnsureCreated
方法创建新的数据库。
步骤7:创建一个 API
控制器,返回 Album
实体列表(JSON
格式)。
[Route("albums")]
public class DemoController : Controller
{
readonly DemoDbContext context;
public DemoController(DemoDbContext cxt)
{
context = cxt;
}
[HttpGet]
public ActionResult Get()
{
var albums = context.Albums.Include(a => a.Tracks);
return Json(albums);
}
}
Albums
实体类的 Tracks
属性属于“导航属性”,它包含于该实体有关联的 Track
对象。这里必须调用 Include
方法,否则 Tracks
属性将返回努力了(默认不会加载导航属性所包含的数据)。
步骤8:运行应用程序,访问地址 http://localhost:9133/albums 可以获取 Album
对象列表。返回的 JSON
内容如下。
[
{
"id":1,
"albumName":"专辑 01",
"year":2010,
"summary":"冬日里的唱响",
"tracks":[
{
"id":1,
"title":"曲目 1",
"artist":"老高",
"duration":212.3
},
{
"id":2,
"title":"曲目 2",
"artist":"大鹏",
"duration":179.62
}
]
},
{
"id":2,
"albumName":"专辑 02",
"year":2016,
"summary":"最具风雅的弦乐",
"tracks":[
{
"id":3,
"title":"曲目 1",
"artist":"张K",
"duration":230.301
},
{
"id":4,
"title":"曲目 2",
"artist":"Coh",
"duration":197
},
{
"id":5,
"title":"曲目 3",
"artist":"L.Joke",
"duration":265.99
}
]
}
]
总结
分享就到这里了,其覆盖的知识肯定是不全的,而且一些很基础的我也没有放进来。总来的说还是要有一定基础的读起来可能会好点。