0%

【FluentValidation】繼承父類別的驗證

很多時候我們的類別會繼承同一個父類別,而父類別的欄位可能都驗證的規則都一致,一直重寫會覺得很煩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Parent 
{
public string Name {get;set;}
}

public class ChildA :Parent
{
public string ChildACustomProperty {get;set;}
}

public class ChildB : Parent
{
public string ChildBCustomProperty { get; set; }
}

這邊有兩個類別分別為ChildA和 ChildB,它們都繼承Parent這個類別,這時候 Parent的Name規則就是不能為空值跟Null,但真正會傳進來使用的是ChildA 與ChildB這兩個子類別,難道只能將驗證Name的欄位兩邊都寫嗎??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class ChildAValidators : AbstractValidator<ChildA>
{
public ChildAValidators()
{
// Name
this.RuleFor(x => x.Name)
.NotEmpty()
.WithErrorCode("400")
.WithMessage("Name 不能為空值")
.NotNull()
.WithErrorCode("400")
.WithMessage("Name 不能為Null");

// ChildACustomProperty
this.RuleFor(x => x.ChildACustomProperty)
.Length(1,6)
.WithErrorCode("400")
.WithMessage("ChildACustomProperty 必須介於1~6個字之間");
}
}

public class ChildBValidators : AbstractValidator<ChildB>
{
public ChildBValidators()
{
// Name
this.RuleFor(x => x.Name)
.NotEmpty()
.WithErrorCode("400")
.WithMessage("Name 不能為空值")
.NotNull()
.WithErrorCode("400")
.WithMessage("Name 不能為Null");

// ChildACustomProperty
this.RuleFor(x => x.ChildBCustomProperty)
.Length(1, 12)
.WithErrorCode("400")
.WithMessage("ChildBCustomProperty 必須介於1~12個字之間");
}
}

這樣對程式設計來說不是很好,如果哪天Name的限制改變,所有繼承Parent的驗證都要翻出來改,其實FluentValidation也可以寫成繼承的方式,可以改成下面的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class ChildAValidators : ParentValidators<ChildA>
{
public ChildAValidators()
{
// ChildACustomProperty
this.RuleFor(x => x.ChildACustomProperty)
.Length(1,6)
.WithErrorCode("400")
.WithMessage("ChildACustomProperty 必須介於1~6個字之間");
}
}

public class ChildBValidators : ParentValidators<ChildB>
{
public ChildBValidators()
{
// ChildACustomProperty
this.RuleFor(x => x.ChildBCustomProperty)
.Length(1, 12)
.WithErrorCode("400")
.WithMessage("ChildBCustomProperty 必須介於1~12個字之間");
}
}

public class ParentValidators<T> : AbstractValidator<T>
where T : Parent
{
public ParentValidators()
{
// Name
this.RuleFor(x => x.Name)
.NotEmpty()
.WithErrorCode("400")
.WithMessage("Name 不能為空值")
.NotNull()
.WithErrorCode("400")
.WithMessage("Name 不能為Null");
}
}

這樣就可以讓程式乾淨許多,也讓它符合物件導向的設計!!!