瀏覽標籤:

NetCore

[.NETCore][LexLibrary.Rbac] 基於 Role-based access control 實作驗證模組

LexLibrary.Rbac


本專案基於 Role-based access control 實作下列模組

  1. 登入 & 登出
  2. 註冊 & 驗證 Email
  3. 忘記密碼 & 重設密碼
  4. 角色模組
  5. 功能模組
  6. 驗證授權狀態 (可限制登入裝置數量)
  7. 基本資料維護

專案演示


閱讀更多

       

[Linux] NETCore 在 Linux 中如何取得時區?

最近想部屬應用程式到 Linux 上玩玩,碰到了時區轉換的問題,在 Window 中可以使用

TimeZoneInfo.FindSystemTimeZoneById("Taipei Standard Time")

取得台灣時區,放到 Linux 卻噴了錯誤給我看

warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {1e7284ba-b3b0-4c9a-8e1c-4dac05942fc7} may be persisted to storage in unencrypted form.
Application startup exception: System.TimeZoneNotFoundException: The time zone ID 'Taipei Standard Time' was not found on the local computer. ---> System.IO.FileNotFoundException: Could not find file '/usr/share/zoneinfo/Taipei Standard Time'.
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)

Linux 認不得 Taipei Standard Time 那該怎麼辦呢?

閱讀更多

       

[C#][.NETCore] 壓縮檔案 & 解壓縮檔案

在 .NET Framework 的時候有好用的 DotNetZip 可以快速壓縮&解壓縮檔案
但在寫 .NET Core 的時候發現這個套件不能使用,那只好默默地自己寫了

這邊就用 System.IO.Compression 提供的 ZipArchive 來簡單寫個壓縮 & 解壓縮範例

壓縮檔案:

string rootPath = AppDomain.CurrentDomain.BaseDirectory;
string saveFileName = Path.Combine(rootPath, "test.zip");
string zipFileName = Path.Combine(rootPath, "123.txt");

using (var fs = new FileStream(saveFileName, FileMode.OpenOrCreate))
{
    using (ZipArchive zipArchive = new ZipArchive(fs, ZipArchiveMode.Create))
    {
        string fileName = Path.GetFileName(zipFileName);

        var zipArchiveEntry = zipArchive.CreateEntry(fileName);
        using (var zipStream = zipArchiveEntry.Open())
        {
            byte[] bytes = File.ReadAllBytes(zipFileName);
            zipStream.Write(bytes, 0, bytes.Length);
        }
    }
}

 

解壓縮檔案:

string rootPath = AppDomain.CurrentDomain.BaseDirectory;
string zipFileName = Path.Combine(rootPath, "test.zip");
string saveFolder = rootPath;

using (var fs = new FileStream(zipFileName, FileMode.Open))
{
    using (ZipArchive zipArchive = new ZipArchive(fs, ZipArchiveMode.Read))
    {
        foreach (ZipArchiveEntry zipArchiveEntry in zipArchive.Entries)
        {
            string temp = Path.Combine(saveFolder, zipArchiveEntry.FullName);
            zipArchiveEntry.ExtractToFile(temp);
        }
    }
}

 

解壓縮的時候最好可以將 zipArchiveEntry.FullName 再做一層處理,避免產生資安問題 (詳情)

       

[Docker][NetCore] Win7 可以在 Docker 下 Debug ASP.NET Core 嗎?

今天心血來潮想試試看可不可以把 ASP.NET Core 部屬在 Docker 裡面 Debug,但我的測試機是 Win7 無法安裝新版 Docker for Windows 於是乎抱著僥倖下載 Docker Toolbox 來試試看
兩者最大差異在於 Docker Toolbox 是運行在 Oracle VM VirtualBox,而 Docker for Windows 則是可以在微軟的虛擬化技術 Hyper-V 底下運行

肉身測試開始

如果想要讓現有專案支援 Docker 的話只要對 專案右鍵 -> 加入 -> Docker Support 強大的 Visual Studio 2017 就會搞定基礎設定

這邊的話要選擇 Linux 上面的 Windows 是給 Docker for Windows 選的
接著 Visual Studio 就會幫你下載與設定一些基本環境

接著直接按 F5 執行偵錯模式
噹噹… 他竟然說我沒有安裝 dotnet sdk

-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
Did you mean to run dotnet SDK commands? Please install dotnet SDK from:
http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
The target process exited without raising a CoreCLR started event. Ensure that the target process is configured to use .NET Core. This may be expected if the target process did not run on .NET Core.
The program '[24] dotnet' has exited with code 145 (0x91).
'' 程式以返回碼 145 (0x91) 結束。

 

 

翻了很久才翻到一篇文章 Docker debugging for ASP.NET Core application is not working 國外也有個勇者想在 Win7 利用 Docker 來 Debug ASP.NET Core

最後被加上了 Closed - Won't Fix 的 Tag 看來這個問題應該是不會修正了

結論

想要在 Docker 上玩 ASP.NET Core 還是乖乖用 Win10 吧
哪天有空了來試試看在 Win10 安裝 Docker 玩玩看
不知道會不會又有其他地雷引爆

       

[C#][DI] 相互依賴造成循環注入死結

問題緣由

最近在寫 .NET Core 的時候遇到了一個問題

A circular dependency was detected for the service of type 'WebApplication1.Service.A1Service'

 

A1Service

public class A1Service
{
    private readonly string guid = null;
    private readonly A2Service _a2Service = null;

    public A1Service(A2Service a2Service)
    {
        _a2Service = a2Service;

        if (guid == null)
        {
            guid = Guid.NewGuid().ToString();
        }
    }

    public void Run()
    {
        Console.WriteLine("A1Service: " + guid);
    }

    public void RunOther()
    {
        _a2Service.Run();
    }
}

 

這是網路教學文章上常見的從建構子中依賴注入 A2Service 的程式
接著我們再來看看另外一支程式

A2Service

public class A2Service
{
    private readonly string guid = null;
    private readonly A1Service _a1Service = null;

    public A2Service(A1Service a1Service)
    {
        _a1Service = a1Service;

        if (guid == null)
        {
            guid = Guid.NewGuid().ToString();
        }
    }

    public void Run()
    {
        Console.WriteLine("A2Service: " + guid);
    }

    public void RunOther()
    {
        _a1Service.Run();
    }
}

 

 

這裡就發生了一個循環依賴的問題 A1Service 在建構子中注入了 A2Service,而 A2Service 也在建構子中注入了 A1Service,造成兩個物件互相依賴造成 Exception

解決方法

改成不直接在建構子中注入 Service ,改注入 IServiceProvider,再利用 GetService 這個方法來取得物件,這樣就可以順利解決這個問題囉。

A3Service

public class A3Service
{
    private readonly string guid = null;
    private readonly IServiceProvider _serviceProvider = null;

    public A3Service(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;

        if (guid == null)
        {
            guid = Guid.NewGuid().ToString();
        }
    }

    public void Run()
    {
        Console.WriteLine("A3Service: " + guid);
    }

    public void RunOther()
    {
        _serviceProvider.GetService<A4Service>().Run();
    }
}

 

A4Service

public class A4Service
{
    private readonly string guid = null;
    private readonly IServiceProvider _serviceProvider = null;

    public A4Service(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;

        if (guid == null)
        {
            guid = Guid.NewGuid().ToString();
        }
    }

    public void Run()
    {
        Console.WriteLine("A4Service: " + guid);
    }

    public void RunOther()
    {
        _serviceProvider.GetService<A3Service>().Run();
    }
}

 

       

[.NET Core] EFCore Generate DbModel

使用 EFCore 的時候沒有看有地方可以像 .NET Framework 可以直接使用 VS 新增 edmx 產生好資料庫的 Model 與 DbContext,這個時候就必須靠自己拉,不過當 Table 多的時候這樣人工慢慢新增 Model 有點智障,於是乎就上網找到了 EFCore Tool 有提供一段命令可以使用。

網址:https://docs.microsoft.com/zh-tw/ef/core/miscellaneous/cli/powershell

這裡就來簡單做個筆記

  1. 首先在 Package Manager Console 輸入指令安裝 EFCore Tool
Install-Package Microsoft.EntityFrameworkCore.Tools
  1. 若為 Win7 需要先裝 Windows Management Framework 3.0 否則會跟我一樣出現下面的錯誤
    錯誤畫面

  2. 檔案可以在 這裡 找到下載安裝並重開機。

  3. 產生 Model 前需注意一件事情就是密碼不能有 $ 符號,不然會跟我一樣鬼打牆一小時都找不到問題,我有嘗試使用單引號包起來,但依然無法成功連線

  4. 接著在 Package Manager Console 輸入指令 (適用於 Azure SQL DataBase)

Scaffold-DbContext "Server={ip};Initial Catalog={dbName};Persist Security Info=False;User ID={Account};Password={Password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir {Path}
  1. 接著就可以看到 VS 裡面跑出 DbModel 與 DbContext 囉 !!
       

[SideProject] 財政部電子發票 API 測試工具

財政部電子發票 API 測試工具

這是我最近在串接財政部 API 時自己寫的測試工具,希望能讓大家在串接測試上更加方便。
歡迎 PR 財政部的 API 清單

操作說明

  • 環境變數
  1. 簽章 (Signature):將 Request 參數按照名稱排序並以 HMAC-SHA1 加密後加在 Query 後方傳送至財政部
  2. 測試環境:將資料傳送至財政部測試環境
  3. Client 模式:以另開新頁的方式呼叫財政部 API
  • 選擇 Api
    要測試的 API

  • 財政部加密用 Key
    財政部提供的 HMAC-SHA1 加密用 AppKey

  • Api 位置
    呼叫的 API 位置

  • Request
    傳送給財政部的資料

使用方法

  1. 開啟 /src/appsettings.json
  2. 將財政部提供的 AppKeyAppID 填上去
  3. 用 Visual Studio 2017 開啟並執行即可 !!

Api 新增

開啟 /src/Json/ApiList.json 且依照下面的參數新增 Api

參數介紹

參數名稱 參數說明
TypeName Api 類型 (依此欄位排序)
ApiName Api 名稱
ApiUrl Api 位置
Param Api 需傳送的參數範本 (參數 timeStamp, expTimeStamp, uuid, appID 會被自動取代)
       
  • 1
  • 2