在使用[Required]這個標籤進行 Guid 型態屬性的驗證時,原本預期沒有填入該欄位時會被檔下來,但用在 Guid 型態的屬性上居然沒效。本篇紀錄如何以「自訂驗證標籤」及「更改欄位型態」兩個方法來解決這個問題。

環境

  • macOS Sonoma 14.0(Apple M1 Pro)
  • .NET 6.0
  • Visual Studio Community 2022 for Mac 17.6.6

情境

首先有一個Model,用於存放使用者輸入的資料

public class PostViewModel
{
    [Required]
    public Guid ProjectId { get; set; }

    public Guid? SupervisorId { get; set; }
}

使用者呼叫使用此PostViewModel作為參數的API,傳送一個空的JSON給API

{
    
}

原本預期應該會跳出類似The ProjectId field is required.之類的錯誤,結果任何錯誤都沒跳,還直接讓我過了。

查了一下發現 Guid 是使用 struct 實作的,struct 是實值類型,預設值是Guid.Empty,使用[Required]無法有效的驗證 Guid 型態的屬性。

自訂驗證標籤方法

自訂驗證標籤(ValidationAttribute)需要完成兩個動作,分別是

  1. 新增一個類別,繼承ValidationAttribute類別
  2. 實作IsValid方法

我們在專案中新增一個ValidationAttributes目錄,在目錄中新增RequiredAttribute.cs檔案,在檔案中加入以下程式碼:

using System.Collections;
using System.ComponentModel.DataAnnotations;

namespace Example.ValidationAttributes
{
    public class GuidRequiredAttribute : ValidationAttribute
    {
        // 實作 IsValid 方法,自訂驗證邏輯,
        // 回傳true代表通過驗證,false代表不通過驗證
        public override bool IsValid(object? value)
        {
            var guidValue = value as Guid?;
            
            // 判斷傳入的值是否為 null,並且判斷是否為Guid.Empty
            if (guidValue == null || guidValue == Guid.Empty)
            {
                return false;
            }
            return true;
        }
    }
}

完成驗證邏輯後,我們就可以將自訂的[GuidRequired]標籤用在我們需要驗證的屬性上

public class PostViewModel
{
    [GuidRequired]
    public Guid ProjectId { get; set; }

    public Guid? SupervisorId { get; set; }
}

更改欄位型態方法

更改欄位型態也是其中一種方法,將需要驗證的 Guid 型態屬性改成 Nullable 的 Guid 即可使用[Required]進行驗證。

public class PostViewModel
{
    //將此欄位改成Guid?以使用[Required]驗證標籤
    [Required]
    public Guid? ProjectId { get; set; } 

    public Guid? SupervisorId { get; set; }
}
參考資料