瀏覽標籤:

C#

[C#][ASP.NET Core] 快速將 Google reCAPTCHA 驗證加入你的網站

LexLibrary.Google.reCAPTCHA

使用 HtmlHelper + ValidateAttribute 快速將 Google reCAPTCHA 驗證加入你的網站

Blog:https://blog.exfast.me/2018/11/c-sharp-asp-net-core-quickly-add-google-recaptcha-verification-to-your-website/

NuGet:https://www.nuget.org/packages/LexLibrary.Google.reCAPTCHA/

GitHub:https://github.com/shuangrain/LexLibrary.Google.reCAPTCHA

Support

  • [  ] Google reCAPTCHA v1
  • [x] Google reCAPTCHA v2
  • [x] Google reCAPTCHA v3 閱讀更多
       

[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#][LeetCode] 479. Largest Palindrome Product

題目

Find the largest palindrome made from the product of two n-digit numbers.
Since the result could be very large, you should return the largest palindrome mod 1337.

Example:

Input: 2
Output: 987
Explanation: 99 x 91 = 9009, 9009 % 1337 = 987

Note:
The range of n is [1,8].

解題過程

這題要找出 N 位數相乘後且結果是迴文的數字
例如:N = 2 最大數字等於 99,那就要找出最大 99 最小 10 的兩位數相乘後且結果是迴文的數字。

最初我用一個很笨的方法迴圈慢慢跑,最後當然是直接逾時,後來改成先取最大數字相乘後的前半段數字,再用迴圈去產生迴文並篩選資料,這樣比前面的笨方法快非常多。
閱讀更多

       

[C#][LeetCode] 494. Target Sum

題目

You are given a list of non-negative integers, a1, a2, …, an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose one from + and – as its new symbol.

Find out how many ways to assign symbols to make sum of integers equal to target S.

題目會傳入兩個參數 nums (數字陣列)S (整數),限制只能使用兩個運算符號 +- 改變數字陣列 nums 的數字讓總和等於 S

解題過程

我自己比較少接觸演算法的東西(大學沒學好),就算去翻解答也看不懂別人在寫什麼東西,後來看了 演算法筆記- Backtracking 的圖解後終於理解解答再寫什麼東西

閱讀更多

       

[C#][LeetCode] 515. Find Largest Value in Each Tree Row

題目

You need to find the largest value in each row of a binary tree.

Example:

Input: 

          1
         / \
        3   2
       / \   \  
      5   3   9 

Output: [1, 3, 9]

解題過程

這題要找出二元樹中同階層最大的數字,我的作法是先將每層的數字收集起來,最後再一起比較。

答案

Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>();

public IList<int> LargestValues(TreeNode root)
{
    List<int> list = new List<int>();

    if (root == null)
    {
        return list;
    }

    list.Add(root.val);
    FindNum(0, root.left, root.right);
    list.AddRange(dict.Keys.Select(x => dict[x].Max()));

    return list;
}

public void FindNum(int idx, TreeNode left, TreeNode right)
{
    if (left == null && right == null)
    {
        return;
    }

    if (!dict.ContainsKey(idx))
    {
        dict[idx] = new List<int>();
    }

    if (left != null)
    {
        dict[idx].Add(left.val);
        FindNum(idx + 1, left.left, left.right);
    }

    if (right != null)
    {
        dict[idx].Add(right.val);
        FindNum(idx + 1, right.left, right.right);
    }
}

 

       

[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 再做一層處理,避免產生資安問題 (詳情)

       

[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();
    }
}