.Net Core 学习之路-基础
.Net Core出来好久了,一直在了解,但始终没有应用到实际项目中....
准备用.net core搞个SSO,才发现它和.net framework的变化并不是一点点...
.net core还在学习摸索中,这篇文章就遇到的问题记录一下,希望对需要的人有所帮助
环境变量
.Net Core包含一个launchSettings.json的文件,在项目的Properties"文件夹下
本地计算机开发环境中,这个文件设置了.net core不同运行环境中每个变量的值
在生产环境中,设置环境的方法取决于操作系统而不是此文件了
我们可以通过配置环境变量启用或禁用应用程序部分功能
在Startup.cs 的 Configure函数中可通过IHostingEnvironment来获取当前环境变量的配置
配置项读写
WebHost.CreateDefaultBuilder(args) 这段代码会加载默认配置项,同时也可能启用部分服务
加载顺序为:
- appsettings.json。
- appsettings.{Environment}.json。
- 应用在 Development 环境中运行时的用户机密。(secrets.json)
- 环境变量。(launchSettings.json)
- 命令行参数。
读取配置项
以下面的appsettings设置为例:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},
"App": {
"ConnectionStrings": {
"RwViewSQLConnString": "server=*;Initial Catalog=*;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=300;",
"RoViewSQLConnString": "server=*;Initial Catalog=*;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=300;"
},
"AppSettings": {
"SqlHelperNonQueryCommandTimeout": 30,
"SqlHelperQueryCommandTimeout": 30
}
}
}
读取单个节点: Configuration.GetSection("App:ConnectionStrings:RwViewSQLConnString")
将节点绑定到实体数据模型: Configuration.GetSection("App").Bind(new ConfigOptions());
在类库中获取IConfiguration:
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
ApplicationEnvironment env = PlatformServices.Default.Application;
IConfiguration Configuration = builder.Build();
也可以用ioc的注入从构造函数中获取,不过着实不方便,更建议建一个静态类来保存全局配置
可以监听配置文件的改变事件来重新绑定实体模型:
Configuration.GetReloadToken().RegisterChangeCallback(OnSettingChanged, Configuration);
public void OnSettingChanged(object state)
{
callbackRegistration?.Dispose();
IConfiguration configuration = (IConfiguration)state;
configuration.GetSection("App").Bind(new ConfigOptions());
callbackRegistration = configuration.GetReloadToken()
.RegisterChangeCallback(OnSettingChanged, state);
}
按环境配置
我们可以通过设置 launchSettings.json文件中对应启动方式的ASPNETCORE_ENVIRONMENT值来设定程序的运行环境,官方只支持三个固定的值:Development、Staging 或 Production
appsettings.json会优先读取appsettings.{Environment}.json中设定的值
用户机密
按照我们以往的习惯,可能习惯于将之前存在web.config中的配置项转移到 appsettings.json 中存储,但是对于数据库连接字符串等加密信息如今.net core不太建议我们通过这种方式来存储
在开发环境中它提供了另一种存储方式:机密管理器
实际上是将密码的配置存储到本地电脑的一个json文件当中,这个文件存储的位置与操作系统和服务器的登陆用户有关。
这种做法的好处总结为下两点:
- 将机密文件与项目源代码分离,提高安全性
- 以连接字符串为例,如果多人开发的情况,每个人可能用到的链接不同,避免的多人都在更改同一个配置文件,上传时还要还原的繁琐
下面介绍下机密管理器的使用方式:
安装nuget包:
- Microsoft.Extensions.Configuration.UserSecrets
- Microsoft.VisualStudio.Web.CodeGeneration.Tools
第一个包用于配置机密文件 第二个用于读取配置
此时查看项目的工程文件(*.csproj),可以看到多出来一个UserSecretsId节点的配置,类似于下面这样:
<UserSecretsId>79bbf988-8542-4789-a63e-d4a3588c64a3</UserSecretsId>
在vs中我们可以右键项目->Manage User Secrets 编辑机密文件:
{
"App": {
"ConnectionStrings": {
"RwViewSQLConnString": "server=*;Initial Catalog=*;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=300;",
"RoViewSQLConnString": "server=*;Initial Catalog=*;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=300;"
},
"AppSettings": {
"SqlHelperNonQueryCommandTimeout": 40,
"SqlHelperQueryCommandTimeout": 40
}
}
}
我们再一次读取 configuration.GetSection("App").Bind(new ConfigOptions()); 中的配置项就会以 User Secrets中的配置为准
这种机密文件的配置方式只适用于开发环境,让密码配置脱离源代码管理器。生产环境中我们则需要 生产机密Microsoft Azure 密钥保管库配置
密钥保管库暂时没有进行研究,留到后面研究清楚之后会单独写一篇文章
服务器 URL
可通过 UseUrls函数设置url
或者通过配置文件配置 hostting.json文件内容:
{
urls: "http://*:5005"
}
配置启用方式
public static IWebHost BuildWebHost(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.AddCommandLine(args)
.Build();
return WebHost.CreateDefaultBuilder(args)
.UseUrls("http://*:5000;http://*:5001;")
.UseConfiguration(config)
.UseStartup<Startup>()
.Build();
}
若无hostting.json配置,以上代码将会监听两个端口:5000 5001
若存在配置则会用5005端口
过滤器
.net Core中过滤器的用法没有太大的改变,注册全局过滤器的方式有所不同:
services.AddMvc(options=> {
options.Filters.Add(typeof(SampleActionFilterAttribute));
});
过滤器和.net core的中间件似乎很是相似,但是相比之下,过滤器可以处理到更细节的地方,相比中间件更加灵活
日志
之前一直用Log4net来记录日志,.net core2.0默认提供的日志记录方式并不能满足生产环境的要求,所以研究了下log4net在.net core中的用法:
- 引用最新版的nuget包
- 增加配置文件log4net.config
使用代码如下:
log4net.Repository.ILoggerRepository repository = log4net.LogManager.CreateRepository("NETCoreRepository");
var fileInfo = new FileInfo("log4net.config");
log4net.Config.XmlConfigurator.Configure(repository, fileInfo);
log4net.Config.BasicConfigurator.Configure(repository);
log4net.ILog log = log4net.LogManager.GetLogger(Startup.Repository.Name, MethodBase.GetCurrentMethod().DeclaringType);
repository的位置可以放在startup当中,避免每次都实例化
同时研究了下官方推荐的一个第三方日志记录提供程序Nlog:
Nlog在.net core的详细使用说明可参考官网:https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2
我这里就直接贴代码了:
首先需要引用最新的nuget包:NLog.Web.AspNetCore NLog.Extensions.Logging
配置文件nlog.config:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Debug"
internalLogFile="internal-nlog.txt">
<!--define various log targets-->
<targets>
<!--保存至文件-->
<target name="log_file" xsi:type="File"
fileName="../../../NLogs/${shortdate}_${level:uppercase=false:padding=-5}.log"
layout="${longdate} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" />
</targets>
<rules>
<logger name="*" level="Info" writeTo="log_file" />
<logger name="*" levels="Error" writeTo="log_file" />
<logger name="*" levels="Debug" writeTo="log_file" />
<logger name="*" level="Fatal" writeTo="log_file" />
<logger name="*" level="Warn" writeTo="log_file" />
</rules>
</nlog>
startup:
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddNLog();
app.AddNLogWeb();
env.ConfigureNLog("nlog.config");
}
controller:
private NLog.Logger nLogger = NLog.LogManager.GetCurrentClassLogger();
private readonly ILogger<HomeController> nLogger2;
public HomeController(IOptions<AppSettionsOptions> set, ILogger<HomeController> logger2)
{
nLogger2 = logger2;
}
public IActionResult Index()
{
nLogger.Info("nloginfo");
nLogger.Error("nlogerror", new Exception("自定义异常"));
nLogger2.LogInformation("nloginfo2");
nLogger2.LogError("nlogerror2", new Exception("自定义异常"));
return View();
}
上面展示了两种logger的调用方式
值得注意的是通过构造函数注入的logger对象会优先选择appsettings.json中的配置
更要注意的是appsetting取的是配置的环境变量所对应的appsettings.{Environment}.json。(之前调试过程中我将环境变量改了,结果在测试日志输出时发现appsettings怎么设置都没用...)
IOC
.net Core 内置了一套默认的依赖注入实现,但并不是太好用
官网提供了一个Autofac的简单示例,之前对Antofac也只是初步了解了一下,没有深入使用
下一篇将详细讲解下.Net core中Ioc的使用
.Net Core 学习之路-基础的更多相关文章
- #Java学习之路——基础阶段二(第一篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- MySql 学习之路-基础
Mysql 自学之路 本文包含基础部分与高级部分 一.基础 数据库操作 Show databases:显示所有的数据库 Show tables: 显示所有的数据库表 Use databasename: ...
- #Java学习之路——基础阶段二(第十篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- python学习之路基础篇(第五篇)
前四天课程回顾 1.python简介 2.python基本数据类型 类: int:整型 | str:字符串 | list:列表 |tuple:元组 |dict:字典 | set:集合 对象: li = ...
- python学习之路基础篇(第四篇)
一.课程内容回顾 1.python基础 2.基本数据类型 (str|list|dict|tuple) 3.将字符串“老男人”转换成utf-8 s = "老男人" ret = by ...
- #Java学习之路——基础阶段二(第九篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- #Java学习之路——基础阶段二(第八篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- #Java学习之路——基础阶段二(第七篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
- #Java学习之路——基础阶段二(第六篇)
我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...
随机推荐
- [mysql] MySQL解压缩安装步骤
以前装的MySQL出问题了,只好卸载了. 又下载了一个mysql-5.6.24-win32.1432006610.zip.msi文件直接安装就行了.这里需要解压到指定目录,配置后可使用. 环境变量配置 ...
- oracle 常用select sql语句
本人认为很实用的几条语句 1)select ... from ...into... 2)insert into ...select ... 3)select ...from ...left join ...
- http的CA证书安装(也就是https)
近几年随着安全意识的提高,https流行起来,很多小伙伴不太了解https是什么,其实http和https并没有区别,简单的来说,https就是将http通信进行了加密和解密的一个过程.加上谷歌浏览器 ...
- Java终结方法的使用(终结守卫者)
终结方法finalize()通常是不可预测的,也是很危险的,一般情况下是不必要的. Java语言规范并不保证finalize()会被及时执行,即不确定终结方法执行时间,只规定在对象被垃圾回收之前执行 ...
- 有关java中的hashCode问题
1. HashSet集合存储数据的结构(哈希表) 1.1 什么是哈希表? 哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会 ...
- 深入理解C++ new/delete, new []/delete[]动态内存管理
在C语言中,我们写程序时,总是会有动态开辟内存的需求,每到这个时候我们就会想到用malloc/free 去从堆里面动态申请出来一段内存给我们用.但对这一块申请出来的内存,往往还需要我们对它进行稍许的“ ...
- Linux挂载
1 文件系统中相关目录 dev:设备文件 media:挂载媒体设备,如光驱,U盘 mnt:让用户临时挂载别的文件系统 2 磁盘分区相关知识 1)磁盘包括IDE和SCSI两种接口: IDE接口:速度慢但 ...
- XML使用练习
#!/usr/bin/env python # -*- coding:utf-8 -*- import requests from xml.etree import ElementTree as ET ...
- 《高级软件测试》11.15.全组完成jira安装,开始任务的部分书写
今日任务完成情况如下: 小段:完成linux环境上jira的安装,并将jira的安装过程录制下来 小费:完成linux环境下jira的安装,开始部分任务的书写 小高:完成了jira的安装,并进一步熟悉 ...
- 01-JavaScript之变量
这个系列的文章主要讲解JavaScript的常见用法,适合于初中级的前端开发人员,也可以对比TypeScript的系列文章来看. 先介绍JavaScript的变量与常见变量的函数,代码如下: //变量 ...