[ASP.net Core] 兩種方式讀取應用程式組態設定檔 appsettings.json

asp.net core read config 

前言

剛開始接觸ASP.net Core會遇到困惑的其中一點:沒有Web.config組態檔,以前的connectionStrings、appSettings不知道該如何設定及讀取

本文簡單介紹一下

實作

※本文範例版本為ASP.net Core 2.1 

ASP.net Core的應用程式組態檔改為appsettings.json,內容為json格式

從專案右鍵→加入→新增項目

搜尋關鍵字「應用程式」就可以找得到,把它加入至專案根路徑即可

名稱就維持appsettings.json最好別改它,因為跟Program.cs檔裡的WebHost.CreateDefaultBuilder()有關

然後在appsettings.json裡寫了如下資料

※留意 ASP.net Core 2.0~3.1,預設加入的appsettings.json檔不是UTF-8編碼格式,所以不支援中文,想要支援中文有解套辦法(或繼續等微軟改版XD),請繼續看文章下方

※2021-04-10追記 .Net 5 開始貌似加入的appsettings.json檔案預設已變成UTF-8編碼格式(?

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Email": "test@hotmail.com",
  "ThemeColor": "red",
  "isRunSSL": true,
  "MaxNumber": 10
}

如果有使用Entity Framework Core要讀取資料庫連線字串的話,請參考我的另一篇文章↓

[ASP.net Core 2] 使用Entity Framework Core 2 Database First方式存取資料(資料模型分隔在ClassLibrary專案)

而組態檔讀取方式,主要分兩種

1.類似以前WebConfigurationManager,給Key回傳Value的讀取方式(使用IConfiguration介面)

請看Sample Code的Controller↓

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; 
using Microsoft.Extensions.Options;
using StarterM.Models;
/*引用命名空間*/
using Microsoft.Extensions.Configuration;

namespace StarterM.Controllers
{
    public class HomeController : Controller
    {
        
        private readonly IConfiguration _config;//這很像ASP.net的WebConfigurationManager
        //在建構式使用相依性注入建立IConfiguration
        public HomeController(IConfiguration config)
        {
            this._config = config; 
        }

        public IActionResult Index()
        {
            ViewBag.config = this._config;
            return View();
        }
    }
}

View↓

 
@using Microsoft.Extensions.Configuration  
 
@{
    Layout = null;
} 
<!DOCTYPE html> 
<html>
<head>
    <meta name="viewport" content="width=device-width" /> 
</head>
<body> 
    @{
        IConfiguration config = (IConfiguration)ViewBag.config; 
    <ul style="color:@(config.GetValue<string>("ThemeColor"))">
        <li>DefaultConnection: @config.GetConnectionString("DefaultConnection")</li>
        <li>Email: @(config.GetValue<string>("Email"))</li>
        <li>ThemeColor: @(config.GetValue<string>("ThemeColor"))</li>
        <li>isRunSSL: @(config.GetValue<bool>("isRunSSL"))</li>
        <li>MaxNumber: @(config.GetValue<int>("MaxNumber"))</li>
    </ul>
     
    }
</body>
</html>

執行結果↓

※2021-04-12追記:巢狀、Json Array的讀取方式↓

<!-- 
appsettings.json檔案內容↓
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "錯誤通知信收件者": ["person1@hotmail.com","person2@hotmail.com","person3@hotmail.com"]
} 
-->


@using Microsoft.Extensions.Configuration
<!--在View注入IConfiguration物件-->
@inject IConfiguration config
@{
    Layout = null;
}


@{
    //用冒號往巢狀/階層 找下去↓
    string Lifetime  = config.GetValue<string>("Logging:LogLevel:Microsoft.Hosting.Lifetime");
    //json array取值方式↓
    string[] 錯誤通知信收件者 = config.GetSection("錯誤通知信收件者").Get<string[]>(); 
}
<!--顯示結果↓-->
<div> 
    <div>
        取 Microsoft.Hosting.Lifetime 值: @(Lifetime)  
    </div>
    <div>
        錯誤通知信收件者: <br /> 
        @foreach (string email in 錯誤通知信收件者)
        {
            <div>@email</div>
        }
    </div>
</div>

執行結果↓

其他複雜讀取方式,請見stackoverflow討論:ASP.NET Core Get Json Array using IConfiguration

2.強型別讀取方式

依照JSON內容先自行建立一個類別,如果不知道怎麼建立的話,就到json2csharp網站把appsettings.json裡的JSON內容貼上去

以下是我新增的類別檔↓

接著要把appsettings.json裡的資料倒進剛剛宣告的類別裡,在Startup.cs↓

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using StarterM.Models;

namespace StarterM
{
    public class Startup
    {
        /// <summary>
        /// 讀取 appsettings.json 專用 
        /// </summary>
        public IConfiguration _config { get; }
        public Startup(IConfiguration config)
        {
            this._config = config;
        } 
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(); 
            //加這行
            services.Configure<MyAppConfig>(this._config); 
        } 
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
             
            app.UseStaticFiles();
            app.UseMvcWithDefaultRoute();

        }
    }
}

Controller↓

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
/*引用命名空間*/
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;//加這行
using StarterM.Models;

namespace StarterM.Controllers
{
    public class HomeController : Controller
    {

        private readonly IOptions<MyAppConfig> _opt; //加這行
        private readonly IConfiguration _config;
        //使用相依性注入
        public HomeController(IOptions<MyAppConfig> opt, IConfiguration config)
        {
            this._config = config;
            this._opt = opt;//加這行
        }

        public IActionResult Index()
        {
            ViewBag.config = this._config;
            MyAppConfig objConfig = this._opt.Value;//注意這行
            ViewBag.ObjConfig = objConfig;
            return View();
        }
    }
}

View↓

@using StarterM.Models
<!--使用IConfiguration介面才需引用-->
@using Microsoft.Extensions.Configuration
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
</head>
<body>

    <div>↓使用強型別物件讀取應用程式設定檔案</div>
    @{
        MyAppConfig objConfig = (MyAppConfig)ViewBag.ObjConfig;
        <ul style="color:@objConfig.ThemeColor">
            <li>DefaultConnection: @objConfig.ConnectionStrings.DefaultConnection</li>
            <li>Email: @objConfig.Email </li>
            <li>ThemeColor: @objConfig.ThemeColor </li>
            <li>isRunSSL: @objConfig.isRunSSL </li>
            <li>MaxNumber: @objConfig.MaxNumber </li>
        </ul> 
    }
     
    <div>↓使用IConfiguration讀取應用程式設定檔案</div>
    @{
        IConfiguration config = (IConfiguration)ViewBag.config;
        <ul style="color:@(config.GetValue<string>("ThemeColor"))">
            <li>DefaultConnection: @config.GetConnectionString("DefaultConnection")</li>
            <li>Email: @(config.GetValue<string>("Email"))</li>
            <li>ThemeColor: @(config.GetValue<string>("ThemeColor"))</li>
            <li>isRunSSL: @(config.GetValue<bool>("isRunSSL"))</li>
            <li>MaxNumber: @(config.GetValue<int>("MaxNumber"))</li>
        </ul>

    }
</body>
</html>

執行結果↓

剛才有提過,預設appsettings.json由於不是UTF-8編碼,所以如果有下面的中文內容

執行結果就會變成亂碼↓

解決辦法:先用記事本notepad開啟appsettings.json檔,然後變更使用UTF-8編碼後再覆蓋存檔。

重新建置專案後再執行一次網頁,中文就可以正常顯示了↓

※2021-04-10追記,.Net 5 之後appsettings.json預設就是UTF-8編碼,可以不用額外處理↑

最後留意一下,如果採用強型別物件讀取appsettings.json方式,由於組態資料注入物件時間點的關係

網站發佈到IIS後如果有修改appsettings.json的話,記得IIS站台要重新啟動才會生效

※使用IConfiguration讀取appsettings.json的話,則無需此動作

※2019.4.8追記:.Net Core Console貌似無法從專案直接加入appsettings.json,那就手動自己加入吧XD

請參考:[.Net Core] 在.Net Core Console中讀取應用程式組態檔 appsettings.json

自行從Nuget把 Microsoft.Extensions.Configuration.Json 加入參考後,照著程式碼寫,就可以讀取appsettings.json