Rozumiem, że IValidatableObject
jest to używane do walidacji obiektu w sposób, który pozwala porównać właściwości ze sobą.
Nadal chciałbym mieć atrybuty do walidacji poszczególnych właściwości, ale w niektórych przypadkach chcę ignorować awarie niektórych właściwości.
Czy próbuję go użyć nieprawidłowo w poniższym przypadku? Jeśli nie, jak mam to zaimplementować?
public class ValidateMe : IValidatableObject
{
[Required]
public bool Enable { get; set; }
[Range(1, 5)]
public int Prop1 { get; set; }
[Range(1, 5)]
public int Prop2 { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!this.Enable)
{
/* Return valid result here.
* I don't care if Prop1 and Prop2 are out of range
* if the whole object is not "enabled"
*/
}
else
{
/* Check if Prop1 and Prop2 meet their range requirements here
* and return accordingly.
*/
}
}
}
Cytat z posta na blogu Jeffa Handleya na temat obiektów walidacyjnych i właściwości za pomocą walidatora :
Oznacza to, że to, co próbujesz zrobić, nie zadziała po wyjęciu z pudełka, ponieważ walidacja zostanie przerwana w kroku 2. Możesz spróbować utworzyć atrybuty, które dziedziczą po wbudowanych, a konkretnie sprawdzić obecność włączonej właściwości (za pośrednictwem interfejsu) przed przeprowadzeniem ich normalnej weryfikacji. Alternatywnie, możesz umieścić całą logikę walidacji jednostki w
Validate
metodzie.źródło
Wystarczy dodać kilka punktów:
Ponieważ
Validate()
sygnatura metody powracaIEnumerable<>
,yield return
można jej użyć do leniwego generowania wyników - jest to korzystne, jeśli niektóre kontrole walidacji wymagają intensywnych operacji we / wy lub procesora.Ponadto, jeśli używasz
MVC ModelState
, możesz przekonwertować niepowodzenia wyniku weryfikacji naModelState
wpisy w następujący sposób (może to być przydatne, jeśli przeprowadzasz walidację w segregatorze modelu niestandardowego ):źródło
Zaimplementowałem klasę abstrakcyjną ogólnego zastosowania do walidacji
źródło
Problem z zaakceptowaną odpowiedzią polega na tym, że teraz od wywołującego zależy, czy obiekt zostanie poprawnie zweryfikowany. Chciałbym albo usunąć RangeAttribute i wykonać walidację zakresu w ramach metody Validate, albo utworzyć podklasę atrybutu niestandardowego RangeAttribute, która przyjmuje nazwę wymaganej właściwości jako argument w konstruktorze.
Na przykład:
źródło
Podobała mi się odpowiedź cocogzy, z wyjątkiem tego, że wywołanie base.IsValid spowodowało wyjątek przepełnienia stosu, ponieważ wielokrotnie wprowadzał metodę IsValid. Więc zmodyfikowałem go tak, aby był dla określonego typu walidacji, w moim przypadku był to adres e-mail.
To działa znacznie lepiej! Nie ulega awarii i wyświetla ładny komunikat o błędzie. Mam nadzieję, że to komuś pomoże!
źródło
To, czego nie lubię w iValidate, to wygląda na to, że działa tylko PO wszystkich innych walidacjach.
Dodatkowo, przynajmniej w naszej witrynie, uruchomiłoby się ponownie podczas próby zapisu. Sugerowałbym po prostu utworzenie funkcji i umieszczenie w niej całego kodu walidacyjnego. Alternatywnie w przypadku witryn internetowych możesz mieć swoją „specjalną” walidację w kontrolerze po utworzeniu modelu. Przykład:
źródło