.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端口

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

過濾器

.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的使用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM