.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设置为例:

  1. {
  2. "Logging": {
  3. "IncludeScopes": false,
  4. "LogLevel": {
  5. "Default": "Warning"
  6. }
  7. },
  8. "App": {
  9. "ConnectionStrings": {
  10. "RwViewSQLConnString": "server=*;Initial Catalog=*;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=300;",
  11. "RoViewSQLConnString": "server=*;Initial Catalog=*;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=300;"
  12. },
  13. "AppSettings": {
  14. "SqlHelperNonQueryCommandTimeout": 30,
  15. "SqlHelperQueryCommandTimeout": 30
  16. }
  17. }
  18. }

读取单个节点: Configuration.GetSection("App:ConnectionStrings:RwViewSQLConnString")

将节点绑定到实体数据模型: Configuration.GetSection("App").Bind(new ConfigOptions());

在类库中获取IConfiguration

  1. var builder = new ConfigurationBuilder()
  2. .SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
  3. ApplicationEnvironment env = PlatformServices.Default.Application;
  4. IConfiguration Configuration = builder.Build();

也可以用ioc的注入从构造函数中获取,不过着实不方便,更建议建一个静态类来保存全局配置

可以监听配置文件的改变事件来重新绑定实体模型:

  1. Configuration.GetReloadToken().RegisterChangeCallback(OnSettingChanged, Configuration);
  2. public void OnSettingChanged(object state)
  3. {
  4. callbackRegistration?.Dispose();
  5. IConfiguration configuration = (IConfiguration)state;
  6. configuration.GetSection("App").Bind(new ConfigOptions());
  7. callbackRegistration = configuration.GetReloadToken()
  8. .RegisterChangeCallback(OnSettingChanged, state);
  9. }

按环境配置

我们可以通过设置 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节点的配置,类似于下面这样:

  1. <UserSecretsId>79bbf988-8542-4789-a63e-d4a3588c64a3</UserSecretsId>

在vs中我们可以右键项目->Manage User Secrets 编辑机密文件:

  1. {
  2. "App": {
  3. "ConnectionStrings": {
  4. "RwViewSQLConnString": "server=*;Initial Catalog=*;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=300;",
  5. "RoViewSQLConnString": "server=*;Initial Catalog=*;Persist Security Info=True;User ID=sa;Password=123456;Connect Timeout=300;"
  6. },
  7. "AppSettings": {
  8. "SqlHelperNonQueryCommandTimeout": 40,
  9. "SqlHelperQueryCommandTimeout": 40
  10. }
  11. }
  12. }

我们再一次读取 configuration.GetSection("App").Bind(new ConfigOptions()); 中的配置项就会以 User Secrets中的配置为准

这种机密文件的配置方式只适用于开发环境,让密码配置脱离源代码管理器。生产环境中我们则需要 生产机密Microsoft Azure 密钥保管库配置

密钥保管库暂时没有进行研究,留到后面研究清楚之后会单独写一篇文章

服务器 URL

可通过 UseUrls函数设置url

或者通过配置文件配置 hostting.json文件内容:

{

urls: "http://*:5005"

}

配置启用方式

  1. public static IWebHost BuildWebHost(string[] args)
  2. {
  3. var config = new ConfigurationBuilder()
  4. .SetBasePath(Directory.GetCurrentDirectory())
  5. .AddJsonFile("hosting.json", optional: true)
  6. .AddCommandLine(args)
  7. .Build();
  8. return WebHost.CreateDefaultBuilder(args)
  9. .UseUrls("http://*:5000;http://*:5001;")
  10. .UseConfiguration(config)
  11. .UseStartup<Startup>()
  12. .Build();
  13. }

若无hostting.json配置,以上代码将会监听两个端口:5000 5001

若存在配置则会用5005端口

参考链接:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/hosting?tabs=aspnetcore2x#overriding-configuration

过滤器

.net Core中过滤器的用法没有太大的改变,注册全局过滤器的方式有所不同:

  1. services.AddMvc(options=> {
  2. options.Filters.Add(typeof(SampleActionFilterAttribute));
  3. });

过滤器和.net core的中间件似乎很是相似,但是相比之下,过滤器可以处理到更细节的地方,相比中间件更加灵活

日志

之前一直用Log4net来记录日志,.net core2.0默认提供的日志记录方式并不能满足生产环境的要求,所以研究了下log4net在.net core中的用法:

  • 引用最新版的nuget包
  • 增加配置文件log4net.config

使用代码如下:

  1. log4net.Repository.ILoggerRepository repository = log4net.LogManager.CreateRepository("NETCoreRepository");
  2. var fileInfo = new FileInfo("log4net.config");
  3. log4net.Config.XmlConfigurator.Configure(repository, fileInfo);
  4. log4net.Config.BasicConfigurator.Configure(repository);
  5. 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:

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. autoReload="true"
  5. internalLogLevel="Debug"
  6. internalLogFile="internal-nlog.txt">
  7. <!--define various log targets-->
  8. <targets>
  9. <!--保存至文件-->
  10. <target name="log_file" xsi:type="File"
  11. fileName="../../../NLogs/${shortdate}_${level:uppercase=false:padding=-5}.log"
  12. layout="${longdate} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" />
  13. </targets>
  14. <rules>
  15. <logger name="*" level="Info" writeTo="log_file" />
  16. <logger name="*" levels="Error" writeTo="log_file" />
  17. <logger name="*" levels="Debug" writeTo="log_file" />
  18. <logger name="*" level="Fatal" writeTo="log_file" />
  19. <logger name="*" level="Warn" writeTo="log_file" />
  20. </rules>
  21. </nlog>

startup:

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env,
  2. ILoggerFactory loggerFactory)
  3. {
  4. loggerFactory.AddNLog();
  5. app.AddNLogWeb();
  6. env.ConfigureNLog("nlog.config");
  7. }

controller:

  1. private NLog.Logger nLogger = NLog.LogManager.GetCurrentClassLogger();
  2. private readonly ILogger<HomeController> nLogger2;
  3. public HomeController(IOptions<AppSettionsOptions> set, ILogger<HomeController> logger2)
  4. {
  5. nLogger2 = logger2;
  6. }
  7. public IActionResult Index()
  8. {
  9. nLogger.Info("nloginfo");
  10. nLogger.Error("nlogerror", new Exception("自定义异常"));
  11. nLogger2.LogInformation("nloginfo2");
  12. nLogger2.LogError("nlogerror2", new Exception("自定义异常"));
  13. return View();
  14. }

上面展示了两种logger的调用方式

值得注意的是通过构造函数注入的logger对象会优先选择appsettings.json中的配置

更要注意的是appsetting取的是配置的环境变量所对应的appsettings.{Environment}.json。(之前调试过程中我将环境变量改了,结果在测试日志输出时发现appsettings怎么设置都没用...)

IOC

.net Core 内置了一套默认的依赖注入实现,但并不是太好用

官网提供了一个Autofac的简单示例,之前对Antofac也只是初步了解了一下,没有深入使用

下一篇将详细讲解下.Net core中Ioc的使用

.Net Core 学习之路-基础的更多相关文章

  1. #Java学习之路——基础阶段二(第一篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  2. MySql 学习之路-基础

    Mysql 自学之路 本文包含基础部分与高级部分 一.基础 数据库操作 Show databases:显示所有的数据库 Show tables: 显示所有的数据库表 Use databasename: ...

  3. #Java学习之路——基础阶段二(第十篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  4. python学习之路基础篇(第五篇)

    前四天课程回顾 1.python简介 2.python基本数据类型 类: int:整型 | str:字符串 | list:列表 |tuple:元组 |dict:字典 | set:集合 对象: li = ...

  5. python学习之路基础篇(第四篇)

    一.课程内容回顾 1.python基础 2.基本数据类型  (str|list|dict|tuple) 3.将字符串“老男人”转换成utf-8 s = "老男人" ret = by ...

  6. #Java学习之路——基础阶段二(第九篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  7. #Java学习之路——基础阶段二(第八篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  8. #Java学习之路——基础阶段二(第七篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

  9. #Java学习之路——基础阶段二(第六篇)

    我的学习阶段是跟着CZBK黑马的双源课程,学习目标以及博客是为了审查自己的学习情况,毕竟看一遍,敲一遍,和自己归纳总结一遍有着很大的区别,在此期间我会参杂Java疯狂讲义(第四版)里面的内容. 前言: ...

随机推荐

  1. Redis这些知识点,是必须知道的!

    Redis是一个开源(BSD许可)的内存数据结构存储,可作为数据库,缓存和消息队列.相比Memcached它支持更多的数据结构,如string(字符串),hash(哈希),list(链表),set(集 ...

  2. linux拓展下:批量改扩展名的方法

    [root@oldboy oldboy]# ll total 0 -rw-r--r-- 1 root root 0 Nov 13 19:38 stu_102999_1_.jpg -rw-r--r-- ...

  3. MSIL实用指南-生成构造函数

    本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodA ...

  4. 关于java中的值传递与引用传递遇到的问题

    来源于:https://www.nowcoder.com/test/question/done?tid=14302398&qid=25373#summary 下列java程序的输出结果为___ ...

  5. 控制input只能输入数字和两位小数

    <input type="text" name="je" onkeyup="clearNoNum(this)" /> funct ...

  6. 在nuxt中加入element-ui插件遇到的问题

    gen1.首先进入nuxt的官网跟着步骤实现内容. https://zh.nuxtjs.org/guide/plugins 2.在我们的项目目录中找plugin 根据图片中的表示引入内容: impor ...

  7. Android Intent 基本使用及对象构成

    Intent基本使用 Intent可以理解为不同组件通信的媒介或者信使. Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcast. 具体方法如下表 ...

  8. Ubuntu16.0.4的磁盘管理

    ubuntu下硬盘无损分区移动修改工具 原创 2014年04月13日 :: ubuntu上面其实有很好的分区调整工具,gparted,非常好使用 安装非常简单 sudo apt-get install ...

  9. Java基础学习笔记二十七 DBUtils和连接池

    DBUtils 如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils.DBUtils就是JDBC的简化开发 ...

  10. Beta冲刺 第二天

    Beta冲刺 第二天 1. 昨天的困难 由于前面的冲刺留下的问题很多,而且混乱的代码给我们接下来的完善工作带来了巨大的困难. 2. 今天解决的进度 潘伟靖: 1.对代码进行了review 2.为系统增 ...